Commit Graph

396 Commits

Author SHA1 Message Date
Dave Collins
974ae66529
txscript: Remove unused isStakeSubmission function. 2019-03-26 14:51:26 -05:00
Dave Collins
5455dbce3c
txscript: Optimize typeOfScript stakesub detection.
This continues the process of converting the typeOfScript function to
use a combination of raw script analysis and the new tokenizer instead
of the far less efficient parsed opcodes.

In particular, it converts the detection of stake submission scripts to
use raw script analysis.

In order to accomplish this, it introduces three new functions.  The first
one is named extractStakePubKeyHash and works with the raw script bytes
to simultaneously determine if the script is a stake-tagged
pay-to-pubkey-hash script tagged with a specified stake opcode, and in
the case it is, extract and return the hash.  The second new function,
named extractStakeScriptHash, is similar except it detect a stake-tagged
pay-to-script-hash script tagged with a specified stake opcode.
Finally, the third function is named isStakeSubmissionScript and is
defined in terms of the former two functions.

The extract function approach was chosen because it is common for
callers to want to only extract relevant details from a script if the
script is of the specific type.  Extracting those details requires
performing the exact same checks to ensure the script is of the correct
type, so it is more efficient to combine the two into one and define the
type determination in terms of the result so long as the extraction does
not require allocations.

The following is a before and after comparison of analyzing a large
script:

benchmark                          old ns/op    new ns/op    delta
---------------------------------------------------------------------
BenchmarkIsStakeSubmissionScript   140308       4.20         -100.00%

benchmark                          old allocs   new allocs   delta
---------------------------------------------------------------------
BenchmarkIsStakeSubmissionScript   1            0            -100.00%

benchmark                          old bytes    new bytes    delta
---------------------------------------------------------------------
BenchmarkIsStakeSubmissionScript   466944       0            -100.00%
2019-03-26 14:51:25 -05:00
Dave Collins
6de8d6901d
txscript: Add bench for stake submission scripts. 2019-03-26 14:51:24 -05:00
Dave Collins
63e74185cf
txscript: Remove unused isNullData function. 2019-03-26 14:51:24 -05:00
Dave Collins
f589dd8fdf
txscript: Optimize typeOfScript nulldata detection.
This continues the process of converting the typeOfScript function to
use a combination of raw script analysis and the new tokenizer instead
of the far less efficient parsed opcodes.

In particular, it converts the detection of nulldata scripts to use both raw
script analysis and the new tokenizer.

The following is a before and after comparison of analyzing a large
script:

benchmark                   old ns/op    new ns/op    delta
--------------------------------------------------------------
BenchmarkIsNullDataScript   120800       3.81         -100.00%

benchmark                   old allocs   new allocs   delta
--------------------------------------------------------------
BenchmarkIsNullDataScript   1            0            -100.00%

benchmark                   old bytes    new bytes    delta
--------------------------------------------------------------
BenchmarkIsNullDataScript   466944       0            -100.00%
2019-03-26 14:51:23 -05:00
Dave Collins
15416b09dc
txscript: Add bench for null scripts. 2019-03-26 14:51:23 -05:00
Dave Collins
e7a172c441
txscript: Optimize typeOfScript pay-to-alt-pk-hash.
This continues the process of converting the typeOfScript function to
use a combination of raw script analysis and the new tokenizer instead
of the far less efficient parsed opcodes.

In particular, it converts the detection of pay-to-alt-pubkey-hash
scripts to use raw script analysis.

In order to accomplish this, it introduces two new functions.  The first
one is named extractPubKeyHashAltDetails and works with the raw script
bytes to simultaneously determine if the script is a
pay-to-alt-pubkey-hash script, and in the case it is, extract and return
the hash and signature type.  The second new function is named
isPubKeyHashAltScript and is defined in terms of the former.

The extract function approach was chosen because it is common for
callers to want to only extract relevant details from a script if the
script is of the specific type.  Extracting those details requires
performing the exact same checks to ensure the script is of the correct
type, so it is more efficient to combine the two into one and define the
type determination in terms of the result so long as the extraction does
not require allocations.

It is important to note that this new implementation intentionally has a
semantic difference from the existing implementation in that it will now
only pass when one of two signature types currently supported by
consensus are specified whereas previously it would allow any single
byte data push.

The following is a before and after comparison of analyzing a large
script:

benchmark                        old ns/op    new ns/op    delta
-------------------------------------------------------------------
BenchmarkIsAltPubKeyHashScript   107100       2.63         -100.00%

benchmark                        old allocs   new allocs   delta
-------------------------------------------------------------------
BenchmarkIsAltPubKeyHashScript   1            0            -100.00%

benchmark                        old bytes    new bytes    delta
-------------------------------------------------------------------
BenchmarkIsAltPubKeyHashScript   466944       0            -100.00%
2019-03-26 14:51:22 -05:00
Dave Collins
95175cb873
txscript: Add bench for pay-to-alt-pubkey-hash scripts. 2019-03-26 14:51:21 -05:00
Dave Collins
ffe80c736a
txscript: Remove unused isPubkeyHash function. 2019-03-26 14:51:21 -05:00
Dave Collins
406f851716
txscript: Optimize typeOfScript pay-to-pubkey-hash.
This continues the process of converting the typeOfScript function to
use a combination of raw script analysis and the new tokenizer instead
of the far less efficient parsed opcodes.

In particular, it converts the detection of pay-to-pubkey-hash scripts
to use raw script analysis.

In order to accomplish this, it introduces two new functions.  The first
one is named extractPubKeyHash and works with the raw script bytes
to simultaneously determine if the script is a pay-to-pubkey-hash script,
and in the case it is, extract and return the hash.  The second new
function is named isPubKeyHashScript and is defined in terms of the
former.

The extract function approach was chosen because it is common for
callers to want to only extract relevant details from a script if the
script is of the specific type.  Extracting those details requires
performing the exact same checks to ensure the script is of the correct
type, so it is more efficient to combine the two into one and define the
type determination in terms of the result so long as the extraction does
not require allocations.

The following is a before and after comparison of analyzing a large
script:

benchmark                     old ns/op    new ns/op    delta
----------------------------------------------------------------
BenchmarkIsPubKeyHashScript   165903       0.64         -100.00%

benchmark                     old allocs   new allocs   delta
----------------------------------------------------------------
BenchmarkIsPubKeyHashScript   1            0            -100.00%

benchmark                     old bytes    new bytes    delta
----------------------------------------------------------------
BenchmarkIsPubKeyHashScript   466945       0            -100.00%
2019-03-26 14:51:20 -05:00
Dave Collins
d07d626882
txscript: Add bench for pay-to-pubkey-hash scripts. 2019-03-26 14:51:19 -05:00
Dave Collins
26026475be
txscript: Optimize typeOfScript pay-to-alt-pubkey.
This continues the process of converting the typeOfScript function to
use a combination of raw script analysis and the new tokenizer instead
of the far less efficient parsed opcodes.

In particular, it converts the detection of pay-to-alt-pubkey scripts to
use raw script analysis.

In order to accomplish this, it introduces two new functions.  The first
one is named extractPubKeyAltDetails and works with the raw script bytes
to simultaneously determine if the script is a pay-to-alt-pubkey script,
and in the case it is, extract and return the relevant details.  The
second new function is named isPubKeyAltScript and is defined in terms
of the former.

The extract function approach was chosen because it is common for
callers to want to only extract relevant details from a script if the
script is of the specific type.  Extracting those details requires
performing the exact same checks to ensure the script is of the correct
type, so it is more efficient to combine the two into one and define the
type determination in terms of the result so long as the extraction does
not require allocations.

It is important to note that this new implementation intentionally
tightens the following semantics as compared to the existing
implementation:

- The signature type must now be one of the two supported types versus
  allowing any single byte data push
- The public key must now be of the correct length for the given
  signature type versus allowing any size up to 512 bytes
- The public key for schnorr secp256k1 pubkeys must now be a compressed
  public key and adhere to the strict encoding requirements for them

The following is a before and after comparison of analyzing a large
script:

benchmark                    old ns/op    new ns/op    delta
---------------------------------------------------------------
BenchmarkIsAltPubKeyScript   143449       2.99         -100.00%

benchmark                    old allocs   new allocs   delta
---------------------------------------------------------------
BenchmarkIsAltPubKeyScript   1            0            -100.00%

benchmark                    old bytes    new bytes    delta
---------------------------------------------------------------
BenchmarkIsAltPubKeyScript   466944       0            -100.00%
2019-03-26 14:51:19 -05:00
Dave Collins
e64e21c29f
txscript: Add bench for pay-to-alt-pubkey scripts. 2019-03-26 14:51:18 -05:00
Dave Collins
b273b8343c
txscript: Remove unused isPubkey function. 2019-03-26 14:51:17 -05:00
Dave Collins
1b067cb785
txscript: Optimize typeOfScript pay-to-pubkey.
This continues the process of converting the typeOfScript function to
use a combination of raw script analysis and the new tokenizer instead
of the far less efficient parsed opcodes.

