Add functions to count the number of signature operations in a script.
To be usd for validation. Most of the codepaths teste, a few tests missing for cases needed tests in the validation codepaths too. To be worked on in tree.
This commit is contained in:
parent
421a213a4f
commit
03696a8874
4 changed files with 274 additions and 48 deletions
110
opcode_test.go
110
opcode_test.go
|
@ -542,6 +542,8 @@ type detailedTest struct {
|
||||||
altafter [][]byte
|
altafter [][]byte
|
||||||
disassembly string
|
disassembly string
|
||||||
disassemblyerr error
|
disassemblyerr error
|
||||||
|
nSigOps int // should have same return as disassembly error
|
||||||
|
nPreciseSigOps int // should have same return as disassembly error
|
||||||
}
|
}
|
||||||
|
|
||||||
var detailedTests = []detailedTest{
|
var detailedTests = []detailedTest{
|
||||||
|
@ -2115,12 +2117,16 @@ var detailedTests = []detailedTest{
|
||||||
script: []byte{btcscript.OP_1, btcscript.OP_CHECKSIG},
|
script: []byte{btcscript.OP_1, btcscript.OP_CHECKSIG},
|
||||||
expectedReturn: btcscript.StackErrUnderflow,
|
expectedReturn: btcscript.StackErrUnderflow,
|
||||||
disassembly: "OP_1 OP_CHECKSIG",
|
disassembly: "OP_1 OP_CHECKSIG",
|
||||||
|
nSigOps: 1,
|
||||||
|
nPreciseSigOps: 1,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "OP_CHECKSIG no arg",
|
name: "OP_CHECKSIG no arg",
|
||||||
script: []byte{btcscript.OP_CHECKSIG},
|
script: []byte{btcscript.OP_CHECKSIG},
|
||||||
expectedReturn: btcscript.StackErrUnderflow,
|
expectedReturn: btcscript.StackErrUnderflow,
|
||||||
disassembly: "OP_CHECKSIG",
|
disassembly: "OP_CHECKSIG",
|
||||||
|
nSigOps: 1,
|
||||||
|
nPreciseSigOps: 1,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "OP_CHECKSIGVERIFY one arg",
|
name: "OP_CHECKSIGVERIFY one arg",
|
||||||
|
@ -2128,18 +2134,24 @@ var detailedTests = []detailedTest{
|
||||||
btcscript.OP_CHECKSIGVERIFY},
|
btcscript.OP_CHECKSIGVERIFY},
|
||||||
expectedReturn: btcscript.StackErrUnderflow,
|
expectedReturn: btcscript.StackErrUnderflow,
|
||||||
disassembly: "OP_1 OP_CHECKSIGVERIFY",
|
disassembly: "OP_1 OP_CHECKSIGVERIFY",
|
||||||
|
nSigOps: 1,
|
||||||
|
nPreciseSigOps: 1,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "OP_CHECKSIGVERIFY no arg",
|
name: "OP_CHECKSIGVERIFY no arg",
|
||||||
script: []byte{btcscript.OP_CHECKSIGVERIFY},
|
script: []byte{btcscript.OP_CHECKSIGVERIFY},
|
||||||
expectedReturn: btcscript.StackErrUnderflow,
|
expectedReturn: btcscript.StackErrUnderflow,
|
||||||
disassembly: "OP_CHECKSIGVERIFY",
|
disassembly: "OP_CHECKSIGVERIFY",
|
||||||
|
nSigOps: 1,
|
||||||
|
nPreciseSigOps: 1,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "OP_CHECK_MULTISIG no args",
|
name: "OP_CHECK_MULTISIG no args",
|
||||||
script: []byte{btcscript.OP_CHECK_MULTISIG},
|
script: []byte{btcscript.OP_CHECK_MULTISIG},
|
||||||
expectedReturn: btcscript.StackErrUnderflow,
|
expectedReturn: btcscript.StackErrUnderflow,
|
||||||
disassembly: "OP_CHECK_MULTISIG",
|
disassembly: "OP_CHECK_MULTISIG",
|
||||||
|
nSigOps: 20,
|
||||||
|
nPreciseSigOps: 20,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "OP_CHECK_MULTISIG huge number",
|
name: "OP_CHECK_MULTISIG huge number",
|
||||||
|
@ -2148,6 +2160,8 @@ var detailedTests = []detailedTest{
|
||||||
btcscript.OP_CHECK_MULTISIG},
|
btcscript.OP_CHECK_MULTISIG},
|
||||||
expectedReturn: btcscript.StackErrNumberTooBig,
|
expectedReturn: btcscript.StackErrNumberTooBig,
|
||||||
disassembly: "010203040506070809 OP_CHECK_MULTISIG",
|
disassembly: "010203040506070809 OP_CHECK_MULTISIG",
|
||||||
|
nSigOps: 20,
|
||||||
|
nPreciseSigOps: 20,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "OP_CHECK_MULTISIG too many keys",
|
name: "OP_CHECK_MULTISIG too many keys",
|
||||||
|
@ -2155,6 +2169,8 @@ var detailedTests = []detailedTest{
|
||||||
btcscript.OP_CHECK_MULTISIG},
|
btcscript.OP_CHECK_MULTISIG},
|
||||||
expectedReturn: btcscript.StackErrTooManyPubkeys,
|
expectedReturn: btcscript.StackErrTooManyPubkeys,
|
||||||
disassembly: "15 OP_CHECK_MULTISIG",
|
disassembly: "15 OP_CHECK_MULTISIG",
|
||||||
|
nSigOps: 20,
|
||||||
|
nPreciseSigOps: 20,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "OP_CHECK_MULTISIG lying about pubkeys",
|
name: "OP_CHECK_MULTISIG lying about pubkeys",
|
||||||
|
@ -2162,6 +2178,8 @@ var detailedTests = []detailedTest{
|
||||||
btcscript.OP_CHECK_MULTISIG},
|
btcscript.OP_CHECK_MULTISIG},
|
||||||
expectedReturn: btcscript.StackErrUnderflow,
|
expectedReturn: btcscript.StackErrUnderflow,
|
||||||
disassembly: "OP_1 OP_CHECK_MULTISIG",
|
disassembly: "OP_1 OP_CHECK_MULTISIG",
|
||||||
|
nSigOps: 20,
|
||||||
|
nPreciseSigOps: 1,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
// pubkey comes from blockchain
|
// pubkey comes from blockchain
|
||||||
|
@ -2180,6 +2198,8 @@ var detailedTests = []detailedTest{
|
||||||
btcscript.OP_CHECK_MULTISIG},
|
btcscript.OP_CHECK_MULTISIG},
|
||||||
expectedReturn: btcscript.StackErrUnderflow,
|
expectedReturn: btcscript.StackErrUnderflow,
|
||||||
disassembly: "04ae1a62fe09c5f51b13905f07f06b99a2f7159b2225f374cd378d71302fa28414e7aab37397f554a7df5f142c21c1b7303b8a0626f1baded5c72a704f7e6cd84c OP_1 OP_CHECK_MULTISIG",
|
disassembly: "04ae1a62fe09c5f51b13905f07f06b99a2f7159b2225f374cd378d71302fa28414e7aab37397f554a7df5f142c21c1b7303b8a0626f1baded5c72a704f7e6cd84c OP_1 OP_CHECK_MULTISIG",
|
||||||
|
nSigOps: 20,
|
||||||
|
nPreciseSigOps: 1,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
// pubkey comes from blockchain
|
// pubkey comes from blockchain
|
||||||
|
@ -2200,6 +2220,8 @@ var detailedTests = []detailedTest{
|
||||||
btcscript.OP_CHECK_MULTISIG},
|
btcscript.OP_CHECK_MULTISIG},
|
||||||
expectedReturn: btcscript.StackErrNumberTooBig,
|
expectedReturn: btcscript.StackErrNumberTooBig,
|
||||||
disassembly: "010203040506070809 04ae1a62fe09c5f51b13905f07f06b99a2f7159b2225f374cd378d71302fa28414e7aab37397f554a7df5f142c21c1b7303b8a0626f1baded5c72a704f7e6cd84c OP_1 OP_CHECK_MULTISIG",
|
disassembly: "010203040506070809 04ae1a62fe09c5f51b13905f07f06b99a2f7159b2225f374cd378d71302fa28414e7aab37397f554a7df5f142c21c1b7303b8a0626f1baded5c72a704f7e6cd84c OP_1 OP_CHECK_MULTISIG",
|
||||||
|
nSigOps: 20,
|
||||||
|
nPreciseSigOps: 1,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "OP_CHECK_MULTISIG too few sigs",
|
name: "OP_CHECK_MULTISIG too few sigs",
|
||||||
|
@ -2217,6 +2239,8 @@ var detailedTests = []detailedTest{
|
||||||
btcscript.OP_CHECK_MULTISIG},
|
btcscript.OP_CHECK_MULTISIG},
|
||||||
expectedReturn: btcscript.StackErrUnderflow,
|
expectedReturn: btcscript.StackErrUnderflow,
|
||||||
disassembly: "OP_1 04ae1a62fe09c5f51b13905f07f06b99a2f7159b2225f374cd378d71302fa28414e7aab37397f554a7df5f142c21c1b7303b8a0626f1baded5c72a704f7e6cd84c OP_1 OP_CHECK_MULTISIG",
|
disassembly: "OP_1 04ae1a62fe09c5f51b13905f07f06b99a2f7159b2225f374cd378d71302fa28414e7aab37397f554a7df5f142c21c1b7303b8a0626f1baded5c72a704f7e6cd84c OP_1 OP_CHECK_MULTISIG",
|
||||||
|
nSigOps: 20,
|
||||||
|
nPreciseSigOps: 1,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
// pubkey and sig comes from blockchain, are unrelated
|
// pubkey and sig comes from blockchain, are unrelated
|
||||||
|
@ -2245,6 +2269,8 @@ var detailedTests = []detailedTest{
|
||||||
btcscript.OP_CHECK_MULTISIG},
|
btcscript.OP_CHECK_MULTISIG},
|
||||||
after: [][]byte{{0}},
|
after: [][]byte{{0}},
|
||||||
disassembly: "OP_1 304402204e45e16932b8af514961a1d3a1a25fdf3f4f7732e9d624c6c61548ab5fb8cd410220181522ec8eca07de4860a4acdd12909d831cc56cbbac4622082221a8768d1d0901 OP_1 04ae1a62fe09c5f51b13905f07f06b99a2f7159b2225f374cd378d71302fa28414e7aab37397f554a7df5f142c21c1b7303b8a0626f1baded5c72a704f7e6cd84c OP_1 OP_CHECK_MULTISIG",
|
disassembly: "OP_1 304402204e45e16932b8af514961a1d3a1a25fdf3f4f7732e9d624c6c61548ab5fb8cd410220181522ec8eca07de4860a4acdd12909d831cc56cbbac4622082221a8768d1d0901 OP_1 04ae1a62fe09c5f51b13905f07f06b99a2f7159b2225f374cd378d71302fa28414e7aab37397f554a7df5f142c21c1b7303b8a0626f1baded5c72a704f7e6cd84c OP_1 OP_CHECK_MULTISIG",
|
||||||
|
nSigOps: 20,
|
||||||
|
nPreciseSigOps: 1,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
// invalid pubkey means that it fails to validate, not an
|
// invalid pubkey means that it fails to validate, not an
|
||||||
|
@ -2266,6 +2292,8 @@ var detailedTests = []detailedTest{
|
||||||
btcscript.OP_CHECK_MULTISIG},
|
btcscript.OP_CHECK_MULTISIG},
|
||||||
after: [][]byte{{0}},
|
after: [][]byte{{0}},
|
||||||
disassembly: "OP_1 304402204e45e16932b8af514961a1d3a1a25fdf3f4f7732e9d624c6c61548ab5fb8cd410220181522ec8eca07de4860a4acdd12909d831cc56cbbac4622082221a8768d1d0901 OP_1 OP_1 OP_1 OP_CHECK_MULTISIG",
|
disassembly: "OP_1 304402204e45e16932b8af514961a1d3a1a25fdf3f4f7732e9d624c6c61548ab5fb8cd410220181522ec8eca07de4860a4acdd12909d831cc56cbbac4622082221a8768d1d0901 OP_1 OP_1 OP_1 OP_CHECK_MULTISIG",
|
||||||
|
nSigOps: 20,
|
||||||
|
nPreciseSigOps: 1,
|
||||||
},
|
},
|
||||||
// XXX(oga) Test multisig when extra arg is missing. needs valid sig.
|
// XXX(oga) Test multisig when extra arg is missing. needs valid sig.
|
||||||
// disabled opcodes
|
// disabled opcodes
|
||||||
|
@ -2274,6 +2302,8 @@ var detailedTests = []detailedTest{
|
||||||
script: []byte{btcscript.OP_CHECKMULTISIGVERIFY},
|
script: []byte{btcscript.OP_CHECKMULTISIGVERIFY},
|
||||||
expectedReturn: btcscript.StackErrUnderflow,
|
expectedReturn: btcscript.StackErrUnderflow,
|
||||||
disassembly: "OP_CHECKMULTISIGVERIFY",
|
disassembly: "OP_CHECKMULTISIGVERIFY",
|
||||||
|
nSigOps: 20,
|
||||||
|
nPreciseSigOps: 20,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "OP_CHECKMULTISIGVERIFY huge number",
|
name: "OP_CHECKMULTISIGVERIFY huge number",
|
||||||
|
@ -2282,6 +2312,8 @@ var detailedTests = []detailedTest{
|
||||||
btcscript.OP_CHECKMULTISIGVERIFY},
|
btcscript.OP_CHECKMULTISIGVERIFY},
|
||||||
expectedReturn: btcscript.StackErrNumberTooBig,
|
expectedReturn: btcscript.StackErrNumberTooBig,
|
||||||
disassembly: "010203040506070809 OP_CHECKMULTISIGVERIFY",
|
disassembly: "010203040506070809 OP_CHECKMULTISIGVERIFY",
|
||||||
|
nSigOps: 20,
|
||||||
|
nPreciseSigOps: 20,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "OP_CHECKMULTISIGVERIFY too many keys",
|
name: "OP_CHECKMULTISIGVERIFY too many keys",
|
||||||
|
@ -2289,6 +2321,8 @@ var detailedTests = []detailedTest{
|
||||||
btcscript.OP_CHECKMULTISIGVERIFY},
|
btcscript.OP_CHECKMULTISIGVERIFY},
|
||||||
expectedReturn: btcscript.StackErrTooManyPubkeys,
|
expectedReturn: btcscript.StackErrTooManyPubkeys,
|
||||||
disassembly: "15 OP_CHECKMULTISIGVERIFY",
|
disassembly: "15 OP_CHECKMULTISIGVERIFY",
|
||||||
|
nSigOps: 20,
|
||||||
|
nPreciseSigOps: 20,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "OP_CHECKMULTISIGVERIFY lying about pubkeys",
|
name: "OP_CHECKMULTISIGVERIFY lying about pubkeys",
|
||||||
|
@ -2296,6 +2330,8 @@ var detailedTests = []detailedTest{
|
||||||
btcscript.OP_CHECKMULTISIGVERIFY},
|
btcscript.OP_CHECKMULTISIGVERIFY},
|
||||||
expectedReturn: btcscript.StackErrUnderflow,
|
expectedReturn: btcscript.StackErrUnderflow,
|
||||||
disassembly: "OP_1 OP_CHECKMULTISIGVERIFY",
|
disassembly: "OP_1 OP_CHECKMULTISIGVERIFY",
|
||||||
|
nSigOps: 20,
|
||||||
|
nPreciseSigOps: 1,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
// pubkey comes from blockchain
|
// pubkey comes from blockchain
|
||||||
|
@ -2314,6 +2350,8 @@ var detailedTests = []detailedTest{
|
||||||
btcscript.OP_CHECKMULTISIGVERIFY},
|
btcscript.OP_CHECKMULTISIGVERIFY},
|
||||||
expectedReturn: btcscript.StackErrUnderflow,
|
expectedReturn: btcscript.StackErrUnderflow,
|
||||||
disassembly: "04ae1a62fe09c5f51b13905f07f06b99a2f7159b2225f374cd378d71302fa28414e7aab37397f554a7df5f142c21c1b7303b8a0626f1baded5c72a704f7e6cd84c OP_1 OP_CHECKMULTISIGVERIFY",
|
disassembly: "04ae1a62fe09c5f51b13905f07f06b99a2f7159b2225f374cd378d71302fa28414e7aab37397f554a7df5f142c21c1b7303b8a0626f1baded5c72a704f7e6cd84c OP_1 OP_CHECKMULTISIGVERIFY",
|
||||||
|
nSigOps: 20,
|
||||||
|
nPreciseSigOps: 1,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "OP_CHECKMULTISIGVERIFY sigs huge no",
|
name: "OP_CHECKMULTISIGVERIFY sigs huge no",
|
||||||
|
@ -2333,6 +2371,8 @@ var detailedTests = []detailedTest{
|
||||||
btcscript.OP_CHECKMULTISIGVERIFY},
|
btcscript.OP_CHECKMULTISIGVERIFY},
|
||||||
expectedReturn: btcscript.StackErrNumberTooBig,
|
expectedReturn: btcscript.StackErrNumberTooBig,
|
||||||
disassembly: "010203040506070809 04ae1a62fe09c5f51b13905f07f06b99a2f7159b2225f374cd378d71302fa28414e7aab37397f554a7df5f142c21c1b7303b8a0626f1baded5c72a704f7e6cd84c OP_1 OP_CHECKMULTISIGVERIFY",
|
disassembly: "010203040506070809 04ae1a62fe09c5f51b13905f07f06b99a2f7159b2225f374cd378d71302fa28414e7aab37397f554a7df5f142c21c1b7303b8a0626f1baded5c72a704f7e6cd84c OP_1 OP_CHECKMULTISIGVERIFY",
|
||||||
|
nSigOps: 20,
|
||||||
|
nPreciseSigOps: 1,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "OP_CHECKMULTISIGVERIFY too few sigs",
|
name: "OP_CHECKMULTISIGVERIFY too few sigs",
|
||||||
|
@ -2350,6 +2390,8 @@ var detailedTests = []detailedTest{
|
||||||
btcscript.OP_CHECKMULTISIGVERIFY},
|
btcscript.OP_CHECKMULTISIGVERIFY},
|
||||||
expectedReturn: btcscript.StackErrUnderflow,
|
expectedReturn: btcscript.StackErrUnderflow,
|
||||||
disassembly: "OP_1 04ae1a62fe09c5f51b13905f07f06b99a2f7159b2225f374cd378d71302fa28414e7aab37397f554a7df5f142c21c1b7303b8a0626f1baded5c72a704f7e6cd84c OP_1 OP_CHECKMULTISIGVERIFY",
|
disassembly: "OP_1 04ae1a62fe09c5f51b13905f07f06b99a2f7159b2225f374cd378d71302fa28414e7aab37397f554a7df5f142c21c1b7303b8a0626f1baded5c72a704f7e6cd84c OP_1 OP_CHECKMULTISIGVERIFY",
|
||||||
|
nSigOps: 20,
|
||||||
|
nPreciseSigOps: 1,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
// pubkey and sig comes from blockchain, are unrelated
|
// pubkey and sig comes from blockchain, are unrelated
|
||||||
|
@ -2378,6 +2420,8 @@ var detailedTests = []detailedTest{
|
||||||
btcscript.OP_CHECKMULTISIGVERIFY},
|
btcscript.OP_CHECKMULTISIGVERIFY},
|
||||||
expectedReturn: btcscript.StackErrVerifyFailed,
|
expectedReturn: btcscript.StackErrVerifyFailed,
|
||||||
disassembly: "OP_1 304402204e45e16932b8af514961a1d3a1a25fdf3f4f7732e9d624c6c61548ab5fb8cd410220181522ec8eca07de4860a4acdd12909d831cc56cbbac4622082221a8768d1d0901 OP_1 04ae1a62fe09c5f51b13905f07f06b99a2f7159b2225f374cd378d71302fa28414e7aab37397f554a7df5f142c21c1b7303b8a0626f1baded5c72a704f7e6cd84c OP_1 OP_CHECKMULTISIGVERIFY",
|
disassembly: "OP_1 304402204e45e16932b8af514961a1d3a1a25fdf3f4f7732e9d624c6c61548ab5fb8cd410220181522ec8eca07de4860a4acdd12909d831cc56cbbac4622082221a8768d1d0901 OP_1 04ae1a62fe09c5f51b13905f07f06b99a2f7159b2225f374cd378d71302fa28414e7aab37397f554a7df5f142c21c1b7303b8a0626f1baded5c72a704f7e6cd84c OP_1 OP_CHECKMULTISIGVERIFY",
|
||||||
|
nSigOps: 20,
|
||||||
|
nPreciseSigOps: 1,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
// invalid pubkey means that it fails to validate, not an
|
// invalid pubkey means that it fails to validate, not an
|
||||||
|
@ -2399,6 +2443,8 @@ var detailedTests = []detailedTest{
|
||||||
btcscript.OP_CHECKMULTISIGVERIFY},
|
btcscript.OP_CHECKMULTISIGVERIFY},
|
||||||
expectedReturn: btcscript.StackErrVerifyFailed,
|
expectedReturn: btcscript.StackErrVerifyFailed,
|
||||||
disassembly: "OP_1 304402204e45e16932b8af514961a1d3a1a25fdf3f4f7732e9d624c6c61548ab5fb8cd410220181522ec8eca07de4860a4acdd12909d831cc56cbbac4622082221a8768d1d0901 OP_1 OP_1 OP_1 OP_CHECKMULTISIGVERIFY",
|
disassembly: "OP_1 304402204e45e16932b8af514961a1d3a1a25fdf3f4f7732e9d624c6c61548ab5fb8cd410220181522ec8eca07de4860a4acdd12909d831cc56cbbac4622082221a8768d1d0901 OP_1 OP_1 OP_1 OP_CHECKMULTISIGVERIFY",
|
||||||
|
nSigOps: 20,
|
||||||
|
nPreciseSigOps: 1,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
// 201 operations + one push, should just fit limits
|
// 201 operations + one push, should just fit limits
|
||||||
|
@ -3032,6 +3078,8 @@ var detailedTests = []detailedTest{
|
||||||
},
|
},
|
||||||
expectedReturn: btcscript.StackErrTooManyOperations,
|
expectedReturn: btcscript.StackErrTooManyOperations,
|
||||||
disassembly: "OP_1 OP_DUP OP_DROP OP_DUP OP_DROP OP_DUP OP_DROP OP_DUP OP_DROP OP_DUP OP_DROP OP_DUP OP_DROP OP_DUP OP_DROP OP_DUP OP_DROP OP_DUP OP_DROP OP_DUP OP_DROP OP_DUP OP_DROP OP_DUP OP_DROP OP_DUP OP_DROP OP_DUP OP_DROP OP_DUP OP_DROP OP_DUP OP_DROP OP_DUP OP_DROP OP_DUP OP_DROP OP_DUP OP_DROP OP_DUP OP_DROP OP_DUP OP_DROP OP_DUP OP_DROP OP_DUP OP_DROP OP_DUP OP_DROP OP_DUP OP_DROP OP_DUP OP_DROP OP_DUP OP_DROP OP_DUP OP_DROP OP_DUP OP_DROP OP_DUP OP_DROP OP_DUP OP_DROP OP_DUP OP_DROP OP_DUP OP_DROP OP_DUP OP_DROP OP_DUP OP_DROP OP_DUP OP_DROP OP_DUP OP_DROP OP_DUP OP_DROP OP_DUP OP_DROP OP_DUP OP_DROP OP_DUP OP_DROP OP_DUP OP_DROP OP_DUP OP_DROP OP_DUP OP_DROP OP_DUP OP_DROP OP_DUP OP_DROP OP_DUP OP_DROP OP_DUP OP_DROP OP_DUP OP_DROP OP_DUP OP_DROP OP_DUP OP_DROP OP_DUP OP_DROP OP_DUP OP_DROP OP_DUP OP_DROP OP_DUP OP_DROP OP_DUP OP_DROP OP_DUP OP_DROP OP_DUP OP_DROP OP_DUP OP_DROP OP_DUP OP_DROP OP_DUP OP_DROP OP_DUP OP_DROP OP_DUP OP_DROP OP_DUP OP_DROP OP_DUP OP_DROP OP_DUP OP_DROP OP_DUP OP_DROP OP_DUP OP_DROP OP_DUP OP_DROP OP_DUP OP_DROP OP_DUP OP_DROP OP_DUP OP_DROP OP_DUP OP_DROP OP_DUP OP_DROP OP_DUP OP_DROP OP_DUP OP_DROP OP_DUP OP_DROP OP_DUP OP_DROP OP_DUP OP_DROP OP_DUP OP_DROP OP_DUP OP_DROP OP_DUP OP_DROP OP_DUP OP_DROP OP_DUP OP_DROP OP_DUP OP_DROP OP_DUP OP_DROP OP_DUP OP_DROP OP_DUP OP_DROP OP_DUP OP_DROP OP_DUP OP_DROP OP_DUP OP_DROP OP_DUP OP_DROP OP_DUP OP_DROP OP_DUP OP_DROP OP_DUP OP_DROP OP_DUP OP_DROP OP_DUP OP_DROP OP_DUP OP_DROP OP_DUP OP_DROP OP_DUP OP_DROP OP_1 OP_1 OP_1 OP_1 OP_2 OP_CHECK_MULTISIG",
|
disassembly: "OP_1 OP_DUP OP_DROP OP_DUP OP_DROP OP_DUP OP_DROP OP_DUP OP_DROP OP_DUP OP_DROP OP_DUP OP_DROP OP_DUP OP_DROP OP_DUP OP_DROP OP_DUP OP_DROP OP_DUP OP_DROP OP_DUP OP_DROP OP_DUP OP_DROP OP_DUP OP_DROP OP_DUP OP_DROP OP_DUP OP_DROP OP_DUP OP_DROP OP_DUP OP_DROP OP_DUP OP_DROP OP_DUP OP_DROP OP_DUP OP_DROP OP_DUP OP_DROP OP_DUP OP_DROP OP_DUP OP_DROP OP_DUP OP_DROP OP_DUP OP_DROP OP_DUP OP_DROP OP_DUP OP_DROP OP_DUP OP_DROP OP_DUP OP_DROP OP_DUP OP_DROP OP_DUP OP_DROP OP_DUP OP_DROP OP_DUP OP_DROP OP_DUP OP_DROP OP_DUP OP_DROP OP_DUP OP_DROP OP_DUP OP_DROP OP_DUP OP_DROP OP_DUP OP_DROP OP_DUP OP_DROP OP_DUP OP_DROP OP_DUP OP_DROP OP_DUP OP_DROP OP_DUP OP_DROP OP_DUP OP_DROP OP_DUP OP_DROP OP_DUP OP_DROP OP_DUP OP_DROP OP_DUP OP_DROP OP_DUP OP_DROP OP_DUP OP_DROP OP_DUP OP_DROP OP_DUP OP_DROP OP_DUP OP_DROP OP_DUP OP_DROP OP_DUP OP_DROP OP_DUP OP_DROP OP_DUP OP_DROP OP_DUP OP_DROP OP_DUP OP_DROP OP_DUP OP_DROP OP_DUP OP_DROP OP_DUP OP_DROP OP_DUP OP_DROP OP_DUP OP_DROP OP_DUP OP_DROP OP_DUP OP_DROP OP_DUP OP_DROP OP_DUP OP_DROP OP_DUP OP_DROP OP_DUP OP_DROP OP_DUP OP_DROP OP_DUP OP_DROP OP_DUP OP_DROP OP_DUP OP_DROP OP_DUP OP_DROP OP_DUP OP_DROP OP_DUP OP_DROP OP_DUP OP_DROP OP_DUP OP_DROP OP_DUP OP_DROP OP_DUP OP_DROP OP_DUP OP_DROP OP_DUP OP_DROP OP_DUP OP_DROP OP_DUP OP_DROP OP_DUP OP_DROP OP_DUP OP_DROP OP_DUP OP_DROP OP_DUP OP_DROP OP_DUP OP_DROP OP_DUP OP_DROP OP_DUP OP_DROP OP_DUP OP_DROP OP_DUP OP_DROP OP_DUP OP_DROP OP_DUP OP_DROP OP_DUP OP_DROP OP_DUP OP_DROP OP_DUP OP_DROP OP_1 OP_1 OP_1 OP_1 OP_2 OP_CHECK_MULTISIG",
|
||||||
|
nSigOps: 20,
|
||||||
|
nPreciseSigOps: 2,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "OP_CAT disabled",
|
name: "OP_CAT disabled",
|
||||||
|
@ -3735,3 +3783,65 @@ func TestDisasmStrings(t *testing.T) {
|
||||||
testDisasmString(t, &detailedTests[i])
|
testDisasmString(t, &detailedTests[i])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// A basic test of GetSigOpCount for most opcodes, we do this by
|
||||||
|
// running the same test for every one of the detailed tests. Since
|
||||||
|
// disassembly errors are always parse errors, and so are
|
||||||
|
// sigops count errors we use the same error code.
|
||||||
|
// While this isn't as precise as using full transaction scripts, this gives
|
||||||
|
// us coverage over a wider range of opcodes.
|
||||||
|
func TestSigOps(t *testing.T) {
|
||||||
|
for _, test := range detailedTests {
|
||||||
|
count, err := btcscript.GetSigOpCount(test.script)
|
||||||
|
if err != nil {
|
||||||
|
if err != test.disassemblyerr {
|
||||||
|
t.Errorf("%s: unexpected error. exp \"%v\""+
|
||||||
|
"got \"%v\"", test.name,
|
||||||
|
test.disassemblyerr, err)
|
||||||
|
}
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if test.disassemblyerr != nil {
|
||||||
|
t.Errorf("%s: no error when expected \"%v\"",
|
||||||
|
test.name, test.disassemblyerr)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if count != test.nSigOps {
|
||||||
|
t.Errorf("%s: expected count of %d, got %d", test.name,
|
||||||
|
test.nSigOps, count)
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// A basic test of GetPreciseSigOpCount for most opcodes, we do this by
|
||||||
|
// running the same test for every one of the detailed tests with a fake
|
||||||
|
// sigscript. Sicne disassembly errors are always parse errors, and so are
|
||||||
|
// sigops count errors we use the same error code.
|
||||||
|
// While this isn't as precise as using full transaction scripts, this gives
|
||||||
|
// us coverage over a wider range of opcodes. See script_test.go for tests
|
||||||
|
// using real transactions to provide a bit more coverage.
|
||||||
|
func TestPreciseSigOps(t *testing.T) {
|
||||||
|
for _, test := range detailedTests {
|
||||||
|
count, err := btcscript.GetPreciseSigOpCount(
|
||||||
|
[]byte{btcscript.OP_1}, test.script, false)
|
||||||
|
if err != nil {
|
||||||
|
if err != test.disassemblyerr {
|
||||||
|
t.Errorf("%s: unexpected error. exp \"%v\""+
|
||||||
|
"got \"%v\"", test.name,
|
||||||
|
test.disassemblyerr, err)
|
||||||
|
}
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if test.disassemblyerr != nil {
|
||||||
|
t.Errorf("%s: no error when expected \"%v\"",
|
||||||
|
test.name, test.disassemblyerr)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if count != test.nPreciseSigOps {
|
||||||
|
t.Errorf("%s: expected count of %d, got %d", test.name,
|
||||||
|
test.nPreciseSigOps, count)
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
84
script.go
84
script.go
|
@ -715,3 +715,87 @@ func (s *Script) GetAltStack() [][]byte {
|
||||||
func (s *Script) SetAltStack(data [][]byte) {
|
func (s *Script) SetAltStack(data [][]byte) {
|
||||||
setStack(&s.astack, data)
|
setStack(&s.astack, data)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GetSigOpCount provides a quick count of the number of signature operations
|
||||||
|
// in a script. a CHECKSIG operations counts for 1, and a CHECK_MULTISIG for 20.
|
||||||
|
func GetSigOpCount(script [] byte) (int, error) {
|
||||||
|
pops, err := parseScript(script)
|
||||||
|
if err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return getSigOpCount(pops, false), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetPreciseSigOpCount returns the number of signature operations in
|
||||||
|
// scriptPubKey. If bip16 is true then scriptSig may be searched for the
|
||||||
|
// Pay-To-Script-Hash script in order to find the precise number of signature
|
||||||
|
// operations in the transaction.
|
||||||
|
func GetPreciseSigOpCount(scriptSig, scriptPubKey []byte, bip16 bool) (int, error) {
|
||||||
|
pops, err := parseScript(scriptPubKey)
|
||||||
|
if err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
// non P2SH transactions just treated as normal.
|
||||||
|
if !(bip16 && isScriptHash(pops)) {
|
||||||
|
return getSigOpCount(pops, true), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ok so this is P2SH, get the contained script and count it..
|
||||||
|
|
||||||
|
sigPops, err := parseScript(scriptSig)
|
||||||
|
if err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
if !isPushOnly(sigPops) || len(sigPops) == 0 {
|
||||||
|
return 0, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
shScript := sigPops[len(sigPops) - 1].data
|
||||||
|
// Means that sigPops is jus OP_1 - OP_16, no sigops there.
|
||||||
|
if shScript == nil {
|
||||||
|
return 0, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
shPops, err := parseScript(shScript)
|
||||||
|
if err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return getSigOpCount(shPops, true), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// getSigOpCount is the implementation function for counting the number of
|
||||||
|
// signature operations in the script provided by pops. If precise mode is
|
||||||
|
// requested then we attempt to count the number of operations for a multisig
|
||||||
|
// op. Otherwise we use the maximum.
|
||||||
|
func getSigOpCount(pops []parsedOpcode, precise bool) int {
|
||||||
|
nSigs := 0
|
||||||
|
for i, pop := range pops {
|
||||||
|
switch pop.opcode.value {
|
||||||
|
case OP_CHECKSIG:
|
||||||
|
fallthrough;
|
||||||
|
case OP_CHECKSIGVERIFY:
|
||||||
|
nSigs++
|
||||||
|
case OP_CHECK_MULTISIG:
|
||||||
|
fallthrough;
|
||||||
|
case OP_CHECKMULTISIGVERIFY:
|
||||||
|
// If we are being precise then look for familiar
|
||||||
|
// patterns for multisig, for now all we recognise is
|
||||||
|
// OP_1 - OP_16 to signify the number of pubkeys.
|
||||||
|
// Otherwise, we use the max of 20.
|
||||||
|
if precise && i > 0 &&
|
||||||
|
pops[i - 1].opcode.value >= OP_1 &&
|
||||||
|
pops[i - 1].opcode.value <= OP_16 {
|
||||||
|
nSigs += int(pops[i-1].opcode.value -
|
||||||
|
(OP_1 - 1))
|
||||||
|
} else {
|
||||||
|
nSigs += MaxPubKeysPerMultiSig
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
// not a sigop.
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nSigs
|
||||||
|
}
|
||||||
|
|
|
@ -19,6 +19,7 @@ type txTest struct {
|
||||||
bip16 bool
|
bip16 bool
|
||||||
err error
|
err error
|
||||||
shouldFail bool
|
shouldFail bool
|
||||||
|
nSigOps int
|
||||||
}
|
}
|
||||||
|
|
||||||
var txTests = []txTest{
|
var txTests = []txTest{
|
||||||
|
@ -121,6 +122,7 @@ var txTests = []txTest{
|
||||||
0x12, 0xa3, btcscript.OP_CHECKSIG,
|
0x12, 0xa3, btcscript.OP_CHECKSIG,
|
||||||
},
|
},
|
||||||
idx: 0,
|
idx: 0,
|
||||||
|
nSigOps: 1,
|
||||||
},
|
},
|
||||||
// Previous test with the value of one output changed.
|
// Previous test with the value of one output changed.
|
||||||
txTest{
|
txTest{
|
||||||
|
@ -221,6 +223,7 @@ var txTests = []txTest{
|
||||||
},
|
},
|
||||||
idx: 0,
|
idx: 0,
|
||||||
err: btcscript.StackErrScriptFailed,
|
err: btcscript.StackErrScriptFailed,
|
||||||
|
nSigOps: 1,
|
||||||
},
|
},
|
||||||
txTest{
|
txTest{
|
||||||
name: "CheckSig invalid signature",
|
name: "CheckSig invalid signature",
|
||||||
|
@ -322,6 +325,7 @@ var txTests = []txTest{
|
||||||
},
|
},
|
||||||
idx: 0,
|
idx: 0,
|
||||||
shouldFail: true,
|
shouldFail: true,
|
||||||
|
nSigOps: 1,
|
||||||
},
|
},
|
||||||
txTest{
|
txTest{
|
||||||
name: "CheckSig invalid pubkey",
|
name: "CheckSig invalid pubkey",
|
||||||
|
@ -422,6 +426,7 @@ var txTests = []txTest{
|
||||||
},
|
},
|
||||||
idx: 0,
|
idx: 0,
|
||||||
shouldFail: true,
|
shouldFail: true,
|
||||||
|
nSigOps: 1,
|
||||||
},
|
},
|
||||||
// tx 599e47a8114fe098103663029548811d2651991b62397e057f0c863c2bc9f9ea
|
// tx 599e47a8114fe098103663029548811d2651991b62397e057f0c863c2bc9f9ea
|
||||||
// uses checksig with SigHashNone.
|
// uses checksig with SigHashNone.
|
||||||
|
@ -523,6 +528,7 @@ var txTests = []txTest{
|
||||||
},
|
},
|
||||||
idx: 0,
|
idx: 0,
|
||||||
bip16: true, // after threshold
|
bip16: true, // after threshold
|
||||||
|
nSigOps: 1,
|
||||||
},
|
},
|
||||||
// tx 51bf528ecf3c161e7c021224197dbe84f9a8564212f6207baa014c01a1668e1e
|
// tx 51bf528ecf3c161e7c021224197dbe84f9a8564212f6207baa014c01a1668e1e
|
||||||
// first instance of an AnyoneCanPay signature in the blockchain
|
// first instance of an AnyoneCanPay signature in the blockchain
|
||||||
|
@ -646,6 +652,7 @@ var txTests = []txTest{
|
||||||
},
|
},
|
||||||
idx: 0,
|
idx: 0,
|
||||||
bip16: true, // after threshold
|
bip16: true, // after threshold
|
||||||
|
nSigOps: 1,
|
||||||
},
|
},
|
||||||
// tx 6d36bc17e947ce00bb6f12f8e7a56a1585c5a36188ffa2b05e10b4743273a74b
|
// tx 6d36bc17e947ce00bb6f12f8e7a56a1585c5a36188ffa2b05e10b4743273a74b
|
||||||
// Uses OP_CODESEPARATOR and OP_CHECKMULTISIG
|
// Uses OP_CODESEPARATOR and OP_CHECKMULTISIG
|
||||||
|
@ -768,6 +775,7 @@ var txTests = []txTest{
|
||||||
},
|
},
|
||||||
idx: 1,
|
idx: 1,
|
||||||
bip16: false,
|
bip16: false,
|
||||||
|
nSigOps: 0, // multisig is in the pkScript!
|
||||||
},
|
},
|
||||||
// same as previous but with one byte changed to make signature fail
|
// same as previous but with one byte changed to make signature fail
|
||||||
txTest{
|
txTest{
|
||||||
|
@ -890,6 +898,7 @@ var txTests = []txTest{
|
||||||
idx: 1,
|
idx: 1,
|
||||||
bip16: false,
|
bip16: false,
|
||||||
err: btcscript.StackErrScriptFailed,
|
err: btcscript.StackErrScriptFailed,
|
||||||
|
nSigOps: 0, // multisig is in the pkScript!
|
||||||
},
|
},
|
||||||
// tx e5779b9e78f9650debc2893fd9636d827b26b4ddfa6a8172fe8708c924f5c39d
|
// tx e5779b9e78f9650debc2893fd9636d827b26b4ddfa6a8172fe8708c924f5c39d
|
||||||
// First P2SH transaction in the blockchain
|
// First P2SH transaction in the blockchain
|
||||||
|
@ -948,6 +957,7 @@ var txTests = []txTest{
|
||||||
},
|
},
|
||||||
idx: 0,
|
idx: 0,
|
||||||
bip16: true,
|
bip16: true,
|
||||||
|
nSigOps: 0, // no signature ops in the pushed script.
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -990,6 +1000,25 @@ func TestTX(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestGetPreciseSignOps(t *testing.T) {
|
||||||
|
for _, test := range txTests {
|
||||||
|
count, err := btcscript.GetPreciseSigOpCount(
|
||||||
|
test.tx.TxIn[test.idx].SignatureScript, test.pkScript,
|
||||||
|
test.bip16)
|
||||||
|
// all tx currently parse
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("%s: unexpected error. got \"%v\"",
|
||||||
|
test.name, err)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if count != test.nSigOps {
|
||||||
|
t.Errorf("%s: expected count of %d, got %d", test.name,
|
||||||
|
test.nSigOps, count)
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
type removeOpcodeTest struct {
|
type removeOpcodeTest struct {
|
||||||
name string
|
name string
|
||||||
before []byte
|
before []byte
|
||||||
|
|
|
@ -2,56 +2,57 @@
|
||||||
github.com/conformal/btcscript/stack.go asInt 100.00% (18/18)
|
github.com/conformal/btcscript/stack.go asInt 100.00% (18/18)
|
||||||
github.com/conformal/btcscript/stack.go fromInt 100.00% (14/14)
|
github.com/conformal/btcscript/stack.go fromInt 100.00% (14/14)
|
||||||
github.com/conformal/btcscript/opcode.go opcodeWithin 100.00% (13/13)
|
github.com/conformal/btcscript/opcode.go opcodeWithin 100.00% (13/13)
|
||||||
github.com/conformal/btcscript/opcode.go parsedOpcode.bytes 100.00% (12/12)
|
|
||||||
github.com/conformal/btcscript/stack.go Stack.nipN 100.00% (12/12)
|
|
||||||
github.com/conformal/btcscript/opcode.go parsedOpcode.print 100.00% (12/12)
|
github.com/conformal/btcscript/opcode.go parsedOpcode.print 100.00% (12/12)
|
||||||
|
github.com/conformal/btcscript/stack.go Stack.nipN 100.00% (12/12)
|
||||||
|
github.com/conformal/btcscript/opcode.go parsedOpcode.bytes 100.00% (12/12)
|
||||||
github.com/conformal/btcscript/opcode.go opcodeIf 100.00% (11/11)
|
github.com/conformal/btcscript/opcode.go opcodeIf 100.00% (11/11)
|
||||||
github.com/conformal/btcscript/opcode.go opcodeNotIf 100.00% (11/11)
|
github.com/conformal/btcscript/opcode.go opcodeNotIf 100.00% (11/11)
|
||||||
|
github.com/conformal/btcscript/stack.go Stack.Tuck 100.00% (10/10)
|
||||||
|
github.com/conformal/btcscript/script.go getSigOpCount 100.00% (10/10)
|
||||||
|
github.com/conformal/btcscript/opcode.go opcodeMax 100.00% (10/10)
|
||||||
|
github.com/conformal/btcscript/opcode.go opcodeMin 100.00% (10/10)
|
||||||
|
github.com/conformal/btcscript/opcode.go opcodeGreaterThanOrEqual 100.00% (10/10)
|
||||||
github.com/conformal/btcscript/opcode.go opcodeLessThanOrEqual 100.00% (10/10)
|
github.com/conformal/btcscript/opcode.go opcodeLessThanOrEqual 100.00% (10/10)
|
||||||
github.com/conformal/btcscript/opcode.go opcodeGreaterThan 100.00% (10/10)
|
github.com/conformal/btcscript/opcode.go opcodeGreaterThan 100.00% (10/10)
|
||||||
github.com/conformal/btcscript/opcode.go opcodeLessThan 100.00% (10/10)
|
github.com/conformal/btcscript/opcode.go opcodeLessThan 100.00% (10/10)
|
||||||
github.com/conformal/btcscript/opcode.go opcodeNumNotEqual 100.00% (10/10)
|
github.com/conformal/btcscript/opcode.go opcodeNumNotEqual 100.00% (10/10)
|
||||||
|
github.com/conformal/btcscript/opcode.go opcodeNumEqual 100.00% (10/10)
|
||||||
github.com/conformal/btcscript/opcode.go opcodeBoolOr 100.00% (10/10)
|
github.com/conformal/btcscript/opcode.go opcodeBoolOr 100.00% (10/10)
|
||||||
github.com/conformal/btcscript/opcode.go opcodeBoolAnd 100.00% (10/10)
|
github.com/conformal/btcscript/opcode.go opcodeBoolAnd 100.00% (10/10)
|
||||||
github.com/conformal/btcscript/opcode.go opcodeNumEqual 100.00% (10/10)
|
|
||||||
github.com/conformal/btcscript/opcode.go opcodeMax 100.00% (10/10)
|
|
||||||
github.com/conformal/btcscript/stack.go Stack.Tuck 100.00% (10/10)
|
|
||||||
github.com/conformal/btcscript/opcode.go opcodeMin 100.00% (10/10)
|
|
||||||
github.com/conformal/btcscript/opcode.go opcodeGreaterThanOrEqual 100.00% (10/10)
|
|
||||||
github.com/conformal/btcscript/stack.go Stack.RotN 100.00% (9/9)
|
github.com/conformal/btcscript/stack.go Stack.RotN 100.00% (9/9)
|
||||||
github.com/conformal/btcscript/script.go DisasmString 100.00% (9/9)
|
|
||||||
github.com/conformal/btcscript/stack.go Stack.SwapN 100.00% (9/9)
|
github.com/conformal/btcscript/stack.go Stack.SwapN 100.00% (9/9)
|
||||||
github.com/conformal/btcscript/stack.go Stack.OverN 100.00% (9/9)
|
github.com/conformal/btcscript/stack.go Stack.OverN 100.00% (9/9)
|
||||||
github.com/conformal/btcscript/opcode.go opcodeEqual 100.00% (8/8)
|
github.com/conformal/btcscript/script.go DisasmString 100.00% (9/9)
|
||||||
github.com/conformal/btcscript/opcode.go opcodeAdd 100.00% (8/8)
|
github.com/conformal/btcscript/opcode.go opcodeAdd 100.00% (8/8)
|
||||||
github.com/conformal/btcscript/opcode.go opcodeSub 100.00% (8/8)
|
github.com/conformal/btcscript/opcode.go opcodeSub 100.00% (8/8)
|
||||||
|
github.com/conformal/btcscript/opcode.go opcodeEqual 100.00% (8/8)
|
||||||
github.com/conformal/btcscript/stack.go Stack.DupN 100.00% (8/8)
|
github.com/conformal/btcscript/stack.go Stack.DupN 100.00% (8/8)
|
||||||
github.com/conformal/btcscript/opcode.go opcodePick 100.00% (7/7)
|
|
||||||
github.com/conformal/btcscript/opcode.go opcodeNot 100.00% (7/7)
|
|
||||||
github.com/conformal/btcscript/stack.go Stack.DropN 100.00% (7/7)
|
github.com/conformal/btcscript/stack.go Stack.DropN 100.00% (7/7)
|
||||||
github.com/conformal/btcscript/opcode.go opcode0NotEqual 100.00% (7/7)
|
github.com/conformal/btcscript/opcode.go opcode0NotEqual 100.00% (7/7)
|
||||||
github.com/conformal/btcscript/opcode.go opcodeRoll 100.00% (7/7)
|
github.com/conformal/btcscript/opcode.go opcodeRoll 100.00% (7/7)
|
||||||
github.com/conformal/btcscript/opcode.go opcodeElse 100.00% (6/6)
|
github.com/conformal/btcscript/opcode.go opcodePick 100.00% (7/7)
|
||||||
github.com/conformal/btcscript/opcode.go opcodeIfDup 100.00% (6/6)
|
github.com/conformal/btcscript/opcode.go opcodeNot 100.00% (7/7)
|
||||||
github.com/conformal/btcscript/opcode.go parsedOpcode.conditional 100.00% (6/6)
|
|
||||||
github.com/conformal/btcscript/opcode.go opcodeVerify 100.00% (6/6)
|
github.com/conformal/btcscript/opcode.go opcodeVerify 100.00% (6/6)
|
||||||
|
github.com/conformal/btcscript/opcode.go opcodeIfDup 100.00% (6/6)
|
||||||
|
github.com/conformal/btcscript/opcode.go opcodeElse 100.00% (6/6)
|
||||||
|
github.com/conformal/btcscript/opcode.go parsedOpcode.conditional 100.00% (6/6)
|
||||||
github.com/conformal/btcscript/opcode.go opcodeHash256 100.00% (5/5)
|
github.com/conformal/btcscript/opcode.go opcodeHash256 100.00% (5/5)
|
||||||
github.com/conformal/btcscript/script.go removeOpcode 100.00% (5/5)
|
github.com/conformal/btcscript/script.go removeOpcode 100.00% (5/5)
|
||||||
github.com/conformal/btcscript/script.go removeOpcodeByData 100.00% (5/5)
|
github.com/conformal/btcscript/script.go Script.validPC 100.00% (5/5)
|
||||||
github.com/conformal/btcscript/stack.go Stack.PickN 100.00% (5/5)
|
github.com/conformal/btcscript/opcode.go opcodeNegate 100.00% (5/5)
|
||||||
github.com/conformal/btcscript/opcode.go parsedOpcode.exec 100.00% (5/5)
|
github.com/conformal/btcscript/opcode.go opcodeHash160 100.00% (5/5)
|
||||||
github.com/conformal/btcscript/stack.go Stack.RollN 100.00% (5/5)
|
|
||||||
github.com/conformal/btcscript/opcode.go opcodeToAltStack 100.00% (5/5)
|
|
||||||
github.com/conformal/btcscript/opcode.go opcodeFromAltStack 100.00% (5/5)
|
github.com/conformal/btcscript/opcode.go opcodeFromAltStack 100.00% (5/5)
|
||||||
github.com/conformal/btcscript/opcode.go opcodeSha256 100.00% (5/5)
|
github.com/conformal/btcscript/opcode.go opcodeSha256 100.00% (5/5)
|
||||||
github.com/conformal/btcscript/opcode.go opcodeRipemd160 100.00% (5/5)
|
github.com/conformal/btcscript/opcode.go opcodeRipemd160 100.00% (5/5)
|
||||||
github.com/conformal/btcscript/opcode.go opcodeNegate 100.00% (5/5)
|
|
||||||
github.com/conformal/btcscript/opcode.go opcodeHash160 100.00% (5/5)
|
|
||||||
github.com/conformal/btcscript/opcode.go opcodeAbs 100.00% (5/5)
|
github.com/conformal/btcscript/opcode.go opcodeAbs 100.00% (5/5)
|
||||||
github.com/conformal/btcscript/script.go Script.validPC 100.00% (5/5)
|
github.com/conformal/btcscript/opcode.go opcodeToAltStack 100.00% (5/5)
|
||||||
|
github.com/conformal/btcscript/opcode.go opcodeSize 100.00% (5/5)
|
||||||
github.com/conformal/btcscript/opcode.go opcode1Add 100.00% (5/5)
|
github.com/conformal/btcscript/opcode.go opcode1Add 100.00% (5/5)
|
||||||
github.com/conformal/btcscript/opcode.go opcode1Sub 100.00% (5/5)
|
github.com/conformal/btcscript/opcode.go opcode1Sub 100.00% (5/5)
|
||||||
github.com/conformal/btcscript/opcode.go opcodeSize 100.00% (5/5)
|
github.com/conformal/btcscript/opcode.go parsedOpcode.exec 100.00% (5/5)
|
||||||
|
github.com/conformal/btcscript/stack.go Stack.PickN 100.00% (5/5)
|
||||||
|
github.com/conformal/btcscript/stack.go Stack.RollN 100.00% (5/5)
|
||||||
|
github.com/conformal/btcscript/script.go removeOpcodeByData 100.00% (5/5)
|
||||||
github.com/conformal/btcscript/stack.go Stack.PeekBool 100.00% (4/4)
|
github.com/conformal/btcscript/stack.go Stack.PeekBool 100.00% (4/4)
|
||||||
github.com/conformal/btcscript/opcode.go opcodeEndif 100.00% (4/4)
|
github.com/conformal/btcscript/opcode.go opcodeEndif 100.00% (4/4)
|
||||||
github.com/conformal/btcscript/opcode.go opcodeEqualVerify 100.00% (4/4)
|
github.com/conformal/btcscript/opcode.go opcodeEqualVerify 100.00% (4/4)
|
||||||
|
@ -66,43 +67,47 @@ github.com/conformal/btcscript/script.go unparseScript 100.00% (4/4)
|
||||||
github.com/conformal/btcscript/script.go Script.curPC 100.00% (4/4)
|
github.com/conformal/btcscript/script.go Script.curPC 100.00% (4/4)
|
||||||
github.com/conformal/btcscript/script.go Script.DisasmPC 100.00% (4/4)
|
github.com/conformal/btcscript/script.go Script.DisasmPC 100.00% (4/4)
|
||||||
github.com/conformal/btcscript/script.go getStack 100.00% (4/4)
|
github.com/conformal/btcscript/script.go getStack 100.00% (4/4)
|
||||||
|
github.com/conformal/btcscript/script.go GetSigOpCount 100.00% (4/4)
|
||||||
github.com/conformal/btcscript/stack.go fromBool 100.00% (3/3)
|
github.com/conformal/btcscript/stack.go fromBool 100.00% (3/3)
|
||||||
|
github.com/conformal/btcscript/script.go setStack 100.00% (3/3)
|
||||||
github.com/conformal/btcscript/address.go ScriptType.String 100.00% (3/3)
|
github.com/conformal/btcscript/address.go ScriptType.String 100.00% (3/3)
|
||||||
github.com/conformal/btcscript/script.go scriptUInt16 100.00% (3/3)
|
github.com/conformal/btcscript/script.go scriptUInt16 100.00% (3/3)
|
||||||
github.com/conformal/btcscript/script.go setStack 100.00% (3/3)
|
|
||||||
github.com/conformal/btcscript/script.go scriptUInt8 100.00% (3/3)
|
github.com/conformal/btcscript/script.go scriptUInt8 100.00% (3/3)
|
||||||
github.com/conformal/btcscript/script.go scriptUInt32 100.00% (3/3)
|
github.com/conformal/btcscript/script.go scriptUInt32 100.00% (3/3)
|
||||||
github.com/conformal/btcscript/stack.go Stack.NipN 100.00% (2/2)
|
|
||||||
github.com/conformal/btcscript/stack.go Stack.Depth 100.00% (2/2)
|
|
||||||
github.com/conformal/btcscript/opcode.go calcHash 100.00% (2/2)
|
|
||||||
github.com/conformal/btcscript/opcode.go opcodeDepth 100.00% (2/2)
|
|
||||||
github.com/conformal/btcscript/opcode.go opcodeN 100.00% (2/2)
|
|
||||||
github.com/conformal/btcscript/opcode.go opcodeCodeSeparator 100.00% (2/2)
|
|
||||||
github.com/conformal/btcscript/opcode.go opcode1Negate 100.00% (2/2)
|
|
||||||
github.com/conformal/btcscript/opcode.go opcodeFalse 100.00% (2/2)
|
|
||||||
github.com/conformal/btcscript/opcode.go opcodePushData 100.00% (2/2)
|
github.com/conformal/btcscript/opcode.go opcodePushData 100.00% (2/2)
|
||||||
github.com/conformal/btcscript/opcode.go opcodeNop 100.00% (1/1)
|
github.com/conformal/btcscript/opcode.go calcHash 100.00% (2/2)
|
||||||
github.com/conformal/btcscript/opcode.go opcode3Dup 100.00% (1/1)
|
github.com/conformal/btcscript/opcode.go opcodeCodeSeparator 100.00% (2/2)
|
||||||
|
github.com/conformal/btcscript/opcode.go opcodeDepth 100.00% (2/2)
|
||||||
|
github.com/conformal/btcscript/stack.go Stack.Depth 100.00% (2/2)
|
||||||
|
github.com/conformal/btcscript/opcode.go opcode1Negate 100.00% (2/2)
|
||||||
|
github.com/conformal/btcscript/stack.go Stack.NipN 100.00% (2/2)
|
||||||
|
github.com/conformal/btcscript/opcode.go opcodeN 100.00% (2/2)
|
||||||
|
github.com/conformal/btcscript/opcode.go opcodeFalse 100.00% (2/2)
|
||||||
|
github.com/conformal/btcscript/opcode.go init 100.00% (1/1)
|
||||||
|
github.com/conformal/btcscript/log.go newLogClosure 100.00% (1/1)
|
||||||
|
github.com/conformal/btcscript/stack.go Stack.PopByteArray 100.00% (1/1)
|
||||||
github.com/conformal/btcscript/opcode.go calcHash160 100.00% (1/1)
|
github.com/conformal/btcscript/opcode.go calcHash160 100.00% (1/1)
|
||||||
github.com/conformal/btcscript/opcode.go opcode2Dup 100.00% (1/1)
|
github.com/conformal/btcscript/opcode.go opcode2Dup 100.00% (1/1)
|
||||||
github.com/conformal/btcscript/opcode.go opcode2Drop 100.00% (1/1)
|
github.com/conformal/btcscript/opcode.go opcode2Drop 100.00% (1/1)
|
||||||
github.com/conformal/btcscript/opcode.go opcodeReturn 100.00% (1/1)
|
github.com/conformal/btcscript/opcode.go opcodeReturn 100.00% (1/1)
|
||||||
|
github.com/conformal/btcscript/opcode.go opcodeNop 100.00% (1/1)
|
||||||
|
github.com/conformal/btcscript/opcode.go opcode3Dup 100.00% (1/1)
|
||||||
github.com/conformal/btcscript/stack.go Stack.PushByteArray 100.00% (1/1)
|
github.com/conformal/btcscript/stack.go Stack.PushByteArray 100.00% (1/1)
|
||||||
github.com/conformal/btcscript/stack.go Stack.PushInt 100.00% (1/1)
|
github.com/conformal/btcscript/stack.go Stack.PushInt 100.00% (1/1)
|
||||||
github.com/conformal/btcscript/opcode.go opcode2Over 100.00% (1/1)
|
github.com/conformal/btcscript/script.go Script.GetStack 100.00% (1/1)
|
||||||
github.com/conformal/btcscript/stack.go Stack.PopByteArray 100.00% (1/1)
|
|
||||||
github.com/conformal/btcscript/opcode.go opcodeInvalid 100.00% (1/1)
|
github.com/conformal/btcscript/opcode.go opcodeInvalid 100.00% (1/1)
|
||||||
github.com/conformal/btcscript/opcode.go opcodeReserved 100.00% (1/1)
|
github.com/conformal/btcscript/opcode.go opcodeReserved 100.00% (1/1)
|
||||||
github.com/conformal/btcscript/opcode.go opcodeDisabled 100.00% (1/1)
|
|
||||||
github.com/conformal/btcscript/opcode.go init 100.00% (1/1)
|
|
||||||
github.com/conformal/btcscript/script.go Script.SetStack 100.00% (1/1)
|
github.com/conformal/btcscript/script.go Script.SetStack 100.00% (1/1)
|
||||||
|
github.com/conformal/btcscript/opcode.go opcodeDisabled 100.00% (1/1)
|
||||||
|
github.com/conformal/btcscript/script.go Script.GetAltStack 100.00% (1/1)
|
||||||
|
github.com/conformal/btcscript/log.go UseLogger 100.00% (1/1)
|
||||||
|
github.com/conformal/btcscript/script.go Script.SetAltStack 100.00% (1/1)
|
||||||
|
github.com/conformal/btcscript/script.go isPubkey 100.00% (1/1)
|
||||||
github.com/conformal/btcscript/script.go isPubkeyHash 100.00% (1/1)
|
github.com/conformal/btcscript/script.go isPubkeyHash 100.00% (1/1)
|
||||||
github.com/conformal/btcscript/script.go isScriptHash 100.00% (1/1)
|
github.com/conformal/btcscript/script.go isScriptHash 100.00% (1/1)
|
||||||
github.com/conformal/btcscript/log.go DisableLog 100.00% (1/1)
|
github.com/conformal/btcscript/log.go DisableLog 100.00% (1/1)
|
||||||
github.com/conformal/btcscript/script.go Script.GetAltStack 100.00% (1/1)
|
|
||||||
github.com/conformal/btcscript/log.go init 100.00% (1/1)
|
|
||||||
github.com/conformal/btcscript/script.go Script.SetAltStack 100.00% (1/1)
|
|
||||||
github.com/conformal/btcscript/script.go Script.disasm 100.00% (1/1)
|
github.com/conformal/btcscript/script.go Script.disasm 100.00% (1/1)
|
||||||
|
github.com/conformal/btcscript/log.go init 100.00% (1/1)
|
||||||
github.com/conformal/btcscript/opcode.go opcodeTuck 100.00% (1/1)
|
github.com/conformal/btcscript/opcode.go opcodeTuck 100.00% (1/1)
|
||||||
github.com/conformal/btcscript/opcode.go opcodeSwap 100.00% (1/1)
|
github.com/conformal/btcscript/opcode.go opcodeSwap 100.00% (1/1)
|
||||||
github.com/conformal/btcscript/opcode.go opcodeRot 100.00% (1/1)
|
github.com/conformal/btcscript/opcode.go opcodeRot 100.00% (1/1)
|
||||||
|
@ -112,22 +117,20 @@ github.com/conformal/btcscript/opcode.go opcodeDup 100.00% (1/1)
|
||||||
github.com/conformal/btcscript/opcode.go opcodeDrop 100.00% (1/1)
|
github.com/conformal/btcscript/opcode.go opcodeDrop 100.00% (1/1)
|
||||||
github.com/conformal/btcscript/opcode.go opcode2Swap 100.00% (1/1)
|
github.com/conformal/btcscript/opcode.go opcode2Swap 100.00% (1/1)
|
||||||
github.com/conformal/btcscript/opcode.go opcode2Rot 100.00% (1/1)
|
github.com/conformal/btcscript/opcode.go opcode2Rot 100.00% (1/1)
|
||||||
github.com/conformal/btcscript/script.go Script.GetStack 100.00% (1/1)
|
github.com/conformal/btcscript/opcode.go opcode2Over 100.00% (1/1)
|
||||||
github.com/conformal/btcscript/log.go newLogClosure 100.00% (1/1)
|
|
||||||
github.com/conformal/btcscript/script.go isPubkey 100.00% (1/1)
|
|
||||||
github.com/conformal/btcscript/stack.go Stack.PushBool 100.00% (1/1)
|
github.com/conformal/btcscript/stack.go Stack.PushBool 100.00% (1/1)
|
||||||
github.com/conformal/btcscript/script.go Script.subScript 100.00% (1/1)
|
github.com/conformal/btcscript/script.go Script.subScript 100.00% (1/1)
|
||||||
github.com/conformal/btcscript/log.go UseLogger 100.00% (1/1)
|
|
||||||
github.com/conformal/btcscript/opcode.go opcodeCheckMultiSig 98.21% (55/56)
|
github.com/conformal/btcscript/opcode.go opcodeCheckMultiSig 98.21% (55/56)
|
||||||
github.com/conformal/btcscript/opcode.go opcodeCheckSig 96.15% (25/26)
|
github.com/conformal/btcscript/opcode.go opcodeCheckSig 96.15% (25/26)
|
||||||
github.com/conformal/btcscript/script.go NewScript 95.24% (20/21)
|
|
||||||
github.com/conformal/btcscript/address.go ScriptToAddress 94.92% (56/59)
|
github.com/conformal/btcscript/address.go ScriptToAddress 94.92% (56/59)
|
||||||
|
github.com/conformal/btcscript/script.go NewScript 94.74% (18/19)
|
||||||
github.com/conformal/btcscript/script.go parseScript 93.75% (30/32)
|
github.com/conformal/btcscript/script.go parseScript 93.75% (30/32)
|
||||||
github.com/conformal/btcscript/script.go Script.Step 91.89% (34/37)
|
github.com/conformal/btcscript/script.go Script.Step 91.89% (34/37)
|
||||||
github.com/conformal/btcscript/script.go typeOfScript 83.33% (5/6)
|
github.com/conformal/btcscript/script.go typeOfScript 83.33% (5/6)
|
||||||
github.com/conformal/btcscript/script.go Script.DisasmScript 80.00% (4/5)
|
github.com/conformal/btcscript/script.go Script.DisasmScript 80.00% (4/5)
|
||||||
github.com/conformal/btcscript/script.go isPushOnly 75.00% (3/4)
|
github.com/conformal/btcscript/script.go GetPreciseSigOpCount 77.78% (14/18)
|
||||||
github.com/conformal/btcscript/opcode.go opcodeCheckSigVerify 75.00% (3/4)
|
github.com/conformal/btcscript/opcode.go opcodeCheckSigVerify 75.00% (3/4)
|
||||||
|
github.com/conformal/btcscript/script.go isPushOnly 75.00% (3/4)
|
||||||
github.com/conformal/btcscript/script.go Script.calcScriptHash 71.43% (25/35)
|
github.com/conformal/btcscript/script.go Script.calcScriptHash 71.43% (25/35)
|
||||||
github.com/conformal/btcscript/script.go Script.CheckErrorCondition 71.43% (10/14)
|
github.com/conformal/btcscript/script.go Script.CheckErrorCondition 71.43% (10/14)
|
||||||
github.com/conformal/btcscript/script.go isMultiSig 61.54% (8/13)
|
github.com/conformal/btcscript/script.go isMultiSig 61.54% (8/13)
|
||||||
|
@ -135,5 +138,5 @@ github.com/conformal/btcscript/opcode.go opcodeSha1 60.00% (3/5)
|
||||||
github.com/conformal/btcscript/script.go Script.Execute 44.44% (8/18)
|
github.com/conformal/btcscript/script.go Script.Execute 44.44% (8/18)
|
||||||
github.com/conformal/btcscript/log.go SetLogWriter 0.00% (0/7)
|
github.com/conformal/btcscript/log.go SetLogWriter 0.00% (0/7)
|
||||||
github.com/conformal/btcscript/log.go logClosure.String 0.00% (0/1)
|
github.com/conformal/btcscript/log.go logClosure.String 0.00% (0/1)
|
||||||
github.com/conformal/btcscript -------------------------- 93.98% (843/897)
|
github.com/conformal/btcscript -------------------------- 93.74% (869/927)
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue