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.
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.
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.
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.
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.
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.
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.
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.
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
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.
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
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.
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.
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.
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.
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.
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
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
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
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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%
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.
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.
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.
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.
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.
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).