In particular, it converts the detection of pay-to-pubkey scripts to use
raw script analysis.

In order to accomplish this, it introduces four new functions:
extractCompressedPubKey, extractUncompressedPubKey, extractPubKey, and
isPubKeyScript.  The extractPubKey function makes use of
extractCompressedPubKey and extractUncompressedPubKey to combine their
functionality as a convenience and isPubKeyScript is defined in terms of
extractPubKey.

The extractCompressedPubKey works with the raw script bytes to
simultaneously determine if the script is a pay-to-compressed-pubkey
script, and in the case it is, extract and return the raw compressed
pubkey bytes.

Similarly, the extractUncompressedPubKey works in the same way except it
determines if the script is a pay-to-uncompressed-pubkey script and
returns the raw uncompressed pubkey bytes in the case it is.

The extract function approach was chosen because it is common for
callers to want to only extract relevant details from a script if the
script is of the specific type.  Extracting those details requires
performing the exact same checks to ensure the script is of the correct
type, so it is more efficient to combine the two into one and define the
type determination in terms of the result so long as the extraction does
not require allocations.

The following is a before and after comparison of analyzing a large
script:

benchmark                 old ns/op    new ns/op    delta
------------------------------------------------------------
BenchmarkIsPubKeyScript   124749       4.01         -100.00%

benchmark                 old allocs   new allocs   delta
------------------------------------------------------------
BenchmarkIsPubKeyScript   1            0            -100.00%

benchmark                 old bytes    new bytes    delta
------------------------------------------------------------
BenchmarkIsPubKeyScript   466944       0            -100.00%
2019-03-26 14:51:17 -05:00
Dave Collins
c4a15275ce
txscript: Add benchmark for pay-to-pubkey scripts. 2019-03-26 14:51:16 -05:00
Dave Collins
07168b8623
txscript: Remove unused isMultiSig function. 2019-03-26 14:51:15 -05:00
Dave Collins
900af9b029
txscript: Optimize typeOfScript multisig.
This continues the process of converting the typeOfScript function to
use a combination of raw script analysis and the new tokenizer instead
of the far less efficient parsed opcodes.

In particular, for this commit, since the ability to detect multisig
scripts via the new tokenizer is now available, the function is simply
updated to make use of it.
2019-03-26 14:51:15 -05:00
Dave Collins
efd7e2f572
txscript: Remove unused isScriptHash function. 2019-03-26 14:51:14 -05:00
Dave Collins
bdd51a0ddc
txscript: Optimize typeOfScript pay-to-script-hash.
This begins the process of converting the typeOfScript function to use a
combination of raw script analysis and the new tokenizer instead of the
far less efficient parsed opcodes with the intent of significantly
optimizing the function.

In order to ease the review process, each script type will be converted
in a separate commit and the typeOfScript function will be updated such
that the script is only parsed as a fallback for the cases that are not
already converted to more efficient raw script variants.

In particular, for this commit, since the ability to detect
pay-to-script-hash via raw script analysis is now available, the
function is simply updated to make use of it.
2019-03-26 14:51:14 -05:00
Dave Collins
4f27dfc507
txscript: Make typeOfScript accept raw script.
This converts the typeOfScript function to accept a script version and
raw script instead of an array of internal parsed opcodes in order to
make it more flexible for raw script analysis.

Also, this adds a comment to CalcScriptInfo to call out the specific
version semantics and deprecates the function since nothing currently
uses it, and the relevant information can now be obtained by callers
more directly through the use of the new script tokenizer.

All other callers are updated accordingly.
2019-03-26 14:51:13 -05:00
Dave Collins
4dc1ffbe6b
txscript: Add benchmark for GetScriptClass. 2019-03-26 14:51:12 -05:00
Dave Collins
a1b24adf27
txscript: Optimize GetPreciseSigOpCount.
This converts the GetPreciseSigOpCount function to use a combination of
raw script analysis and the new tokenizer instead of the far less
efficient parseScript thereby significantly optimizing the function.

In particular it uses the recently converted isScriptHashScript,
IsPushOnlyScript, and countSigOpsV0 functions along with the recently
added finalOpcodeData functions.

It also modifies the comment to explicitly call out the script version
semantics.

The following is a before and after comparison of analyzing a large
script:

benchmark                       old ns/op    new ns/op    delta
------------------------------------------------------------------
BenchmarkGetPreciseSigOpCount   287939       1077         -99.63%

benchmark                       old allocs   new allocs   delta
------------------------------------------------------------------
BenchmarkGetPreciseSigOpCount   3            0            -100.00%

benchmark                       old bytes    new bytes    delta
------------------------------------------------------------------
BenchmarkGetPreciseSigOpCount   934657       0            -100.00%
2019-03-26 14:51:12 -05:00
Dave Collins
75e71d849e
txscript: Add benchmark for GetPreciseSigOpCount. 2019-03-26 14:51:11 -05:00
Dave Collins
281f794408
txscript: Check p2sh push before parsing scripts.
This moves the check for non push-only pay-to-script-hash signature
scripts before the script parsing logic when creating a new engine
instance to avoid the extra overhead in the error case.
2019-03-26 14:51:10 -05:00
Dave Collins
af67951b9a
txscript: Optimize new engine push only script.
This modifies the check for whether or not a pay-to-script-hash
signature script is a push only script to make use of the new and more
efficient raw script function.

Also, since the script will have already been checked further above when
the ScriptVerifySigPushOnly flags is set, avoid checking it again in
that case.
2019-03-26 14:51:10 -05:00
Dave Collins
9e8bfd2493
txscript: Optimize IsPushOnlyScript.
This converts the IsPushOnlyScript function to make use of the new
tokenizer instead of the far less efficient parseScript thereby
significantly optimizing the function.

It also deprecates the isPushOnly function that requires opcodes in
favor of the new function and modifies the comment on IsPushOnlyScript
to explicitly call out the script version semantics.

The following is a before and after comparison of analyzing a large
script:

benchmark                    old ns/op    new ns/op    delta
---------------------------------------------------------------
BenchmarkIsPayToScriptHash   139961       0.66         -100.00%

benchmark                    old allocs   new allocs   delta
---------------------------------------------------------------
BenchmarkIsPayToScriptHash   1            0            -100.00%

benchmark                    old bytes    new bytes    delta
---------------------------------------------------------------
BenchmarkIsPayToScriptHash   466944       0            -100.00%
2019-03-26 14:51:09 -05:00
Dave Collins
93b039d5ac
txscript: Add benchmark for IsPushOnlyScript. 2019-03-26 14:51:08 -05:00
Dave Collins
a598838fb7
txscript: Optimize isAnyKindOfScriptHash.
This converts the isAnyKindOfScriptHash function to analyze the raw
script instead of requiring far less efficient parsed opcodes thereby
significantly optimizing the function.

Since the function relies on isStakeScriptHash to identify a stake
tagged pay-to-script-hash, and is the only consumer of it, this also
converts that function to analyze the raw script and renames it to
isStakeScriptHashScript for more consistent naming.

Finally, the tests are updated accordingly.

The following is a before and after comparison of analyzing a large
script:

benchmark                        old ns/op    new ns/op    delta
-------------------------------------------------------------------
BenchmarkIsAnyKindOfScriptHash   101249       3.83         -100.00%

benchmark                        old allocs   new allocs   delta
-------------------------------------------------------------------
BenchmarkIsAnyKindOfScriptHash   1            0            -100.00%

benchmark                        old bytes    new bytes    delta
-------------------------------------------------------------------
BenchmarkIsAnyKindOfScriptHash   466944       0            -100.00%
2019-03-26 14:51:08 -05:00
Dave Collins
bc56df1046
txscript: Add benchmark for isAnyKindOfScriptHash. 2019-03-26 14:51:07 -05:00
Dave Collins
51f76392b4
txscript: Add tests for stake-tagged script hash.
This adds tests to ensure the isAnyKindOfScriptHash function properly
identifies the four stake-tagged pay-to-script-hash possibilities in
addition to ensuring they are not misidentified as standard
pay-to-script-hash scripts.
2019-03-26 14:51:06 -05:00
Dave Collins
ffa6fb9e9d
txscript: Optimize GetSigOpCount.
This converts the GetSigOpCount function to make use of the new
tokenizer instead of the far less efficient parseScript thereby
significantly optimizing the function.

A new function named countSigOpsV0 which accepts the raw script is
introduced to perform the bulk of the work so it can be reused for
precise signature operation counting as well in a later commit.  It
retains the same semantics in terms of counting the number of signature
operations either up to the first parse error or the end of the script
in the case it parses successfully as required by consensus.

Finally, this also deprecates the getSigOpCount function that requires
opcodes in favor of the new function and modifies the comment on
GetSigOpCount to explicitly call out the script version semantics.

The following is a before and after comparison of analyzing a large
script:

benchmark                old ns/op    new ns/op    delta
-----------------------------------------------------------
BenchmarkGetSigOpCount   163896       1048         -99.36%

benchmark                old allocs   new allocs   delta
-----------------------------------------------------------
BenchmarkGetSigOpCount   1            0            -100.00%

benchmark                old bytes    new bytes    delta
-----------------------------------------------------------
BenchmarkGetSigOpCount   466945       0            -100.00%
2019-03-26 14:51:06 -05:00
Dave Collins
2d70450b7b
txscript: Add benchmark for GetSigOpCount. 2019-03-26 14:51:05 -05:00
Dave Collins
462eea3b82
txscript: Optimize IsMultisigSigScript.
This converts the IsMultisigSigScript function to analyze the raw script
and make use of the new tokenizer instead of the far less efficient
parseScript thereby significantly optimizing the function.

In order to accomplish this, it first rejects scripts that can't
possibly fit the bill due to the final byte of what would be the redeem
script not being the appropriate opcode or the overall script not having
enough bytes.  Then, it uses a new function that is introduced named
finalOpcodeData that uses the tokenizer to return any data associated
with the final opcode in the signature script (which will be nil for
non-push opcodes or if the script fails to parse) and analyzes it as if
it were a redeem script when it is non nil.

It is also worth noting that this new implementation intentionally has
the same semantic difference from the existing implementation as the
updated IsMultisigScript function in regards to allowing zero pubkeys
whereas previously it incorrectly required at least one pubkey.

Finally, the comment is modified to explicitly call out the script
version semantics.

The following is a before and after comparison of analyzing a large
script that is not a multisig script and both a 1-of-2 multisig public
key script (which should be false) and a signature script comprised of a
pay-to-script-hash 1-of-2 multisig redeem script (which should be true):

benchmark                           old ns/op    new ns/op     delta
-----------------------------------------------------------------------
BenchmarkIsMultisigSigScriptLarge   158149       4             -100.00%
BenchmarkIsMultisigSigScript        3445         202           -94.14%

benchmark                           old allocs   new allocs    delta
-----------------------------------------------------------------------
BenchmarkIsMultisigSigScriptLarge   9            0             -100.00%
BenchmarkIsMultisigSigScript        3            0             -100.00%

benchmark                           old bytes    new bytes     delta
-----------------------------------------------------------------------
BenchmarkIsMultisigSigScriptLarge   533189       0             -100.00%
BenchmarkIsMultisigSigScript        9472         0             -100.00%
2019-03-26 14:51:04 -05:00
Dave Collins
d7492c38ac
txscript: Add benchmarks for IsMutlsigSigScript. 2019-03-26 14:51:04 -05:00
Dave Collins
7b8259b4ed
txscript: Optimize IsMultisigScript.
This converts the IsMultisigScript function to make use of the new
tokenizer instead of the far less efficient parseScript thereby
significantly optimizing the function.

In order to accomplish this, it introduces two new functions.  The first
one is named extractMultisigScriptDetails and works with the raw script
bytes to simultaneously determine if the script is a multisignature
script, and in the case it is, extract and return the relevant details.
The second new function is named isMultisigScript and is defined in
terms of the former.

The extract function accepts the script version, raw script bytes, and a
flag to determine whether or not the public keys should also be
extracted.  The flag is provided because extracting pubkeys results in
an allocation that the caller might wish to avoid.

The extract function approach was chosen because it is common for
callers to want to only extract relevant details from a script if the
script is of the specific type.  Extracting those details requires
performing the exact same checks to ensure the script is of the correct
type, so it is more efficient to combine the two into one and define the
type determination in terms of the result so long as the extraction does
not require allocations.

It is important to note that this new implementation intentionally has a
semantic difference from the existing implementation in that it will now
correctly identify a multisig script with zero pubkeys whereas
previously it incorrectly required at least one pubkey.  This change is
acceptable because the function only deals with standardness rather than
consensus rules.

Finally, this also deprecates the isMultiSig function that requires
opcodes in favor of the new functions and deprecates the error return on
the export IsMultisigScript function since it really does not make sense
given the purpose of the function.

The following is a before and after comparison of analyzing both a large
script that is not a multisig script and a 1-of-2 multisig public key
script:

benchmark                        old ns/op    new ns/op    delta
-------------------------------------------------------------------
BenchmarkIsMultisigScriptLarge   121599       8.63         -99.99%
BenchmarkIsMultisigScript        797          72.8         -90.87%

benchmark                        old allocs   new allocs   delta
-------------------------------------------------------------------
BenchmarkIsMultisigScriptLarge   1            0            -100.00%
BenchmarkIsMultisigScript        1            0            -100.00%

benchmark                        old bytes    new bytes    delta
-------------------------------------------------------------------
BenchmarkIsMultisigScriptLarge   466944       0            -100.00%
BenchmarkIsMultisigScript        2304         0            -100.00%
2019-03-26 14:51:03 -05:00
Dave Collins
356492bc42
txscript: Add benchmarks for IsMutlsigScript. 2019-03-26 14:51:03 -05:00
Dave Collins
9f2f038842
txscript: Optimize IsPayToScriptHash.
This converts the IsPayToScriptHash function to analyze the raw script
instead of using the far less efficient parseScript thereby
significantly optimizing the function.

In order to accomplish this, it introduces two new functions.  The first
one is named extractScriptHash and works with the raw script bytes to
simultaneously determine if the script is a p2sh script, and in the case
it is, extract and return the hash.  The second new function is named
isScriptHashScript and is defined in terms of the former.

The extract function approach was chosen because it is common for
callers to want to only extract relevant details from a script if the
script is of the specific type.  Extracting those details requires
performing the exact same checks to ensure the script is of the correct
type, so it is more efficient to combine the two into one and define the
type determination in terms of the result so long as the extraction does
not require allocations.

Finally, this also deprecates the isScriptHash function that requires
opcodes in favor of the new functions and modifies the comment on
IsPayToScriptHash to explicitly call out the script version semantics.

The following is a before and after comparison of analyzing a large
script that is not a p2sh script:

benchmark                    old ns/op    new ns/op    delta
---------------------------------------------------------------
BenchmarkIsPayToScriptHash   139961       0.66         -100.00%

benchmark                    old allocs   new allocs   delta
---------------------------------------------------------------
BenchmarkIsPayToScriptHash   1            0            -100.00%

benchmark                    old bytes    new bytes    delta
---------------------------------------------------------------
BenchmarkIsPayToScriptHash   466944       0            -100.00%
2019-03-26 14:51:02 -05:00
Dave Collins
c705a0e31b
txscript: Add benchmark for IsPayToScriptHash. 2019-03-26 14:51:01 -05:00
Dave Collins
082d1ed6b4
txscript: Make isStakeOpcode accept raw opcode.
This converts the isStakeOpcode function to accept an opcode as a byte
instead of the internal opcode data struct in order to make it more
flexible for raw script analysis.

It also updates all callers accordingly.
2019-03-26 14:51:01 -05:00
Dave Collins
0ed8e25a1e
txscript: Make asSmallInt accept raw opcode.
This converts the asSmallInt function to accept an opcode as a byte
instead of the internal opcode data struct in order to make it more
flexible for raw script analysis.

It also updates all callers accordingly.
2019-03-26 14:51:00 -05:00
Dave Collins
44cbc3176c
txscript: Make isSmallInt accept raw opcode.
This converts the isSmallInt function to accept an opcode as a byte
instead of the internal opcode data struct in order to make it more
flexible for raw script analysis.

The comment is modified to explicitly call out the script version
semantics.

Finally, it updates all callers accordingly.
2019-03-26 14:50:59 -05:00
Dave Collins
06f769ef72
txscript: Convert sighash calc tests.
This converts the tests for calculating signature hashes to use the
exported function which handles the raw script versus the now deprecated
variant requiring parsed opcodes.
2019-03-26 14:50:59 -05:00
Dave Collins
c57dc2d6b0
txscript: Optimize CalcSignatureHash.
This modifies the CalcSignatureHash function to make use of the new
signature hash calculation function that accepts raw scripts without
needing to first parse them.  Consequently, it also doubles as a slight
optimization to the execution time and a significant reduction in the
number of allocations.

In order to convert the CalcScriptHash function and keep the same
semantics, a new function named checkScriptParses is introduced which
will quickly determine if a script can be fully parsed without failure
and return the parse failure in the case it can't.

The following is a before and after comparison of analyzing a large
multiple input transaction:

benchmark              old ns/op    new ns/op   delta
-------------------------------------------------------
BenchmarkCalcSigHash   2792057      2760042     -1.15%

benchmark              old allocs   new allocs  delta
-------------------------------------------------------
BenchmarkCalcSigHash   1691         1068        -36.84%

benchmark              old bytes    new bytes   delta
-------------------------------------------------------
BenchmarkCalcSigHash   521673       438604      -15.92%
2019-03-26 14:50:58 -05:00
Dave Collins
f306a72a16
txscript: Introduce raw script sighash calc func.
This introduces a new function named calcSignatureHashRaw which accepts
the raw script bytes to calculate the script hash versus requiring the
parsed opcode only to unparse them later in order to make it more
flexible for working with raw scripts.

Since there are several places in the rest of the code that currently
only have access to the parsed opcodes, this modifies the existing
calcSignatureHash to first unparse the script before calling the new
function.

Note that the code in the signature hash calculation to remove all
instances of OP_CODESEPARATOR from the script is removed because that is
a holdover from BTC code which does not apply to v0 Decred scripts since
OP_CODESEPARATOR is completely disabled in Decred and thus there can
never actually be one in the script.

Finally, it removes the removeOpcode function and related tests since it
is no longer used.
2019-03-26 14:50:57 -05:00
Dave Collins
e332430021
txscript: Optimize script disasm.
This converts the DisasmString function to make use of the new
zero-allocation script tokenizer instead of the far less efficient
parseScript thereby significantly optimizing the function.

In order to facilitate this, the opcode disassembly functionality is
split into a separate function called disasmOpcode that accepts the
opcode struct and data independently as opposed to requiring a parsed
opcode.  The new function also accepts a pointer to a string builder so
the disassembly can be more efficiently be built.

While here, the comment is modified to explicitly call out the script
version semantics.

The following is a before and after comparison of a large script:

benchmark               old ns/op    new ns/op    delta
----------------------------------------------------------
BenchmarkDisasmString   288729       94157        -67.39%

benchmark               old bytes    new bytes    delta
----------------------------------------------------------
BenchmarkDisasmString   584611       177528       -69.63%
2019-03-26 14:50:57 -05:00
Dave Collins
9b2ec27edd
txscript: Add benchmark for DisasmString. 2019-03-26 14:50:56 -05:00
Dave Collins
cb86bc073c
txscript: Introduce zero-alloc script tokenizer.
This implements an efficient and zero-allocation script tokenizer that
is exported to both provide a new capability to tokenize scripts to
external consumers of the API as well as to serve as a base for
refactoring the existing highly inefficient internal code.

It is important to note that this tokenizer is intended to be used in
consensus critical code in the future, so it must exactly follow the
existing semantics.

The current script parsing mechanism used throughout the txscript module
is to fully tokenize the scripts into an array of internal parsed
opcodes which are then examined and passed around in order to implement
virtually everything related to scripts.

While that approach does simplify the analysis of certain scripts and
thus provide some nice properties in that regard, it is both extremely
inefficient in many cases, and makes it impossible for external
consumers of the API to implement any form of custom script analysis
without manually implementing a bunch of error prone tokenizing code or,
alternatively, the script engine exposing internal structures.

For example, as shown by profiling the total memory allocations of an
initial sync, the existing script parsing code allocates a total of
around 295.12GB, which equates to around 50% of all allocations
performed.  The zero-alloc tokenizer this introduces will allow that to
be reduced to virtually zero.

The following is a before and after comparison of tokenizing a large
script with a high opcode count using the existing code versus the
tokenizer this introduces for both speed and memory allocations:

benchmark                old ns/op    new ns/op     delta
------------------------------------------------------------
BenchmarkScriptParsing   153099       961           -99.37%

benchmark                old allocs   new allocs    delta
------------------------------------------------------------
BenchmarkScriptParsing   1            0             -100.00%

benchmark                old bytes    new bytes     delta
------------------------------------------------------------
BenchmarkScriptParsing   466945       0             -100.00%

The following is an overview of the changes:

- Introduce new error code ErrUnsupportedScriptVersion
- Implement zero-allocation script tokenizer
- Add a full suite of tests to ensure the tokenizer works as intended
  and follows the required consensus semantics
- Add an example of using the new tokenizer to count the number of
  opcodes in a script
- Update README.md to include the new example
- Update script parsing benchmark to use the new tokenizer
2019-03-26 14:50:56 -05:00
Dave Collins
2f8f078f0e
txscript: Add benchmark for script parsing. 2019-03-26 14:50:55 -05:00
Dave Collins
e6a5701dae
txscript: Move init func in benchmarks to top. 2019-03-26 14:50:54 -05:00
Dave Collins
7f1da3bc07
txscript: Deprecate GetMultisigMandN.
This deprecates the GetMultisigMandN function which should never have
been added since the CalcMultiSigStats function already existed for this
purpose.

While here, redefine the function in terms of CalcMultiSigStats.
2019-03-26 14:50:53 -05:00
Dave Collins
b1b64d9228
txscript: Deprecate IsStakeOutput.
This function is only useful for internal consensus purposes within the
script engine and as such should not be exported.

While here, also add a comment to specify to the script version
semantics.
2019-03-26 14:50:53 -05:00
Dave Collins
60d41d1230
txscript: Deprecate HasP2SHScriptSigStakeOpCodes.
This function is only useful for internal consensus purposes within the
script engine and as such should not be exported.
2019-03-26 14:50:52 -05:00
VcTT
8695142d02 txscript: Add stake tx remove opcode tests.
txscript: Add stake tx remove opcode tests.
2019-03-26 14:49:15 -05:00
David Hill
3d2d557614 multi: deprecate DisableLog 2019-03-18 11:16:35 -05:00
David Hill
69bac3189f multi: drop init and just set default log 2019-03-18 11:16:35 -05:00
Dave Collins
0f50fd5f8c
multi: Add go 1.11 directive to all modules.
This adds the go 1.11 directive to all of the modules in order to
clearly mark they build and work with that version.  Go 1.12 modified
the tools such that tidy will automatically add the new version to
modules that do not already have a directive and that would prevent
builds on Go 1.11 through Go 1.11.3 which is not desirable.
2019-03-18 02:02:35 -05:00
Dave Collins
8c477528f1
txscript: Introduce constant for max CSV bytes.
As is already well commented in the code, the sequence number parameter
of the CHECKSEQUENCEVERIFY opcode requires 5 bytes instead of the
standard 4 bytes allowed by math opcodes.  This introduces a constant
for the value instead of hardcoding 5 to increase readability and
potentially allow the value to be exported in the future.
2019-03-12 10:26:04 -05:00
Dave Collins
b19842a4c4
txscript: Introduce constant for max CLTV bytes.
As is already well commented in the code, the locktime parameter of the
CHECKLOCKTIMEVERIFY opcode requires 5 bytes instead of the standard 4
bytes allowed by math opcodes.  This introduces a constant for the value
instead of hardcoding 5 to increase readability and potentially allow
the value to be exported in the future.
2019-03-12 10:13:06 -05:00
Dave Collins
a729ce27e0
txscript: Tighten standardness pubkey checks.
This tightens the multisig and pay-to-pubkey standard script
identification functions to use the same strict pubkey requirements as
the consensus rules since standardness rules are generally intended to
be more restrictive than the consensus rules which implies they are at a
minimum at least as restrictive.

The tests are also updated to deal with the additional restriction
accordingly.
2019-03-11 19:33:27 -05:00
Dave Collins
03c9bbf1e5
txscript: Consistent checksigaltverify handling.
This introduces a new error named ErrCheckSigAltVerify and modifies the
opcodeCheckSigAltVerify handler to use the abstractVerify function along
with the new error.  This makes the handling consistent with all other
signature checking verification opcode handlers and ensures the error
both can be programmatically detected as well as be uniquely identified
as compared to a generic verify failure.
2019-03-08 20:36:04 -06:00
Dave Collins
c0124570cd
txscript: Rename p2sh indicator to isP2SH.
This renames the flag that indicates whether or not the script engine is
executing a pay-to-script-hash script pair to a name that more
accurately describes its behavior.
2019-02-14 16:35:30 -06:00
Dave Collins
1f5abadc08
txscript: Add remove signature reference test.
An important (and easy for implementations to miss) aspect of the
CHECKSIG opcodes is that the full signature (signature plus hash type)
that is being checked is first removed from the script prior to
calculating the signature hash against which the signature is verified.

It appears the test in the upstream btcsuite code for this was removed
during the initial Decred port instead of being converted as it should
have been.

Consequently, this converts the relevant test so it is correct for
Decred and adds it to the reference tests.  Note that the first of the
two added tests is to ensure the original signature is valid prior to
testing the actual removal condition.
2019-02-14 14:10:12 -06:00
David Hill
85443cafa9 multi: cleanup linter warnings 2019-02-13 08:38:25 -05:00
Dave Collins
e052b9cbf2
multi: Remove non-root module replacements.
This modifies all of the modules, with the exception of the root module,
to remove all replacement directives from their go.mod files and update
the requirements and module sums accordingly.

While it is nice to be able to build and test directly from each module
directory and have it pull in the latest untagged changes when
developing, having all of the overrides in each module makes it
infeasible to use the module tools to help maintain the modules and thus
makes it quite difficult to ensure they are all independently accurate
for external consumers.

By maintaining all of the overrides in the root module and invoking all
builds and tests from it, the overrides will apply to ensure the latest
code is being built and tested.

This also modifies the tests script used with in CI to run all of the
tests from the root module accordingly.
2019-02-08 18:01:43 -06:00
David Hill
b1bbf8091b txscript: code cleanup
- switch if-else to switch/case for readability
- remove unused params
2019-02-08 09:18:53 -05:00
Dave Collins
1a370d38d6
release: Tidy module files with published versions. 2018-12-12 12:18:11 -06:00
Dave Collins
220d434b6e
release: Bump module versions and deps.
This bumps the various module versions as follows:

- github.com/decred/dcrd/dcrec/secp256k1@v1.0.1
- github.com/decred/dcrd/dcrjson@v1.1.0
- github.com/decred/dcrd/database@v1.0.3
- github.com/decred/dcrd/blockchain/stake@v1.1.0
- github.com/decred/dcrd/mining@v1.1.0
- github.com/decred/dcrd/certgen@v1.0.2
- github.com/decred/dcrd/connmgr@v1.0.2
- github.com/decred/dcrd/mempool@v1.1.0

In addition, it serves as a base for tagging releases of the following
module versions that have previous been bumped since the last release,
but not yet tagged:

- github.com/decred/dcrd/wire@v1.2.0
- github.com/decred/dcrd/chaincfg@v1.2.0
- github.com/decred/dcrd/dcrutil@v1.2.0
- github.com/decred/dcrd/txscript@v1.0.2
- github.com/decred/dcrd/blockchain@v1.1.0
- github.com/decred/dcrd/hdkeychain@v1.1.1
- github.com/decred/dcrd/peer@v1.1.0
- github.com/decred/dcrd/rpcclient@v1.1.0

Finally, it updates all of the dependencies for every module accordingly,
adds a few missing overrides for transitive dependencies, and tidies up
some of the go module sum files.
2018-12-10 11:18:00 -06:00
David Hill
617fca8a93 txscript: Use ScriptBuilder more. 2018-12-04 01:11:20 -06:00
David Hill
5f8081761d multi: Remove unused code. 2018-10-31 21:50:09 -04:00
Dave Collins
6f9b6f1c6e
multi: Use regression test network in unit tests.
This modifies the majority of the tests that make use of chain
parameters and the RPC tests to use the resurrected regression test
network.

It also bumps the affected module versions as follows:

- github.com/decred/dcrd/txscript@v1.0.2
- github.com/decred/dcrd/blockchain/stake@v1.0.3
- github.com/decred/dcrd/mempool@v1.0.2

The blockchain and dcrutil modules are also affected, but since their
version has already been bumped since their last release tags, they are
not bumped again.
2018-10-09 19:40:10 -05:00
Donald Adu-Poku
60cbb70c67 txscript: add stake opcode tests. 2018-09-11 20:21:42 +00:00
Donald Adu-Poku
e0222e383c txscript: add p2sh opcode tests. 2018-09-11 20:14:29 +00:00
Donald Adu-Poku
566bb6625b txscript: group numeric encoding tests with their opcodes.
This also moves some dangling tests to their respective opcode groupings as well as some updates to  test comments.
2018-09-10 17:48:02 -05:00
Dave Collins
36f61d8ebd build: Tidy module sums (go mod tidy). 2018-08-16 20:03:27 -05:00
Dave Collins
9536f0c88f
release: Bump module versions and deps.
This bumps the various module versions as follows:

- github.com/decred/dcrd/addrmgr@v1.0.2
- github.com/decred/dcrd/wire@v1.1.0
- github.com/decred/dcrd/chaincfg@v1.1.1
- github.com/decred/dcrd/connmgr@v1.0.1
- github.com/decred/dcrd/dcrutil@v1.1.1
- github.com/decred/dcrd/database@v1.0.1
- github.com/decred/dcrd/hdkeychain@v1.1.0
- github.com/decred/dcrd/txscript@v1.0.1
- github.com/decred/dcrd/blockchain/stake@v1.0.1
- github.com/decred/dcrd/gcs@v1.0.1
- github.com/decred/dcrd/blockchain@v1.0.1
- github.com/decred/dcrd/mining@v1.0.1
- github.com/decred/dcrd/mempool@v1.0.1
- github.com/decred/dcrd/peer@v1.0.1
- github.com/decred/dcrd/rpcclient@v1.0.1

It also updates all of the dependencies for every module accordingly and
adds a few missing overrides for transitive dependencies.
2018-08-09 14:30:22 -05:00
Dave Collins
96a1a8546d
multi: Reduce testnet2 refs in unit tests.
This modifies the test code for several unit tests to prefer using
another network, such as mainnet or simnet, when not specifically
testing something that requires testnet.

In the cases where where testnet is required, it also now prefers a
local reference over directly accessing the testnet parameters directly
from the chaincfg package.

This is being done because the test network undergoes periodic resets
and by reducing the number of direct references, it simplifies the
process of resetting it.
2018-08-08 06:41:50 -05:00
Dave Collins
295179fc0d
build: Refine build module support.
This further refines the modules to add the following new modules
instead of depending on the entire dcrd module:

- github.com/decred/dcrd/dcrjson@v1.0.0
- github.com/decred/dcrd/blockchain@v1.0.0
- github.com/decred/dcrd/blockchain/stake@v1.0.0
- github.com/decred/dcrd/gcs@v1.0.0
- github.com/decred/dcrd/mining@v1.0.0
- github.com/decred/dcrd/mempool@v1.0.0
- github.com/decred/dcrd/peer@v1.0.0
- github.com/decred/dcrd/rpcclient@v1.0.0

Also, it ensures modules that rely on other modules within the repo are
provided replacements to the latest repo code to ensure builds against
master and continuous integration use the latest code.

- github.com/decred/dcrd/addrmgr
- github.com/decred/dcrd/blockchain
- github.com/decred/dcrd/blockchain/stake
- github.com/decred/dcrd/chaincfg
- github.com/decred/dcrd/connmgr
- github.com/decred/dcrd/database
- github.com/decred/dcrd/dcrec/secp256k1
- github.com/decred/dcrd/dcrjson
- github.com/decred/dcrd/dcrutil
- github.com/decred/dcrd/gcs
- github.com/decred/dcrd/hdkeychain
- github.com/decred/dcrd/mempool
- github.com/decred/dcrd/mining
- github.com/decred/dcrd/peer
- github.com/decred/dcrd/rpcclient
- github.com/decred/dcrd/txscript
- github.com/decred/dcrd/wire
2018-08-05 20:45:45 -05:00
Donald Adu-Poku
3978c40b50 txscript: add/group crypto related op code tests. 2018-07-29 23:06:54 -05:00
Donald Adu-Poku
4fcdfab3c2 txscript: group reserved op code tests.
this groups reserved op codes and moves some dangling tests to their respective groups.
2018-07-29 22:46:55 -05:00
Donald Adu-Poku
1ce290d979 txscript: add/group numeric related opcode tests. 2018-07-29 21:10:59 -05:00
Donald Adu-Poku
315e0a9acd txscript: add/group bitwise logic, comparison & rotation op code tests. 2018-07-27 21:24:28 +00:00
Donald Adu-Poku
245c82557c txscript: group splice opcode tests. 2018-07-26 16:30:02 -05:00
Donald Adu-Poku
34a33e1e57 txscript: add/group stack op code tests. 2018-07-25 23:28:45 -05:00
Donald Adu-Poku
59cc2a447e txscript: add/group control op code tests. 2018-07-24 23:02:25 -05:00
Donald Adu-Poku
fb18a45553 txscript: add additional data push op code tests.
This adds tests for OP_DATA_[1...75], OP_1NEGATE, OP_RESERVED, OP_TRUE, OP_[1...16], OP_PUSHDATA1 and OP_PUSHDATA2.
2018-07-23 20:49:48 -05:00
Dave Collins
4a3343f2f1
txscript: Refine go build module support.
Now that the chaincfg, chainhash, dcrec, edwards, secp256k1, dcrutil,
wire, and slog modules have been defined, update the txscript module to
only depend on them instead of the entire dcrd module.
2018-07-21 14:40:32 -05:00
Dave Collins
d052898731
txscript: Update comments for removal of flags.
This updates various comments to accurately reflect reality now that
several script verification flags have been removed.
2018-07-06 11:56:47 -05:00
Dave Collins
d3199d2aa9
multi: Remove unused secp256k1 sig parse parameter.
This removes the unused curve parameter from the ParseSignature and
ParseDERSignature functions of the secp256k1 package and updates all
callers in the repository accordingly.
2018-07-04 12:27:34 -05:00
David Hill
01316e20f3 multi: Continue conversion from chainec to dcrec. 2018-07-04 11:21:43 -04:00
Dave Collins
370d0daba5
txscript: Make PeekInt consistent with PopInt.
This modifies the PeekInt function of the stack to accept a maximum
script number length to mirror PopInt for consistency.  It also updates
the two callers CLTV and CSV) which were manually performing the same
task with 5 bytes due to PeekInt enforcing 4-byte script nums to use the
modified version accordingly.

It also adds some stack tests for 5-byte encodings on both PopInt and
PeekInt.
2018-07-02 12:14:37 -05:00
Dave Collins
84b65d049b
txscript: Remove script num require minimal flag.
This removes the flag to require minimal encoding when create script
numbers since since all callers now call the function with true due to
the recent removal of the minimal data script verification flag from the
script engine and updates the tests accordingly.
2018-07-02 12:14:15 -05:00
Dave Collins
535e4adb04
txscript: Remove MINIMALDATA flag from test data.
This removes the MINIMALDATA script verify flag from the various
reference test data since it is now a noop due to the corresponding flag
being removed from the script engine.
2018-07-02 12:04:30 -05:00
Dave Collins
f5dc86e9cc
txscript: Remove verify minimal data flag.
This removes the ScriptVerifyMinimalData flag from the txscript package,
changes the default semantics to always enforce its behavior, and
updates all callers in the repository accordingly.

This change is being made to simplify the script engine code since the
flag has always been active and required by consensus in Decred, so
there is no need to require a flag to conditionally toggle it.

It should be noted that the tests removed from script_tests.json
specifically dealt with ensuring equivalency of different ways to encode
the same numbers when the ScriptVerifyMinimalData flag is not set.
Therefore, they are no longer necessary.

A few tests which dealt with equivalency that did not already have
expected failing counterparts were converted to expected failure.

Also, several of the tests which dealt with ensuring the specific
encoding of numeric opcodes is being used have been converted to use
hashes since the minimal data requirements specifically prevent
alternate ways of pushing the same encoding which is necessary for
directly checking equality of the raw bytes.

Finally, the MINIMALDATA indicator to enable the flag in the test data
has been retained for now in order to isolate the logic changes as much
as possible.
2018-07-02 12:02:59 -05:00
Dave Collins
a8e9a63684
txscript: Remove DERSIG flag from test data.
This removes the DERSIG script verify flag from the various reference
test data since it is now a noop due to the corresponding flag being
removed from the script engine.
2018-07-02 12:02:41 -05:00
Dave Collins
98e0b27dd8
txscript: Remove DER signature verification flag.
This removes the ScriptVerifyDERSignatures flag from the txscript
package, changes the default semantics to always enforce its behavior
and updates all callers in the repository accordingly.

This change is being made to simplify the script engine code since the
flag has always been active and required by consensus in Decred, so
there is no need to require a flag to conditionally toggle it.

It should be noted that the tests removed from script_tests.json
specifically dealt with ensuring non-DER-compliant signatures were
handled properly when the ScriptVerifyDERSignatures flag was not set.
Therefore, they are no longer necessary.

Finally, the DERSIG indicator to enable the flag in the test data has
been retained for now in order to keep the logic changes separate.
2018-07-02 12:02:28 -05:00
Dave Collins
d12e172fee
txscript: Remove P2SH flag from test data.
This removes the P2SH script verify flag from the various reference test
data since it is now a noop due to the corresponding flag being removed
from the script engine.
2018-07-02 12:02:14 -05:00
Dave Collins
2157079165
txscript: Remove pay-to-script-hash flag.
This removes the ScriptBip16 flag from the txscript package, changes the
default semantics to always enforce its behavior, and updates all
callers in the repository accordingly.

This change is being made to simplify the script engine code since the
flag has always been active and required by consensus in Decred, so there is
no need to require a flag to conditionally toggle it.

Also, since it is no longer possible to invoke the script engine without
the flag with the clean stack flag, it removes the now unused
ErrInvalidFlags error and associated tests.

It should be noted that the test removed from script_tests.json
specifically dealt with ensuring a signature script that contained
non-data-pushing opcodes was successful when neither the ScriptBip16 or
ScriptVerifySigPushOnly flags were set.  Therefore, it is no longer
necessary.

Finally, the P2SH indicator to enable the flag in the test data has been
retained for now in order to keep the logic changes separate.
2018-07-02 12:01:42 -05:00
Dave Collins
c0be0be19a
txscript: Convert reference tests to new format.
This updates the data driven transaction script tests to combine the
previously separate valid and invalid test data files into a single file
and adds a field for the expected result.  This is a nice improvement
since it means tests can now ensure script failures are due to a
specific expected reason as opposed to only generically detecting
failure as the previous format required.

Since it is possible that the script engine might return more fine
grained errors than that test data expects, the test adapter handles
this by allowing expected errors in the test data to be mapped to
multiple txscript errors.

While performing the conversion, it also adds several tests for the
following areas:

- The test harness itself to ensure the parsing logic, particularly for
  the recently added repetition syntax, is working as intended
- All of the opcodes which were converted to NOPs in Decred
  to ensure they are also discouraged from use
- All of the reserved opcodes in Decred
2018-07-02 11:59:13 -05:00
Dave Collins
d8306ee602
txscript: Significantly improve errors.
This converts the majority of script errors from generic errors created
via errors.New and fmt.Errorf to use a concrete type that implements the
error interface with an error code and description.

This allows callers to programmatically detect the type of error via
type assertions and an error code while still allowing the errors to
provide more context.

For example, instead of just having an error the reads "disabled opcode"
as would happen prior to these changes when a disabled opcode is
encountered, the error will now read "attempt to execute disabled opcode
OP_FOO".

While it was previously possible to programmatically detect many errors
due to them being exported, they provided no additional context and
there were also various instances that were just returning errors
created on the spot which callers could not reliably detect without
resorting to looking at the actual error message, which is nearly always
bad practice.

Also, while here, export the MaxStackSize and MaxScriptSize constants
since they can be useful for consumers of the package and perform some
minor cleanup of some of the tests.
2018-07-01 15:04:59 -05:00
Dave Collins
dd0bfb639c
txscript: Cleanup P2SH and stake opcode handling.
This slightly cleans up the handling for pay-to-script-hash scripts and
related stake opcode checking as follows:

- Move the isScriptHash and isAnyKindOfScriptHash functions to script.go
  since they are required by consensus and therefore do not belong in
  standard.go which is reserved for standardness only rules
- Introduce a new function named isStakeOpcode and use it throughout
  versus repeating the specific logic in multiple places
- Use the stake opcode constants instead of magic numbers in the
  aforementioned new function
- Introduce a new function named isStakeScriptHash which specifically
  determines if a script is of the special stake p2sh form
- Update isAnyKindOfScriptHash to make use of the original isScriptHash
  function instead of repeating the logic and the newly introduced
  isStakeScriptHash function
2018-07-01 14:58:16 -05:00
Dave Collins
d70581c8f0
txscript: Cleanup plus tests for checksig opcodes.
This cleans up the code for handling the checksig and checkmultisig
opcodes to explicitly call out any semantics that are likely not
obvious, correct some comments, and improve readability.

It also adds several tests to the reference script tests which exercise
the semantics of the check[multi]sig opcodes including both positive and
negative tests.

Finally, it corrects nearly all of the negative tests related to
signature checking of the script tests which were not properly updated
for the differences introduced by Decred so that they fail for the
intended reasons.

The malformed signatures in the tests were very carefully crafted to be
valid except for the very specific condition being tested.  The majority
of the negative tests modified and added can be manually verified by
commenting out the relevant checks in the script engine, although a few
of them will pass because they fail for other reasons.  In those cases,
prints can be added to ensure the expected failure path is being hit.
2018-06-29 11:15:24 -05:00
Dave Collins
d3731898e9
txscript: Remove STRICTENC flag from test data.
This removes the STRICTENC script verify flag from the various test data
since it is now a noop due to the corresponding flag being removed from
the script engine.
2018-06-22 00:30:02 -05:00
Dave Collins
c9ca59bf66
txscript: Remove strict encoding verification flag.
This removes the ScriptVerifyStrictEncoding flag from the txscript
package, changes the default semantics to always enforce its behavior
and updates all callers in the repository accordingly.

This change is being made to simplify the script engine code since the
flag has always been active and required by consensus in Decred, so
there is no need to require a flag to conditionally toggle it.

It should be noted that the tests removed from script_valid.json
specifically dealt with ensuring signatures not compliant with DER
encoding did not cause execution to halt early on invalid signatures
when neither of the ScriptVerifyStrictEncoding or
ScriptVerifyDERSignatures flags were set.  Therefore, they are no longer
necessary.

For nearly the same reason, the tx test related to the empty pubkey
tx_valid.json was moved to tx_invalid.json.  In particular, an empty
pubkey without ScriptVerifyStrictEncoding simply failed the signature
check and continued execution, while the same condition with the flag
halts execution.  Thus, without the flag the final NOT in the script
would allow the script to succeed, while it does not under the strict
encoding rules.

Finally, the STRICTENC indicator to enable the flag in the test data has
been retained for now in order to keep the logic changes separate.
2018-06-22 00:29:46 -05:00
Dave Collins
3aa1930845
txscript: Remove unused old sig hash type.
This removes the SigHashOld definition from the txscript package since
it both has never been used in Decred and it has also always been
invalid to use due to the fact that strict encoding has always been
active and required by consensus in Decred.
2018-06-22 00:29:33 -05:00
Dave Collins
7815f0c851
txscript: Remove low S verification flag.
This removes the ScriptVerifyLowS flag from the txscript package,
changes the default semantics to always enforce its behavior and updates
all callers in the repository accordingly.

This change is being made to simplify the script engine code since the
flag has always been active and required by consensus in Decred, so
there is no need to require a flag to conditionally toggle it.
2018-06-22 00:28:54 -05:00
Donald Adu-Poku
b105a9ef49 multi: add valueIn parameter to wire.NewTxIn.
This adds the valueIn parameter to wire.NewTxIn. Call sites and associated tests have also been updated.
2018-06-15 19:13:41 -05:00
Dave Collins
39be89d2eb
txscript: Improve and correct some script tests.
This corrects some of the script tests which were not properly updated
for the differences introduced by Decred as well as adds some additional
tests for some updated semantics.

Namely:

- Correct the redeem script hash of several tests so they fail for the
  intended reason instead of due to having an invalid script hash
- Correct multisig tests to remove the dummy parameter which is not
  needed by Decred
- Change the tests for previously reserved opcodes to discouraged
  upgradable NOP tests to match their new semantics
- Add tests to ensure all discourage NOPs are allowed when in an
  unexecuted branch
- Add tests to ensure all reserved opcodes that are not always illegal
  are allowed when in an unexecuted branch
2018-06-15 13:18:14 -05:00
Dave Collins
3608e8ab74
txscript: Allow multi opcode test data repeat.
This expands upon the recently added ability to specify repeated
raw and quoted data in the test data short script form syntax to also
add syntax to allow repeated sequences of opcodes and updates several
tests to make use of it.

While here, it also corrects a few tests to actually test what they were
originally intended to test but were not updated correctly for Decred
limit changes.  In particular, the following tests were corrected:

- The negative test that ensures exceeding the max opcode limit via
  CHECKMULTISIG and CHECKMULTISIGVERIFY results in failure
- The positive test that ensures hitting the max opcode limit via
  CHECKMULTISIG and CHECKMULTISIGVERIFY with and without keys succeeds
2018-06-15 12:11:02 -05:00
Dave Collins
9e23c8e8ea
txscript: Introduce repeated syntax to test data.
This improves the test data short script form syntax to allow repeated
raw and quoted data and updates several tests to make use of it.

While here, it also corrects a few tests to actually test what they were
originally intended to test but were not updated correctly for Decred
limit changes.  In particular, the following tests were corrected:

- The negative test that ensures to exceeding the maximum allowed script
  size results in failure
- The positive test that ensures a fully maxed out script (max script
  size, max element size push, max opcodes, and max stack items)
  succeeds
- The positive test that ensures OP_RESERVED does not count towards the
  opcode limit
2018-06-14 16:48:04 -05:00
Dave Collins
543ebff573
txscript: Update CSV to match tests in DCP0003. 2018-06-14 10:10:39 -05:00
Dave Collins
ca7eeee6af
txscript: Cleanup and add tests for mod opcode.
This cleans up the code for handling the mod opcode to explicitly call
out its semantics which are likely not otherwise obvious as well as
improve its readability.

It also adds several tests to the reference script tests which exercise
the semantics of the div opcode including both positive and negative
tests.
2018-06-13 16:53:40 -05:00
Dave Collins
1080a9709a
txscript: Cleanup and add tests for div opcode.
This cleans up the code for handling the div opcode to explicitly call
out its semantics which are likely not otherwise obvious as well as
improve its readability.

It also adds several tests to the reference script tests which exercise
the semantics of the div opcode including both positive and negative
tests.
2018-06-13 16:53:24 -05:00
Dave Collins
0ee1468f40
txscript: Cleanup and add tests for rshift opcode.
This cleans up the code for handling the right shift opcode to
explicitly call out its semantics which are likely not otherwise obvious
as well as improve its readability.

It also adds several tests to the reference script tests which exercise
the semantics of the right shift opcode including both positive and
negative tests.
2018-06-13 16:52:36 -05:00
Dave Collins
f8d8dbcd19
txscript: Cleanup and add tests for lshift opcode.
This cleans up the code for handling the left shift opcode to explicitly
call out its semantics which are likely not otherwise obvious as well as
improve its readability.

It also adds several tests to the reference script tests which exercise
the semantics of the left shift opcode including both positive and
negative tests.
2018-06-13 16:51:09 -05:00
Dave Collins
71f86bec32
txscript: Cleanup and add tests for rotl opcode.
This cleans up the code for handling the left rotation opcode to
explicitly call out its semantics which are likely not otherwise obvious
as well as improve its readability.

It also adds several tests to the reference script tests which exercise
the semantics of the left rotation opcode including both positive and
negative tests.
2018-06-13 16:39:44 -05:00
Dave Collins
9644ec433e
txscript: Cleanup and add tests for rotr opcode.
This cleans up the code for handling the right rotation opcode to
explicitly call out its semantics which are likely not otherwise obvious
as well as improve its readability.

It also adds several tests to the reference script tests which exercise
the semantics of the right rotation opcode including both positive and
negative tests.
2018-06-13 16:30:38 -05:00
Dave Collins
e84ee743d2
txscript: Cleanup and add tests for the cat opcode.
This cleans up the code for handling the cat opcode to more closely
match the style used by the rest of the code and improves its test
coverage by adding several tests to the reference script tests which
exercise its semantics including both positive and negative tests.
2018-06-12 12:43:30 -05:00
Dave Collins
549aae93ce
txscript: Cleanup and add tests for right opcode.
This cleans up the code for handling the right opcode to explicitly call
out its semantics which are likely not otherwise obvious as well as
improve its readability.

It also adds several tests to the reference script tests which exercise
the semantics of the right opcode including both positive and negative
tests.
2018-06-12 12:42:49 -05:00
Dave Collins
dc7849061c
txscript: Cleanup and add tests for left opcode.
This cleans up the code for handling the left opcode to explicitly call
out its semantics which are likely not otherwise obvious as well as
improve its readability.

It also adds several tests to the reference script tests which exercise
the semantics of the left opcode including both positive and negative
tests.
2018-06-12 00:22:14 -05:00
Donald Adu-Poku
900e5964db txscript: export canonicalDataSize.
This is needed in determining signed input
script sizes of multisig outputs.
2018-06-06 18:26:24 +00:00
Dave Collins
c476afa931
txscript: Cleanup code for the substr opcode.
This cleans up the code for handling the substr opcode to explicitly
call out its semantics which are likely not otherwise obvious as well as
improve its readability.
2018-05-25 20:28:57 -05:00
Dave Collins
45e313e6d2
multi: Define vgo modules.
This adds module support for the versioned go toolchain.  In particular,
the following packages are defined as modules:

* addrmgr
* blockchain
* certgen
* chaincfg
* connmgr
* database
* dcrjson
* dcrutil
* gcs
* hdkeychain
* mempool
* mining
* peer
* rpcclient
* txscript
* wire

It does not update the travis build environment or README since it is
experimental at this point.
2018-05-25 15:38:16 -05:00
Dave Collins
678ff1efdd
multi: Replace btclog with slog.
This modifies all packages within the repository to the use the Decred
fork of btclog which has been renamed to slog and updates the dependency
files accordingly.
2018-05-23 14:22:10 -05:00
Dave Collins
3a81a21ec9
txscript: Improve substr opcode test coverage.
This adds several tests to the reference script tests which exercise the
semantics of the substr opcode including both positive and negative
tests.
2018-05-15 03:38:18 -05:00
Dave Collins
f54fb6ce67
txscript: Remove unused strict multisig flag.
This removes the ScriptStrictMultiSig flag from the txscript package
since it is not used or needed by Decred.

The flag is a holdover from the upstream code which was used to address
a bug that does not exist in Decred.
2018-05-15 02:34:22 -05:00
Dave Collins
66f5acc9aa
multi: Correct typos found by misspell. 2018-05-08 21:29:33 -05:00
Dave Collins
75432b3c96
multi: Break coinbase dep on standardness rules.
Standardness rules are not the same as consensus rules and it is
important to keep clear separation between them, because standardness
rules can and do change, while the consensus rules must not change
without a specific vote, and even then, the old rules must be kept
around for validation of all blocks prior to any changes introduced by a
successful vote.

Prior to this commit, the blockchain code which enforces the consensus
rule that requires the second output of the coinbase transaction to
contain the height of the block in a provably pruneable nulldata script
push was relying on code in txscript/standard.go, which, as the name of
the file suggests, is specifically intended for code related to
standardness checks.

This introduces a new function in the txscript package named
ExtractCoinbaseNullData which does not rely on any of the code related
to standardness checks and modifies the blockchain code accordingly to
make use of the new function instead.  It also removes the
standardness-dependent GetNullDataContent function which is no longer
used by anything.

Finally, it adds tests in the txscript package to ensure the new
function has the required semantics.
2018-05-08 12:49:40 -05:00
Dave Collins
5717411882
txscript: Decouple and optimize sighash calc.
This modifies the signature hash calculation logic to completely
decouple it from the wire transaction serialization and significantly
optimizes it in the process.  It also significantly improves the
comments to specifically call out the semantics.

This change is highly desirable because it has several beneficial
properties:

- The signature hash semantics are much clearer and specific
- There is no longer a need to copy the entire transaction and modify
  the relevant portions since the necessary substitutions are made on
  the fly
- Allows much faster calculation by serializing directly into byte
  slices and avoiding all of the additional error handling logic
  dedicated to handling network streams
- Provides the possibility of changing the wire format without breaking
  signature hash calculation
  - Note that the caching portion still relies on the wire format, but
    that can be addressed in future commits since it is merely an
    optimization that can also be decoupled

The following is a before and after comparison of signature hash
calculation for both speed and memory allocations for a transaction with
many inputs:

benchmark                old ns/op     new ns/op     delta
------------------------------------------------------------
BenchmarkCalcSigHash     6299714       1551740       -75.37%

benchmark                old allocs    new allocs    delta
------------------------------------------------------------
BenchmarkCalcSigHash     18601         1691          -90.91%
2018-05-01 08:51:41 -05:00
Dave Collins
b51a3bb396
txscript: Add benchmark for sighash calculation. 2018-05-01 08:51:38 -05:00
Dave Collins
a068101639
txscript: Correct JSON-based signature hash tests.
This updates the recently-added JSON-based signature hash test data to
actually test the SigHashAnyOneCanPay flag in the non-fuzzer
transactions as intended.

The flag is 0x80, but the JSON test data specifies the signature hash
type in decimal, so SigHashAll|SigHashAnyOneCanPay, which is 0x81,
should've been specified as 129 decimal instead of 81 decimal.  The same
applies to all combinations with the SigHashAnyOneCanPay flag.
2018-04-30 18:18:18 -05:00
Dave Collins
47cbc26b93
txscript: Add JSON-based signature hash tests.
This adds a significant number of JSON-based tests with various
transactions, scripts, and hash types, to ensure the signature hash
calculated generates the expected hash in each case.

It specifically tests some specialized transactions such as coinbase,
ticket purchase, vote, and revocation.  It also includes carefully
created tests for all combinations of defined hash types along with
triggering an error due to improper use of SigHashSingle.

Finally, it also includes fuzz testing by providing a selection of 100
regular transactions with various numbers of inputs and outputs along
with randomly generated (including undefined) signature hash types and
input indexes.  Due to the way that masking of the signature hash type
works, a couple of the fuzzer tests also hit the improper use of
SigHashSingle.

The test data was generated as JSON in order to make it easier for
developers of software in other languages and platforms that need to
deal with generating signature hashes to consume and prove correctness
of their implementation as well.
2018-04-30 12:14:14 -05:00
Dave Collins
2cb2d9a22a
txscript: Consolidate tests into txscript package.
Putting the test code in the same package makes it easier for forks
since they don't have to change the import paths as much and it also
gets rid of the need for internal_test.go to bridge.

Also, do some light cleanup on a few tests while here.
2018-04-30 10:34:59 -05:00
Dave Collins
6fe33fc277
txscript: Remove SigHashAllValue.
This removes the SigHashAllValue signature hash type.  This is being
done because it is not currently usable without a consensus change due
to a consensus rule which enforces strict signature encoding disallowing
the hash type.

While it would be possible to change the consensus rule in question to
include SigHashAllValue, that would obviously require a consensus vote
since it constitutes a change to the consensus rules.  Given that a vote
is required to make any changes in regards to this, it is ideal to
completely change the algorithm altogether to not only address this
issue, but also to address other shortcomings in regards to efficiency
and complexity of the current algorithm in addition to committing to all
input amounts per the aforementioned description.
2018-04-30 09:10:02 -05:00
Dave Collins
f6be618a1b
txscript: Move sig hash logic to separate file.
This moves the logic to calculate the signature hash and the associated
test to separate files.  Since there will ultimately be a new signature
algorithm, it makes sense to separate all logic related to signature
hashes for better code organization.

It contains no functional changes.
2018-04-30 08:54:07 -05:00
Josh Rickmar
e944badc9b chainec/dcrec: Remove hybrid pubkey support
This is a follow-up to a previous change which removed the ability to
create a dcrutil.Address from a hybrid pubkey.  It removes all
secp256k1 hybrid pubkey support from the chainec/dcrec packages since
these pubkeys are not usable when evaluated by OP_CHECKSIG or
OP_CHECKMULTISIG.

While ParsePubKey is called by consensus code and its behavior has
been changed to error when encountering a hybrid secp256k1 pubkey,
this is not a consensus change as every use of ParsePubKey in
consensus code either checks beforehand that the pubkey is compressed
or uncompressed, requires a parsed address to be P2PKH or P2SH, or
checks an address string against the premine ledger (which only
contains P2PKH addresses).
2018-03-20 17:45:09 -04:00
Markus Richter
1e42b8524d multi: Properly capitalize Decred.
Decred is inconsistencly capitalized in the code base,
change all occurences of decred to Decred.
2018-03-01 17:41:35 -06:00
David Hill
5fc31ca578 multi: fix misspell linter warnings 2018-02-18 12:26:52 -06:00
Josh Rickmar
5eb3296508 Require atomic swap contracts to specify the secret size.
This allows redeeming parties to audit the secret size and ensure it
will be usable once revealed.
2018-02-16 15:14:27 -06:00
David Hill
393a95c079 multi: fix some maligned linter warnings 2018-02-13 14:50:33 -06:00
David Hill
e45c34fbfc multi: release the mutex earlier 2018-02-13 13:55:02 -06:00
David Hill
dce7e3f161 multi: various cleanups 2018-02-02 14:18:41 -06:00
Donald Adu-Poku
e5828813c0 txscript: Remove OP_SMALLDATA 2017-12-29 19:57:26 +00:00
Donald Adu-Poku
29aa087e97 txscript: enforce MaxDataCarrierSize for GenerateProvablyPruneableOut 2017-12-23 01:36:12 +00:00
Donald Adu-Poku
106f979fa7 txscript: Cleanup and improve NullDataScript tests.
This modifies the recently-added NullDataScript function in several
ways in an effort to make them more consistent with the tests in the
rest of the code base and improve/correct the logic:

- Use the hexToBytes and mustParseShortForm functions
- Consistently format the test errors
- Replace the valid bool flag with an expected error and test against it
- Ensure the returned script type is the expected type in all cases
2017-12-22 00:58:54 +00:00
Dave Collins
1ca1017813
txscript: Allow external signature hash calc.
This modifies the exported CalcSignatureHash function to accept a script
as bytes instead of an array of parsed opcodes which are not available
to callers outside of the package.

While here, it also adds a proper comment for the exported function
since it is intended for more than testing as the previous comment
claimed.

Finally, it updates the tests to use a valid script instead of the
previous impossible to achieve constructed series of parsed opcodes.
2017-12-21 14:28:22 -06:00
David Hill
fc31a0b39e multi: remove unused funcs and vars 2017-12-07 21:46:25 -06:00
David Hill
b13f5dfbda travis: add ineffassign linter 2017-12-01 09:14:04 -05:00
Donald Adu-Poku
2d0d42401c txscript: Correct nulldata standardness check. 2017-12-01 01:24:17 +00:00
Josh Rickmar
238bef1c80 txscript: Require SHA256 secret hashes for atomic swaps 2017-11-28 10:03:42 -05:00