mirror of
https://github.com/btcsuite/btcd.git
synced 2024-11-19 01:40:07 +01:00
Merge pull request #2178 from ProofOfKeags/standardness-cleanup
Update standardness rules congruent to Bitcoin Core
This commit is contained in:
commit
c4ed92fb52
@ -49,6 +49,10 @@ const (
|
|||||||
// can be evicted from the mempool when accepting a transaction
|
// can be evicted from the mempool when accepting a transaction
|
||||||
// replacement.
|
// replacement.
|
||||||
MaxReplacementEvictions = 100
|
MaxReplacementEvictions = 100
|
||||||
|
|
||||||
|
// Transactions smaller than 65 non-witness bytes are not relayed to
|
||||||
|
// mitigate CVE-2017-12842.
|
||||||
|
MinStandardTxNonWitnessSize = 65
|
||||||
)
|
)
|
||||||
|
|
||||||
// Tag represents an identifier to use for tagging orphan transactions. The
|
// Tag represents an identifier to use for tagging orphan transactions. The
|
||||||
@ -1355,6 +1359,12 @@ func (mp *TxPool) checkMempoolAcceptance(tx *btcutil.Tx,
|
|||||||
return nil, txRuleError(wire.RejectDuplicate, str)
|
return nil, txRuleError(wire.RejectDuplicate, str)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Disallow transactions under the minimum standardness size.
|
||||||
|
if tx.MsgTx().SerializeSizeStripped() < MinStandardTxNonWitnessSize {
|
||||||
|
str := fmt.Sprintf("tx %v is too small", txHash)
|
||||||
|
return nil, txRuleError(wire.RejectNonstandard, str)
|
||||||
|
}
|
||||||
|
|
||||||
// Perform preliminary sanity checks on the transaction. This makes use
|
// Perform preliminary sanity checks on the transaction. This makes use
|
||||||
// of blockchain which contains the invariant rules for what
|
// of blockchain which contains the invariant rules for what
|
||||||
// transactions are allowed into blocks.
|
// transactions are allowed into blocks.
|
||||||
|
@ -333,6 +333,32 @@
|
|||||||
["BIP143: wrong sighash (with FindAndDelete) = 17c50ec2181ecdfdc85ca081174b248199ba81fff730794d4f69b8ec031f2dce"],
|
["BIP143: wrong sighash (with FindAndDelete) = 17c50ec2181ecdfdc85ca081174b248199ba81fff730794d4f69b8ec031f2dce"],
|
||||||
[[["9628667ad48219a169b41b020800162287d2c0f713c04157e95c484a8dcb7592", 7500, "0x00 0x20 0x9b66c15b4e0b4eb49fa877982cafded24859fe5b0e2dbfbe4f0df1de7743fd52", 200000]],
|
[[["9628667ad48219a169b41b020800162287d2c0f713c04157e95c484a8dcb7592", 7500, "0x00 0x20 0x9b66c15b4e0b4eb49fa877982cafded24859fe5b0e2dbfbe4f0df1de7743fd52", 200000]],
|
||||||
"010000000001019275cb8d4a485ce95741c013f7c0d28722160008021bb469a11982d47a6628964c1d000000ffffffff0101000000000000000007004830450220487fb382c4974de3f7d834c1b617fe15860828c7f96454490edd6d891556dcc9022100baf95feb48f845d5bfc9882eb6aeefa1bc3790e39f59eaa46ff7f15ae626c53e0148304502205286f726690b2e9b0207f0345711e63fa7012045b9eb0f19c2458ce1db90cf43022100e89f17f86abc5b149eba4115d4f128bcf45d77fb3ecdd34f594091340c03959601010221023cb6055f4b57a1580c5a753e19610cafaedf7e0ff377731c77837fd666eae1712102c1b1db303ac232ffa8e5e7cc2cf5f96c6e40d3e6914061204c0541cb2043a0969552af4830450220487fb382c4974de3f7d834c1b617fe15860828c7f96454490edd6d891556dcc9022100baf95feb48f845d5bfc9882eb6aeefa1bc3790e39f59eaa46ff7f15ae626c53e0148304502205286f726690b2e9b0207f0345711e63fa7012045b9eb0f19c2458ce1db90cf43022100e89f17f86abc5b149eba4115d4f128bcf45d77fb3ecdd34f594091340c039596017500000000", "P2SH,WITNESS"],
|
"010000000001019275cb8d4a485ce95741c013f7c0d28722160008021bb469a11982d47a6628964c1d000000ffffffff0101000000000000000007004830450220487fb382c4974de3f7d834c1b617fe15860828c7f96454490edd6d891556dcc9022100baf95feb48f845d5bfc9882eb6aeefa1bc3790e39f59eaa46ff7f15ae626c53e0148304502205286f726690b2e9b0207f0345711e63fa7012045b9eb0f19c2458ce1db90cf43022100e89f17f86abc5b149eba4115d4f128bcf45d77fb3ecdd34f594091340c03959601010221023cb6055f4b57a1580c5a753e19610cafaedf7e0ff377731c77837fd666eae1712102c1b1db303ac232ffa8e5e7cc2cf5f96c6e40d3e6914061204c0541cb2043a0969552af4830450220487fb382c4974de3f7d834c1b617fe15860828c7f96454490edd6d891556dcc9022100baf95feb48f845d5bfc9882eb6aeefa1bc3790e39f59eaa46ff7f15ae626c53e0148304502205286f726690b2e9b0207f0345711e63fa7012045b9eb0f19c2458ce1db90cf43022100e89f17f86abc5b149eba4115d4f128bcf45d77fb3ecdd34f594091340c039596017500000000", "P2SH,WITNESS"],
|
||||||
|
[[["bc7fd132fcf817918334822ee6d9bd95c889099c96e07ca2c1eb2cc70db63224", 0, "CODESEPARATOR 0x21 0x038479a0fa998cd35259a2ef0a7a5c68662c1474f88ccb6d08a7677bbec7f22041 CHECKSIG"]],
|
||||||
|
"01000000012432b60dc72cebc1a27ce0969c0989c895bdd9e62e8234839117f8fc32d17fbc000000004a493046022100a576b52051962c25e642c0fd3d77ee6c92487048e5d90818bcf5b51abaccd7900221008204f8fb121be4ec3b24483b1f92d89b1b0548513a134e345c5442e86e8617a501ffffffff010000000000000000016a00000000", "P2SH,CONST_SCRIPTCODE"],
|
||||||
|
[[["83e194f90b6ef21fa2e3a365b63794fb5daa844bdc9b25de30899fcfe7b01047", 0, "CODESEPARATOR CODESEPARATOR 0x21 0x038479a0fa998cd35259a2ef0a7a5c68662c1474f88ccb6d08a7677bbec7f22041 CHECKSIG"]],
|
||||||
|
"01000000014710b0e7cf9f8930de259bdc4b84aa5dfb9437b665a3e3a21ff26e0bf994e183000000004a493046022100a166121a61b4eeb19d8f922b978ff6ab58ead8a5a5552bf9be73dc9c156873ea02210092ad9bc43ee647da4f6652c320800debcf08ec20a094a0aaf085f63ecb37a17201ffffffff010000000000000000016a00000000", "P2SH,CONST_SCRIPTCODE"],
|
||||||
|
[[["326882a7f22b5191f1a0cc9962ca4b878cd969cf3b3a70887aece4d801a0ba5e", 0, "0x21 0x038479a0fa998cd35259a2ef0a7a5c68662c1474f88ccb6d08a7677bbec7f22041 CODESEPARATOR CHECKSIG"]],
|
||||||
|
"01000000015ebaa001d8e4ec7a88703a3bcf69d98c874bca6299cca0f191512bf2a7826832000000004948304502203bf754d1c6732fbf87c5dcd81258aefd30f2060d7bd8ac4a5696f7927091dad1022100f5bcb726c4cf5ed0ed34cc13dadeedf628ae1045b7cb34421bc60b89f4cecae701ffffffff010000000000000000016a00000000", "P2SH,CONST_SCRIPTCODE"],
|
||||||
|
[[["a955032f4d6b0c9bfe8cad8f00a8933790b9c1dc28c82e0f48e75b35da0e4944", 0, "0x21 0x038479a0fa998cd35259a2ef0a7a5c68662c1474f88ccb6d08a7677bbec7f22041 CHECKSIGVERIFY CODESEPARATOR 0x21 0x038479a0fa998cd35259a2ef0a7a5c68662c1474f88ccb6d08a7677bbec7f22041 CHECKSIGVERIFY CODESEPARATOR 1"]],
|
||||||
|
"010000000144490eda355be7480f2ec828dcc1b9903793a8008fad8cfe9b0c6b4d2f0355a900000000924830450221009c0a27f886a1d8cb87f6f595fbc3163d28f7a81ec3c4b252ee7f3ac77fd13ffa02203caa8dfa09713c8c4d7ef575c75ed97812072405d932bd11e6a1593a98b679370148304502201e3861ef39a526406bad1e20ecad06be7375ad40ddb582c9be42d26c3a0d7b240221009d0a3985e96522e59635d19cc4448547477396ce0ef17a58e7d74c3ef464292301ffffffff010000000000000000016a00000000", "P2SH,CONST_SCRIPTCODE"],
|
||||||
|
[[["a955032f4d6b0c9bfe8cad8f00a8933790b9c1dc28c82e0f48e75b35da0e4944", 0, "IF CODESEPARATOR ENDIF 0x21 0x0378d430274f8c5ec1321338151e9f27f4c676a008bdf8638d07c0b6be9ab35c71 CHECKSIGVERIFY CODESEPARATOR 1"]],
|
||||||
|
"010000000144490eda355be7480f2ec828dcc1b9903793a8008fad8cfe9b0c6b4d2f0355a9000000004a48304502207a6974a77c591fa13dff60cabbb85a0de9e025c09c65a4b2285e47ce8e22f761022100f0efaac9ff8ac36b10721e0aae1fb975c90500b50c56e8a0cc52b0403f0425dd0100ffffffff010000000000000000016a00000000", "P2SH,CONST_SCRIPTCODE"],
|
||||||
|
[[["a955032f4d6b0c9bfe8cad8f00a8933790b9c1dc28c82e0f48e75b35da0e4944", 0, "IF CODESEPARATOR ENDIF 0x21 0x0378d430274f8c5ec1321338151e9f27f4c676a008bdf8638d07c0b6be9ab35c71 CHECKSIGVERIFY CODESEPARATOR 1"]],
|
||||||
|
"010000000144490eda355be7480f2ec828dcc1b9903793a8008fad8cfe9b0c6b4d2f0355a9000000004a483045022100fa4a74ba9fd59c59f46c3960cf90cbe0d2b743c471d24a3d5d6db6002af5eebb02204d70ec490fd0f7055a7c45f86514336e3a7f03503dacecabb247fc23f15c83510151ffffffff010000000000000000016a00000000", "P2SH,CONST_SCRIPTCODE"],
|
||||||
|
[[["ccf7f4053a02e653c36ac75c891b7496d0dc5ce5214f6c913d9cf8f1329ebee0", 0, "DUP HASH160 0x14 0xee5a6aa40facefb2655ac23c0c28c57c65c41f9b EQUALVERIFY CHECKSIG"]],
|
||||||
|
"0100000001e0be9e32f1f89c3d916c4f21e55cdcd096741b895cc76ac353e6023a05f4f7cc00000000d86149304602210086e5f736a2c3622ebb62bd9d93d8e5d76508b98be922b97160edc3dcca6d8c47022100b23c312ac232a4473f19d2aeb95ab7bdf2b65518911a0d72d50e38b5dd31dc820121038479a0fa998cd35259a2ef0a7a5c68662c1474f88ccb6d08a7677bbec7f22041ac4730440220508fa761865c8abd81244a168392876ee1d94e8ed83897066b5e2df2400dad24022043f5ee7538e87e9c6aef7ef55133d3e51da7cc522830a9c4d736977a76ef755c0121038479a0fa998cd35259a2ef0a7a5c68662c1474f88ccb6d08a7677bbec7f22041ffffffff010000000000000000016a00000000", "P2SH,CONST_SCRIPTCODE"],
|
||||||
|
[[["10c9f0effe83e97f80f067de2b11c6a00c3088a4bce42c5ae761519af9306f3c", 1, "DUP HASH160 0x14 0xee5a6aa40facefb2655ac23c0c28c57c65c41f9b EQUALVERIFY CHECKSIG"]],
|
||||||
|
"01000000013c6f30f99a5161e75a2ce4bca488300ca0c6112bde67f0807fe983feeff0c91001000000e608646561646265656675ab61493046022100ce18d384221a731c993939015e3d1bcebafb16e8c0b5b5d14097ec8177ae6f28022100bcab227af90bab33c3fe0a9abfee03ba976ee25dc6ce542526e9b2e56e14b7f10121038479a0fa998cd35259a2ef0a7a5c68662c1474f88ccb6d08a7677bbec7f22041ac493046022100c3b93edcc0fd6250eb32f2dd8a0bba1754b0f6c3be8ed4100ed582f3db73eba2022100bf75b5bd2eff4d6bf2bda2e34a40fcc07d4aa3cf862ceaa77b47b81eff829f9a01ab21038479a0fa998cd35259a2ef0a7a5c68662c1474f88ccb6d08a7677bbec7f22041ffffffff010000000000000000016a00000000", "P2SH,CONST_SCRIPTCODE"],
|
||||||
|
[[["6056ebd549003b10cbbd915cea0d82209fe40b8617104be917a26fa92cbe3d6f", 0, "DUP HASH160 0x14 0xee5a6aa40facefb2655ac23c0c28c57c65c41f9b EQUALVERIFY CHECKSIG"]],
|
||||||
|
"01000000016f3dbe2ca96fa217e94b1017860be49f20820dea5c91bdcb103b0049d5eb566000000000fd1d0147304402203989ac8f9ad36b5d0919d97fa0a7f70c5272abee3b14477dc646288a8b976df5022027d19da84a066af9053ad3d1d7459d171b7e3a80bc6c4ef7a330677a6be548140147304402203989ac8f9ad36b5d0919d97fa0a7f70c5272abee3b14477dc646288a8b976df5022027d19da84a066af9053ad3d1d7459d171b7e3a80bc6c4ef7a330677a6be548140121038479a0fa998cd35259a2ef0a7a5c68662c1474f88ccb6d08a7677bbec7f22041ac47304402203757e937ba807e4a5da8534c17f9d121176056406a6465054bdd260457515c1a02200f02eccf1bec0f3a0d65df37889143c2e88ab7acec61a7b6f5aa264139141a2b0121038479a0fa998cd35259a2ef0a7a5c68662c1474f88ccb6d08a7677bbec7f22041ffffffff010000000000000000016a00000000", "P2SH,CONST_SCRIPTCODE"],
|
||||||
|
[[["5a6b0021a6042a686b6b94abc36b387bef9109847774e8b1e51eb8cc55c53921", 1, "DUP HASH160 0x14 0xee5a6aa40facefb2655ac23c0c28c57c65c41f9b EQUALVERIFY CHECKSIG"]],
|
||||||
|
"01000000012139c555ccb81ee5b1e87477840991ef7b386bc3ab946b6b682a04a621006b5a01000000fdb40148304502201723e692e5f409a7151db386291b63524c5eb2030df652b1f53022fd8207349f022100b90d9bbf2f3366ce176e5e780a00433da67d9e5c79312c6388312a296a5800390148304502201723e692e5f409a7151db386291b63524c5eb2030df652b1f53022fd8207349f022100b90d9bbf2f3366ce176e5e780a00433da67d9e5c79312c6388312a296a5800390121038479a0fa998cd35259a2ef0a7a5c68662c1474f88ccb6d08a7677bbec7f2204148304502201723e692e5f409a7151db386291b63524c5eb2030df652b1f53022fd8207349f022100b90d9bbf2f3366ce176e5e780a00433da67d9e5c79312c6388312a296a5800390175ac4830450220646b72c35beeec51f4d5bc1cbae01863825750d7f490864af354e6ea4f625e9c022100f04b98432df3a9641719dbced53393022e7249fb59db993af1118539830aab870148304502201723e692e5f409a7151db386291b63524c5eb2030df652b1f53022fd8207349f022100b90d9bbf2f3366ce176e5e780a00433da67d9e5c79312c6388312a296a580039017521038479a0fa998cd35259a2ef0a7a5c68662c1474f88ccb6d08a7677bbec7f22041ffffffff010000000000000000016a00000000", "P2SH,CONST_SCRIPTCODE"],
|
||||||
|
[[["b5b598de91787439afd5938116654e0b16b7a0d0f82742ba37564219c5afcbf9", 0, "DUP HASH160 0x14 0xf6f365c40f0739b61de827a44751e5e99032ed8f EQUALVERIFY CHECKSIG"],
|
||||||
|
["ab9805c6d57d7070d9a42c5176e47bb705023e6b67249fb6760880548298e742", 0, "HASH160 0x14 0xd8dacdadb7462ae15cd906f1878706d0da8660e6 EQUAL"]],
|
||||||
|
"0100000002f9cbafc519425637ba4227f8d0a0b7160b4e65168193d5af39747891de98b5b5000000006b4830450221008dd619c563e527c47d9bd53534a770b102e40faa87f61433580e04e271ef2f960220029886434e18122b53d5decd25f1f4acb2480659fea20aabd856987ba3c3907e0121022b78b756e2258af13779c1a1f37ea6800259716ca4b7f0b87610e0bf3ab52a01ffffffff42e7988254800876b69f24676b3e0205b77be476512ca4d970707dd5c60598ab00000000fd260100483045022015bd0139bcccf990a6af6ec5c1c52ed8222e03a0d51c334df139968525d2fcd20221009f9efe325476eb64c3958e4713e9eefe49bf1d820ed58d2112721b134e2a1a53034930460221008431bdfa72bc67f9d41fe72e94c88fb8f359ffa30b33c72c121c5a877d922e1002210089ef5fc22dd8bfc6bf9ffdb01a9862d27687d424d1fefbab9e9c7176844a187a014c9052483045022015bd0139bcccf990a6af6ec5c1c52ed8222e03a0d51c334df139968525d2fcd20221009f9efe325476eb64c3958e4713e9eefe49bf1d820ed58d2112721b134e2a1a5303210378d430274f8c5ec1321338151e9f27f4c676a008bdf8638d07c0b6be9ab35c71210378d430274f8c5ec1321338151e9f27f4c676a008bdf8638d07c0b6be9ab35c7153aeffffffff01a08601000000000017a914d8dacdadb7462ae15cd906f1878706d0da8660e68700000000", "P2SH,CONST_SCRIPTCODE"],
|
||||||
|
[[["ceafe58e0f6e7d67c0409fbbf673c84c166e3c5d3c24af58f7175b18df3bb3db", 0, "DUP HASH160 0x14 0xf6f365c40f0739b61de827a44751e5e99032ed8f EQUALVERIFY CHECKSIG"],
|
||||||
|
["ceafe58e0f6e7d67c0409fbbf673c84c166e3c5d3c24af58f7175b18df3bb3db", 1, "2 0x48 0x3045022015bd0139bcccf990a6af6ec5c1c52ed8222e03a0d51c334df139968525d2fcd20221009f9efe325476eb64c3958e4713e9eefe49bf1d820ed58d2112721b134e2a1a5303 0x21 0x0378d430274f8c5ec1321338151e9f27f4c676a008bdf8638d07c0b6be9ab35c71 0x21 0x0378d430274f8c5ec1321338151e9f27f4c676a008bdf8638d07c0b6be9ab35c71 3 CHECKMULTISIG"]],
|
||||||
|
"0100000002dbb33bdf185b17f758af243c5d3c6e164cc873f6bb9f40c0677d6e0f8ee5afce000000006b4830450221009627444320dc5ef8d7f68f35010b4c050a6ed0d96b67a84db99fda9c9de58b1e02203e4b4aaa019e012e65d69b487fdf8719df72f488fa91506a80c49a33929f1fd50121022b78b756e2258af13779c1a1f37ea6800259716ca4b7f0b87610e0bf3ab52a01ffffffffdbb33bdf185b17f758af243c5d3c6e164cc873f6bb9f40c0677d6e0f8ee5afce010000009300483045022015bd0139bcccf990a6af6ec5c1c52ed8222e03a0d51c334df139968525d2fcd20221009f9efe325476eb64c3958e4713e9eefe49bf1d820ed58d2112721b134e2a1a5303483045022015bd0139bcccf990a6af6ec5c1c52ed8222e03a0d51c334df139968525d2fcd20221009f9efe325476eb64c3958e4713e9eefe49bf1d820ed58d2112721b134e2a1a5303ffffffff01a0860100000000001976a9149bc0bbdd3024da4d0c38ed1aecf5c68dd1d3fa1288ac00000000", "P2SH,CONST_SCRIPTCODE"],
|
||||||
|
|
||||||
["Make diffs cleaner by leaving a comment here without comma at the end"]
|
["Make diffs cleaner by leaving a comment here without comma at the end"]
|
||||||
]
|
]
|
||||||
|
@ -471,17 +471,17 @@
|
|||||||
["BIP143 example: P2WSH with OP_CODESEPARATOR and out-of-range SIGHASH_SINGLE."],
|
["BIP143 example: P2WSH with OP_CODESEPARATOR and out-of-range SIGHASH_SINGLE."],
|
||||||
[[["6eb316926b1c5d567cd6f5e6a84fec606fc53d7b474526d1fff3948020c93dfe", 0, "0x21 0x036d5c20fa14fb2f635474c1dc4ef5909d4568e5569b79fc94d3448486e14685f8 CHECKSIG", 156250000],
|
[[["6eb316926b1c5d567cd6f5e6a84fec606fc53d7b474526d1fff3948020c93dfe", 0, "0x21 0x036d5c20fa14fb2f635474c1dc4ef5909d4568e5569b79fc94d3448486e14685f8 CHECKSIG", 156250000],
|
||||||
["f825690aee1b3dc247da796cacb12687a5e802429fd291cfd63e010f02cf1508", 0, "0x00 0x20 0x5d1b56b63d714eebe542309525f484b7e9d6f686b3781b6f61ef925d66d6f6a0", 4900000000]],
|
["f825690aee1b3dc247da796cacb12687a5e802429fd291cfd63e010f02cf1508", 0, "0x00 0x20 0x5d1b56b63d714eebe542309525f484b7e9d6f686b3781b6f61ef925d66d6f6a0", 4900000000]],
|
||||||
"01000000000102fe3dc9208094f3ffd12645477b3dc56f60ec4fa8e6f5d67c565d1c6b9216b36e000000004847304402200af4e47c9b9629dbecc21f73af989bdaa911f7e6f6c2e9394588a3aa68f81e9902204f3fcf6ade7e5abb1295b6774c8e0abd94ae62217367096bc02ee5e435b67da201ffffffff0815cf020f013ed6cf91d29f4202e8a58726b1ac6c79da47c23d1bee0a6925f80000000000ffffffff0100f2052a010000001976a914a30741f8145e5acadf23f751864167f32e0963f788ac000347304402200de66acf4527789bfda55fc5459e214fa6083f936b430a762c629656216805ac0220396f550692cd347171cbc1ef1f51e15282e837bb2b30860dc77c8f78bc8501e503473044022027dc95ad6b740fe5129e7e62a75dd00f291a2aeb1200b84b09d9e3789406b6c002201a9ecd315dd6a0e632ab20bbb98948bc0c6fb204f2c286963bb48517a7058e27034721026dccc749adc2a9d0d89497ac511f760f45c47dc5ed9cf352a58ac706453880aeadab210255a9626aebf5e29c0e6538428ba0d1dcf6ca98ffdf086aa8ced5e0d0215ea465ac00000000", "P2SH,WITNESS"],
|
"01000000000102fe3dc9208094f3ffd12645477b3dc56f60ec4fa8e6f5d67c565d1c6b9216b36e000000004847304402200af4e47c9b9629dbecc21f73af989bdaa911f7e6f6c2e9394588a3aa68f81e9902204f3fcf6ade7e5abb1295b6774c8e0abd94ae62217367096bc02ee5e435b67da201ffffffff0815cf020f013ed6cf91d29f4202e8a58726b1ac6c79da47c23d1bee0a6925f80000000000ffffffff0100f2052a010000001976a914a30741f8145e5acadf23f751864167f32e0963f788ac000347304402200de66acf4527789bfda55fc5459e214fa6083f936b430a762c629656216805ac0220396f550692cd347171cbc1ef1f51e15282e837bb2b30860dc77c8f78bc8501e503473044022027dc95ad6b740fe5129e7e62a75dd00f291a2aeb1200b84b09d9e3789406b6c002201a9ecd315dd6a0e632ab20bbb98948bc0c6fb204f2c286963bb48517a7058e27034721026dccc749adc2a9d0d89497ac511f760f45c47dc5ed9cf352a58ac706453880aeadab210255a9626aebf5e29c0e6538428ba0d1dcf6ca98ffdf086aa8ced5e0d0215ea465ac00000000", "P2SH,WITNESS,CONST_SCRIPTCODE"],
|
||||||
|
|
||||||
["BIP143 example: P2WSH with unexecuted OP_CODESEPARATOR and SINGLE|ANYONECANPAY"],
|
["BIP143 example: P2WSH with unexecuted OP_CODESEPARATOR and SINGLE|ANYONECANPAY"],
|
||||||
[[["01c0cf7fba650638e55eb91261b183251fbb466f90dff17f10086817c542b5e9", 0, "0x00 0x20 0xba468eea561b26301e4cf69fa34bde4ad60c81e70f059f045ca9a79931004a4d", 16777215],
|
[[["01c0cf7fba650638e55eb91261b183251fbb466f90dff17f10086817c542b5e9", 0, "0x00 0x20 0xba468eea561b26301e4cf69fa34bde4ad60c81e70f059f045ca9a79931004a4d", 16777215],
|
||||||
["1b2a9a426ba603ba357ce7773cb5805cb9c7c2b386d100d1fc9263513188e680", 0, "0x00 0x20 0xd9bbfbe56af7c4b7f960a70d7ea107156913d9e5a26b0a71429df5e097ca6537", 16777215]],
|
["1b2a9a426ba603ba357ce7773cb5805cb9c7c2b386d100d1fc9263513188e680", 0, "0x00 0x20 0xd9bbfbe56af7c4b7f960a70d7ea107156913d9e5a26b0a71429df5e097ca6537", 16777215]],
|
||||||
"01000000000102e9b542c5176808107ff1df906f46bb1f2583b16112b95ee5380665ba7fcfc0010000000000ffffffff80e68831516392fcd100d186b3c2c7b95c80b53c77e77c35ba03a66b429a2a1b0000000000ffffffff0280969800000000001976a914de4b231626ef508c9a74a8517e6783c0546d6b2888ac80969800000000001976a9146648a8cd4531e1ec47f35916de8e259237294d1e88ac02483045022100f6a10b8604e6dc910194b79ccfc93e1bc0ec7c03453caaa8987f7d6c3413566002206216229ede9b4d6ec2d325be245c5b508ff0339bf1794078e20bfe0babc7ffe683270063ab68210392972e2eb617b2388771abe27235fd5ac44af8e61693261550447a4c3e39da98ac024730440220032521802a76ad7bf74d0e2c218b72cf0cbc867066e2e53db905ba37f130397e02207709e2188ed7f08f4c952d9d13986da504502b8c3be59617e043552f506c46ff83275163ab68210392972e2eb617b2388771abe27235fd5ac44af8e61693261550447a4c3e39da98ac00000000", "P2SH,WITNESS"],
|
"01000000000102e9b542c5176808107ff1df906f46bb1f2583b16112b95ee5380665ba7fcfc0010000000000ffffffff80e68831516392fcd100d186b3c2c7b95c80b53c77e77c35ba03a66b429a2a1b0000000000ffffffff0280969800000000001976a914de4b231626ef508c9a74a8517e6783c0546d6b2888ac80969800000000001976a9146648a8cd4531e1ec47f35916de8e259237294d1e88ac02483045022100f6a10b8604e6dc910194b79ccfc93e1bc0ec7c03453caaa8987f7d6c3413566002206216229ede9b4d6ec2d325be245c5b508ff0339bf1794078e20bfe0babc7ffe683270063ab68210392972e2eb617b2388771abe27235fd5ac44af8e61693261550447a4c3e39da98ac024730440220032521802a76ad7bf74d0e2c218b72cf0cbc867066e2e53db905ba37f130397e02207709e2188ed7f08f4c952d9d13986da504502b8c3be59617e043552f506c46ff83275163ab68210392972e2eb617b2388771abe27235fd5ac44af8e61693261550447a4c3e39da98ac00000000", "P2SH,WITNESS,CONST_SCRIPTCODE"],
|
||||||
|
|
||||||
["BIP143 example: Same as the previous example with input-output pairs swapped"],
|
["BIP143 example: Same as the previous example with input-output pairs swapped"],
|
||||||
[[["1b2a9a426ba603ba357ce7773cb5805cb9c7c2b386d100d1fc9263513188e680", 0, "0x00 0x20 0xd9bbfbe56af7c4b7f960a70d7ea107156913d9e5a26b0a71429df5e097ca6537", 16777215],
|
[[["1b2a9a426ba603ba357ce7773cb5805cb9c7c2b386d100d1fc9263513188e680", 0, "0x00 0x20 0xd9bbfbe56af7c4b7f960a70d7ea107156913d9e5a26b0a71429df5e097ca6537", 16777215],
|
||||||
["01c0cf7fba650638e55eb91261b183251fbb466f90dff17f10086817c542b5e9", 0, "0x00 0x20 0xba468eea561b26301e4cf69fa34bde4ad60c81e70f059f045ca9a79931004a4d", 16777215]],
|
["01c0cf7fba650638e55eb91261b183251fbb466f90dff17f10086817c542b5e9", 0, "0x00 0x20 0xba468eea561b26301e4cf69fa34bde4ad60c81e70f059f045ca9a79931004a4d", 16777215]],
|
||||||
"0100000000010280e68831516392fcd100d186b3c2c7b95c80b53c77e77c35ba03a66b429a2a1b0000000000ffffffffe9b542c5176808107ff1df906f46bb1f2583b16112b95ee5380665ba7fcfc0010000000000ffffffff0280969800000000001976a9146648a8cd4531e1ec47f35916de8e259237294d1e88ac80969800000000001976a914de4b231626ef508c9a74a8517e6783c0546d6b2888ac024730440220032521802a76ad7bf74d0e2c218b72cf0cbc867066e2e53db905ba37f130397e02207709e2188ed7f08f4c952d9d13986da504502b8c3be59617e043552f506c46ff83275163ab68210392972e2eb617b2388771abe27235fd5ac44af8e61693261550447a4c3e39da98ac02483045022100f6a10b8604e6dc910194b79ccfc93e1bc0ec7c03453caaa8987f7d6c3413566002206216229ede9b4d6ec2d325be245c5b508ff0339bf1794078e20bfe0babc7ffe683270063ab68210392972e2eb617b2388771abe27235fd5ac44af8e61693261550447a4c3e39da98ac00000000", "P2SH,WITNESS"],
|
"0100000000010280e68831516392fcd100d186b3c2c7b95c80b53c77e77c35ba03a66b429a2a1b0000000000ffffffffe9b542c5176808107ff1df906f46bb1f2583b16112b95ee5380665ba7fcfc0010000000000ffffffff0280969800000000001976a9146648a8cd4531e1ec47f35916de8e259237294d1e88ac80969800000000001976a914de4b231626ef508c9a74a8517e6783c0546d6b2888ac024730440220032521802a76ad7bf74d0e2c218b72cf0cbc867066e2e53db905ba37f130397e02207709e2188ed7f08f4c952d9d13986da504502b8c3be59617e043552f506c46ff83275163ab68210392972e2eb617b2388771abe27235fd5ac44af8e61693261550447a4c3e39da98ac02483045022100f6a10b8604e6dc910194b79ccfc93e1bc0ec7c03453caaa8987f7d6c3413566002206216229ede9b4d6ec2d325be245c5b508ff0339bf1794078e20bfe0babc7ffe683270063ab68210392972e2eb617b2388771abe27235fd5ac44af8e61693261550447a4c3e39da98ac00000000", "P2SH,WITNESS,CONST_SCRIPTCODE"],
|
||||||
|
|
||||||
["BIP143 example: P2SH-P2WSH 6-of-6 multisig signed with 6 different SIGHASH types"],
|
["BIP143 example: P2SH-P2WSH 6-of-6 multisig signed with 6 different SIGHASH types"],
|
||||||
[[["6eb98797a21c6c10aa74edf29d618be109f48a8e94c694f3701e08ca69186436", 1, "HASH160 0x14 0x9993a429037b5d912407a71c252019287b8d27a5 EQUAL", 987654321]],
|
[[["6eb98797a21c6c10aa74edf29d618be109f48a8e94c694f3701e08ca69186436", 1, "HASH160 0x14 0x9993a429037b5d912407a71c252019287b8d27a5 EQUAL", 987654321]],
|
||||||
@ -498,7 +498,7 @@
|
|||||||
"010000000169c12106097dc2e0526493ef67f21269fe888ef05c7a3a5dacab38e1ac8387f1581b0000b64830450220487fb382c4974de3f7d834c1b617fe15860828c7f96454490edd6d891556dcc9022100baf95feb48f845d5bfc9882eb6aeefa1bc3790e39f59eaa46ff7f15ae626c53e0121037a3fb04bcdb09eba90f69961ba1692a3528e45e67c85b200df820212d7594d334aad4830450220487fb382c4974de3f7d834c1b617fe15860828c7f96454490edd6d891556dcc9022100baf95feb48f845d5bfc9882eb6aeefa1bc3790e39f59eaa46ff7f15ae626c53e01ffffffff0101000000000000000000000000", "P2SH,WITNESS"],
|
"010000000169c12106097dc2e0526493ef67f21269fe888ef05c7a3a5dacab38e1ac8387f1581b0000b64830450220487fb382c4974de3f7d834c1b617fe15860828c7f96454490edd6d891556dcc9022100baf95feb48f845d5bfc9882eb6aeefa1bc3790e39f59eaa46ff7f15ae626c53e0121037a3fb04bcdb09eba90f69961ba1692a3528e45e67c85b200df820212d7594d334aad4830450220487fb382c4974de3f7d834c1b617fe15860828c7f96454490edd6d891556dcc9022100baf95feb48f845d5bfc9882eb6aeefa1bc3790e39f59eaa46ff7f15ae626c53e01ffffffff0101000000000000000000000000", "P2SH,WITNESS"],
|
||||||
["BIP143: correct sighash (without FindAndDelete) = 71c9cd9b2869b9c70b01b1f0360c148f42dee72297db312638df136f43311f23"],
|
["BIP143: correct sighash (without FindAndDelete) = 71c9cd9b2869b9c70b01b1f0360c148f42dee72297db312638df136f43311f23"],
|
||||||
[[["f18783ace138abac5d3a7a5cf08e88fe6912f267ef936452e0c27d090621c169", 7500, "0x00 0x20 0x9e1be07558ea5cc8e02ed1d80c0911048afad949affa36d5c3951e3159dbea19", 200000]],
|
[[["f18783ace138abac5d3a7a5cf08e88fe6912f267ef936452e0c27d090621c169", 7500, "0x00 0x20 0x9e1be07558ea5cc8e02ed1d80c0911048afad949affa36d5c3951e3159dbea19", 200000]],
|
||||||
"0100000000010169c12106097dc2e0526493ef67f21269fe888ef05c7a3a5dacab38e1ac8387f14c1d000000ffffffff01010000000000000000034830450220487fb382c4974de3f7d834c1b617fe15860828c7f96454490edd6d891556dcc9022100baf95feb48f845d5bfc9882eb6aeefa1bc3790e39f59eaa46ff7f15ae626c53e012102a9781d66b61fb5a7ef00ac5ad5bc6ffc78be7b44a566e3c87870e1079368df4c4aad4830450220487fb382c4974de3f7d834c1b617fe15860828c7f96454490edd6d891556dcc9022100baf95feb48f845d5bfc9882eb6aeefa1bc3790e39f59eaa46ff7f15ae626c53e0100000000", "P2SH,WITNESS"],
|
"0100000000010169c12106097dc2e0526493ef67f21269fe888ef05c7a3a5dacab38e1ac8387f14c1d000000ffffffff01010000000000000000034830450220487fb382c4974de3f7d834c1b617fe15860828c7f96454490edd6d891556dcc9022100baf95feb48f845d5bfc9882eb6aeefa1bc3790e39f59eaa46ff7f15ae626c53e012102a9781d66b61fb5a7ef00ac5ad5bc6ffc78be7b44a566e3c87870e1079368df4c4aad4830450220487fb382c4974de3f7d834c1b617fe15860828c7f96454490edd6d891556dcc9022100baf95feb48f845d5bfc9882eb6aeefa1bc3790e39f59eaa46ff7f15ae626c53e0100000000", "P2SH,WITNESS,CONST_SCRIPTCODE"],
|
||||||
["This is multisig version of the FindAndDelete tests"],
|
["This is multisig version of the FindAndDelete tests"],
|
||||||
["Script is 2 CHECKMULTISIGVERIFY <sig1> <sig2> DROP"],
|
["Script is 2 CHECKMULTISIGVERIFY <sig1> <sig2> DROP"],
|
||||||
["52af4830450220487fb382c4974de3f7d834c1b617fe15860828c7f96454490edd6d891556dcc9022100baf95feb48f845d5bfc9882eb6aeefa1bc3790e39f59eaa46ff7f15ae626c53e0148304502205286f726690b2e9b0207f0345711e63fa7012045b9eb0f19c2458ce1db90cf43022100e89f17f86abc5b149eba4115d4f128bcf45d77fb3ecdd34f594091340c0395960175"],
|
["52af4830450220487fb382c4974de3f7d834c1b617fe15860828c7f96454490edd6d891556dcc9022100baf95feb48f845d5bfc9882eb6aeefa1bc3790e39f59eaa46ff7f15ae626c53e0148304502205286f726690b2e9b0207f0345711e63fa7012045b9eb0f19c2458ce1db90cf43022100e89f17f86abc5b149eba4115d4f128bcf45d77fb3ecdd34f594091340c0395960175"],
|
||||||
@ -508,7 +508,9 @@
|
|||||||
"01000000019275cb8d4a485ce95741c013f7c0d28722160008021bb469a11982d47a662896581b0000fd6f01004830450220487fb382c4974de3f7d834c1b617fe15860828c7f96454490edd6d891556dcc9022100baf95feb48f845d5bfc9882eb6aeefa1bc3790e39f59eaa46ff7f15ae626c53e0148304502205286f726690b2e9b0207f0345711e63fa7012045b9eb0f19c2458ce1db90cf43022100e89f17f86abc5b149eba4115d4f128bcf45d77fb3ecdd34f594091340c03959601522102cd74a2809ffeeed0092bc124fd79836706e41f048db3f6ae9df8708cefb83a1c2102e615999372426e46fd107b76eaf007156a507584aa2cc21de9eee3bdbd26d36c4c9552af4830450220487fb382c4974de3f7d834c1b617fe15860828c7f96454490edd6d891556dcc9022100baf95feb48f845d5bfc9882eb6aeefa1bc3790e39f59eaa46ff7f15ae626c53e0148304502205286f726690b2e9b0207f0345711e63fa7012045b9eb0f19c2458ce1db90cf43022100e89f17f86abc5b149eba4115d4f128bcf45d77fb3ecdd34f594091340c0395960175ffffffff0101000000000000000000000000", "P2SH,WITNESS"],
|
"01000000019275cb8d4a485ce95741c013f7c0d28722160008021bb469a11982d47a662896581b0000fd6f01004830450220487fb382c4974de3f7d834c1b617fe15860828c7f96454490edd6d891556dcc9022100baf95feb48f845d5bfc9882eb6aeefa1bc3790e39f59eaa46ff7f15ae626c53e0148304502205286f726690b2e9b0207f0345711e63fa7012045b9eb0f19c2458ce1db90cf43022100e89f17f86abc5b149eba4115d4f128bcf45d77fb3ecdd34f594091340c03959601522102cd74a2809ffeeed0092bc124fd79836706e41f048db3f6ae9df8708cefb83a1c2102e615999372426e46fd107b76eaf007156a507584aa2cc21de9eee3bdbd26d36c4c9552af4830450220487fb382c4974de3f7d834c1b617fe15860828c7f96454490edd6d891556dcc9022100baf95feb48f845d5bfc9882eb6aeefa1bc3790e39f59eaa46ff7f15ae626c53e0148304502205286f726690b2e9b0207f0345711e63fa7012045b9eb0f19c2458ce1db90cf43022100e89f17f86abc5b149eba4115d4f128bcf45d77fb3ecdd34f594091340c0395960175ffffffff0101000000000000000000000000", "P2SH,WITNESS"],
|
||||||
["BIP143: correct sighash (without FindAndDelete) = c1628a1e7c67f14ca0c27c06e4fdeec2e6d1a73c7a91d7c046ff83e835aebb72"],
|
["BIP143: correct sighash (without FindAndDelete) = c1628a1e7c67f14ca0c27c06e4fdeec2e6d1a73c7a91d7c046ff83e835aebb72"],
|
||||||
[[["9628667ad48219a169b41b020800162287d2c0f713c04157e95c484a8dcb7592", 7500, "0x00 0x20 0x9b66c15b4e0b4eb49fa877982cafded24859fe5b0e2dbfbe4f0df1de7743fd52", 200000]],
|
[[["9628667ad48219a169b41b020800162287d2c0f713c04157e95c484a8dcb7592", 7500, "0x00 0x20 0x9b66c15b4e0b4eb49fa877982cafded24859fe5b0e2dbfbe4f0df1de7743fd52", 200000]],
|
||||||
"010000000001019275cb8d4a485ce95741c013f7c0d28722160008021bb469a11982d47a6628964c1d000000ffffffff0101000000000000000007004830450220487fb382c4974de3f7d834c1b617fe15860828c7f96454490edd6d891556dcc9022100baf95feb48f845d5bfc9882eb6aeefa1bc3790e39f59eaa46ff7f15ae626c53e0148304502205286f726690b2e9b0207f0345711e63fa7012045b9eb0f19c2458ce1db90cf43022100e89f17f86abc5b149eba4115d4f128bcf45d77fb3ecdd34f594091340c0395960101022102966f109c54e85d3aee8321301136cedeb9fc710fdef58a9de8a73942f8e567c021034ffc99dd9a79dd3cb31e2ab3e0b09e0e67db41ac068c625cd1f491576016c84e9552af4830450220487fb382c4974de3f7d834c1b617fe15860828c7f96454490edd6d891556dcc9022100baf95feb48f845d5bfc9882eb6aeefa1bc3790e39f59eaa46ff7f15ae626c53e0148304502205286f726690b2e9b0207f0345711e63fa7012045b9eb0f19c2458ce1db90cf43022100e89f17f86abc5b149eba4115d4f128bcf45d77fb3ecdd34f594091340c039596017500000000", "P2SH,WITNESS"],
|
"010000000001019275cb8d4a485ce95741c013f7c0d28722160008021bb469a11982d47a6628964c1d000000ffffffff0101000000000000000007004830450220487fb382c4974de3f7d834c1b617fe15860828c7f96454490edd6d891556dcc9022100baf95feb48f845d5bfc9882eb6aeefa1bc3790e39f59eaa46ff7f15ae626c53e0148304502205286f726690b2e9b0207f0345711e63fa7012045b9eb0f19c2458ce1db90cf43022100e89f17f86abc5b149eba4115d4f128bcf45d77fb3ecdd34f594091340c0395960101022102966f109c54e85d3aee8321301136cedeb9fc710fdef58a9de8a73942f8e567c021034ffc99dd9a79dd3cb31e2ab3e0b09e0e67db41ac068c625cd1f491576016c84e9552af4830450220487fb382c4974de3f7d834c1b617fe15860828c7f96454490edd6d891556dcc9022100baf95feb48f845d5bfc9882eb6aeefa1bc3790e39f59eaa46ff7f15ae626c53e0148304502205286f726690b2e9b0207f0345711e63fa7012045b9eb0f19c2458ce1db90cf43022100e89f17f86abc5b149eba4115d4f128bcf45d77fb3ecdd34f594091340c039596017500000000", "P2SH,WITNESS,CONST_SCRIPTCODE"],
|
||||||
|
[[["7a554c397846f025738965683b8448d79458c54b869f6391ece95145c962e65f", 0, "OP_HASH160 0x149512447916448e4193c321f2d599dff2538973f3 OP_EQUAL", 0]],
|
||||||
|
"02000000015fe662c94551e9ec91639f864bc55894d748843b6865897325f04678394c557a0000000039093006020101020101012103f0665be3ccc59a592608790e84bcf117349fc76c77d06cd3fb323548c310ff340cad0a09300602010102010101ffffffff010000000000000000015100000000", "CHECKLOCKTIMEVERIFY,CHECKSEQUENCEVERIFY,CLEANSTACK,DERSIG,DISCOURAGE_UPGRADABLE_NOPS,LOW_S,MINIMALDATA,NULLDUMMY,NULLFAIL,P2SH,SIGPUSHONLY,STRICTENC,WITNESS,DISCOURAGE_UPGRADABLE_WITNESS_PROGRAM,MINIMALIF,WITNESS_PUBKEYTYPE,TAPROOT"],
|
||||||
|
|
||||||
["Make diffs cleaner by leaving a comment here without comma at the end"]
|
["Make diffs cleaner by leaving a comment here without comma at the end"]
|
||||||
]
|
]
|
||||||
|
@ -114,6 +114,10 @@ const (
|
|||||||
// ScriptVerifyDiscourageUpgradeablePubkeyType defines if unknown
|
// ScriptVerifyDiscourageUpgradeablePubkeyType defines if unknown
|
||||||
// public key versions (during tapscript execution) is non-standard.
|
// public key versions (during tapscript execution) is non-standard.
|
||||||
ScriptVerifyDiscourageUpgradeablePubkeyType
|
ScriptVerifyDiscourageUpgradeablePubkeyType
|
||||||
|
|
||||||
|
// ScriptVerifyConstScriptCode fails non-segwit scripts if a signature
|
||||||
|
// match is found in the script code or if OP_CODESEPARATOR is used.
|
||||||
|
ScriptVerifyConstScriptCode
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
@ -408,6 +408,14 @@ const (
|
|||||||
// is exceeded during taproot execution.
|
// is exceeded during taproot execution.
|
||||||
ErrTaprootMaxSigOps
|
ErrTaprootMaxSigOps
|
||||||
|
|
||||||
|
// ErrNonConstScriptCode is returned when a signature match is found when
|
||||||
|
// calling removeOpcodeByData in a non-segwit script.
|
||||||
|
ErrNonConstScriptCode
|
||||||
|
|
||||||
|
// ErrCodeSeparator is returned when OP_CODESEPARATOR is used in a
|
||||||
|
// non-segwit script.
|
||||||
|
ErrCodeSeparator
|
||||||
|
|
||||||
// numErrorCodes is the maximum error code number used in tests. This
|
// numErrorCodes is the maximum error code number used in tests. This
|
||||||
// entry MUST be the last entry in the enum.
|
// entry MUST be the last entry in the enum.
|
||||||
numErrorCodes
|
numErrorCodes
|
||||||
@ -494,6 +502,8 @@ var errorCodeStrings = map[ErrorCode]string{
|
|||||||
ErrInvalidTaprootSigLen: "ErrInvalidTaprootSigLen",
|
ErrInvalidTaprootSigLen: "ErrInvalidTaprootSigLen",
|
||||||
ErrTaprootPubkeyIsEmpty: "ErrTaprootPubkeyIsEmpty",
|
ErrTaprootPubkeyIsEmpty: "ErrTaprootPubkeyIsEmpty",
|
||||||
ErrTaprootMaxSigOps: "ErrTaprootMaxSigOps",
|
ErrTaprootMaxSigOps: "ErrTaprootMaxSigOps",
|
||||||
|
ErrNonConstScriptCode: "ErrNonConstScriptCode",
|
||||||
|
ErrCodeSeparator: "ErrCodeSeparator",
|
||||||
}
|
}
|
||||||
|
|
||||||
// String returns the ErrorCode as a human-readable name.
|
// String returns the ErrorCode as a human-readable name.
|
||||||
|
@ -96,6 +96,8 @@ func TestErrorCodeStringer(t *testing.T) {
|
|||||||
{ErrInvalidTaprootSigLen, "ErrInvalidTaprootSigLen"},
|
{ErrInvalidTaprootSigLen, "ErrInvalidTaprootSigLen"},
|
||||||
{ErrTaprootPubkeyIsEmpty, "ErrTaprootPubkeyIsEmpty"},
|
{ErrTaprootPubkeyIsEmpty, "ErrTaprootPubkeyIsEmpty"},
|
||||||
{ErrTaprootMaxSigOps, "ErrTaprootMaxSigOps"},
|
{ErrTaprootMaxSigOps, "ErrTaprootMaxSigOps"},
|
||||||
|
{ErrNonConstScriptCode, "ErrNonConstScriptCode"},
|
||||||
|
{ErrCodeSeparator, "ErrCodeSeparator"},
|
||||||
{0xffff, "Unknown ErrorCode (65535)"},
|
{0xffff, "Unknown ErrorCode (65535)"},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1953,6 +1953,12 @@ func opcodeCodeSeparator(op *opcode, data []byte, vm *Engine) error {
|
|||||||
|
|
||||||
if vm.taprootCtx != nil {
|
if vm.taprootCtx != nil {
|
||||||
vm.taprootCtx.codeSepPos = uint32(vm.tokenizer.OpcodePosition())
|
vm.taprootCtx.codeSepPos = uint32(vm.tokenizer.OpcodePosition())
|
||||||
|
} else if vm.witnessProgram == nil &&
|
||||||
|
vm.hasFlag(ScriptVerifyConstScriptCode) {
|
||||||
|
|
||||||
|
// Disable OP_CODESEPARATOR for non-segwit scripts.
|
||||||
|
str := "OP_CODESEPARATOR used in non-segwit script"
|
||||||
|
return scriptError(ErrCodeSeparator, str)
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
@ -2073,7 +2079,13 @@ func opcodeCheckSig(op *opcode, data []byte, vm *Engine) error {
|
|||||||
// TODO(roasbeef): return an error?
|
// TODO(roasbeef): return an error?
|
||||||
}
|
}
|
||||||
|
|
||||||
valid := sigVerifier.Verify()
|
result := sigVerifier.Verify()
|
||||||
|
valid := result.sigValid
|
||||||
|
|
||||||
|
if vm.hasFlag(ScriptVerifyConstScriptCode) && result.sigMatch {
|
||||||
|
str := "non-const script code"
|
||||||
|
return scriptError(ErrNonConstScriptCode, str)
|
||||||
|
}
|
||||||
|
|
||||||
switch {
|
switch {
|
||||||
// For tapscript, and prior execution with null fail active, if the
|
// For tapscript, and prior execution with null fail active, if the
|
||||||
@ -2166,11 +2178,11 @@ func opcodeCheckSigAdd(op *opcode, data []byte, vm *Engine) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
valid := sigVerifier.Verify()
|
result := sigVerifier.Verify()
|
||||||
|
|
||||||
// If the signature is invalid, this we fail execution, as it should
|
// If the signature is invalid, this we fail execution, as it should
|
||||||
// have been an empty signature.
|
// have been an empty signature.
|
||||||
if !valid {
|
if !result.sigValid {
|
||||||
str := "signature not empty on failed checksig"
|
str := "signature not empty on failed checksig"
|
||||||
return scriptError(ErrNullFail, str)
|
return scriptError(ErrNullFail, str)
|
||||||
}
|
}
|
||||||
@ -2303,7 +2315,13 @@ func opcodeCheckMultiSig(op *opcode, data []byte, vm *Engine) error {
|
|||||||
// no way for a signature to sign itself.
|
// no way for a signature to sign itself.
|
||||||
if !vm.isWitnessVersionActive(0) {
|
if !vm.isWitnessVersionActive(0) {
|
||||||
for _, sigInfo := range signatures {
|
for _, sigInfo := range signatures {
|
||||||
script = removeOpcodeByData(script, sigInfo.signature)
|
var match bool
|
||||||
|
script, match = removeOpcodeByData(script, sigInfo.signature)
|
||||||
|
if vm.hasFlag(ScriptVerifyConstScriptCode) && match {
|
||||||
|
str := fmt.Sprintf("got match of %v in %v", sigInfo.signature,
|
||||||
|
script)
|
||||||
|
return scriptError(ErrNonConstScriptCode, str)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -196,6 +196,8 @@ func parseScriptFlags(flagStr string) (ScriptFlags, error) {
|
|||||||
flags |= ScriptVerifyWitnessPubKeyType
|
flags |= ScriptVerifyWitnessPubKeyType
|
||||||
case "TAPROOT":
|
case "TAPROOT":
|
||||||
flags |= ScriptVerifyTaproot
|
flags |= ScriptVerifyTaproot
|
||||||
|
case "CONST_SCRIPTCODE":
|
||||||
|
flags |= ScriptVerifyConstScriptCode
|
||||||
default:
|
default:
|
||||||
return flags, fmt.Errorf("invalid flag: %s", flag)
|
return flags, fmt.Errorf("invalid flag: %s", flag)
|
||||||
}
|
}
|
||||||
|
@ -255,10 +255,10 @@ func isCanonicalPush(opcode byte, data []byte) bool {
|
|||||||
// NOTE: This function is only valid for version 0 scripts. Since the function
|
// NOTE: This function is only valid for version 0 scripts. Since the function
|
||||||
// does not accept a script version, the results are undefined for other script
|
// does not accept a script version, the results are undefined for other script
|
||||||
// versions.
|
// versions.
|
||||||
func removeOpcodeByData(script []byte, dataToRemove []byte) []byte {
|
func removeOpcodeByData(script []byte, dataToRemove []byte) ([]byte, bool) {
|
||||||
// Avoid work when possible.
|
// Avoid work when possible.
|
||||||
if len(script) == 0 || len(dataToRemove) == 0 {
|
if len(script) == 0 || len(dataToRemove) == 0 {
|
||||||
return script
|
return script, false
|
||||||
}
|
}
|
||||||
|
|
||||||
// Parse through the script looking for a canonical data push that contains
|
// Parse through the script looking for a canonical data push that contains
|
||||||
@ -266,8 +266,28 @@ func removeOpcodeByData(script []byte, dataToRemove []byte) []byte {
|
|||||||
const scriptVersion = 0
|
const scriptVersion = 0
|
||||||
var result []byte
|
var result []byte
|
||||||
var prevOffset int32
|
var prevOffset int32
|
||||||
|
var match bool
|
||||||
tokenizer := MakeScriptTokenizer(scriptVersion, script)
|
tokenizer := MakeScriptTokenizer(scriptVersion, script)
|
||||||
for tokenizer.Next() {
|
for tokenizer.Next() {
|
||||||
|
var found bool
|
||||||
|
result, prevOffset, found = removeOpcodeCanonical(
|
||||||
|
&tokenizer, script, dataToRemove, prevOffset, result,
|
||||||
|
)
|
||||||
|
if found {
|
||||||
|
match = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if result == nil {
|
||||||
|
result = script
|
||||||
|
}
|
||||||
|
return result, match
|
||||||
|
}
|
||||||
|
|
||||||
|
func removeOpcodeCanonical(t *ScriptTokenizer, script, dataToRemove []byte,
|
||||||
|
prevOffset int32, result []byte) ([]byte, int32, bool) {
|
||||||
|
|
||||||
|
var found bool
|
||||||
|
|
||||||
// In practice, the script will basically never actually contain the
|
// In practice, the script will basically never actually contain the
|
||||||
// data since this function is only used during signature verification
|
// data since this function is only used during signature verification
|
||||||
// to remove the signature itself which would require some incredibly
|
// to remove the signature itself which would require some incredibly
|
||||||
@ -275,23 +295,19 @@ func removeOpcodeByData(script []byte, dataToRemove []byte) []byte {
|
|||||||
//
|
//
|
||||||
// Thus, as an optimization, avoid allocating a new script unless there
|
// Thus, as an optimization, avoid allocating a new script unless there
|
||||||
// is actually a match that needs to be removed.
|
// is actually a match that needs to be removed.
|
||||||
op, data := tokenizer.Opcode(), tokenizer.Data()
|
op, data := t.Opcode(), t.Data()
|
||||||
if isCanonicalPush(op, data) && bytes.Contains(data, dataToRemove) {
|
if isCanonicalPush(op, data) && bytes.Equal(data, dataToRemove) {
|
||||||
if result == nil {
|
if result == nil {
|
||||||
fullPushLen := tokenizer.ByteIndex() - prevOffset
|
fullPushLen := t.ByteIndex() - prevOffset
|
||||||
result = make([]byte, 0, int32(len(script))-fullPushLen)
|
result = make([]byte, 0, int32(len(script))-fullPushLen)
|
||||||
result = append(result, script[0:prevOffset]...)
|
result = append(result, script[0:prevOffset]...)
|
||||||
}
|
}
|
||||||
|
found = true
|
||||||
} else if result != nil {
|
} else if result != nil {
|
||||||
result = append(result, script[prevOffset:tokenizer.ByteIndex()]...)
|
result = append(result, script[prevOffset:t.ByteIndex()]...)
|
||||||
}
|
}
|
||||||
|
|
||||||
prevOffset = tokenizer.ByteIndex()
|
return result, t.ByteIndex(), found
|
||||||
}
|
|
||||||
if result == nil {
|
|
||||||
result = script
|
|
||||||
}
|
|
||||||
return result
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// AsSmallInt returns the passed opcode, which must be true according to
|
// AsSmallInt returns the passed opcode, which must be true according to
|
||||||
|
@ -357,6 +357,12 @@ func TestRemoveOpcodeByData(t *testing.T) {
|
|||||||
remove: []byte{1, 2, 3, 4},
|
remove: []byte{1, 2, 3, 4},
|
||||||
after: []byte{OP_NOP},
|
after: []byte{OP_NOP},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: "",
|
||||||
|
before: []byte{OP_NOP, OP_DATA_8, 1, 2, 3, 4, 5, 6, 7, 8, OP_DATA_4, 1, 2, 3, 4},
|
||||||
|
remove: []byte{1, 2, 3, 4},
|
||||||
|
after: []byte{OP_NOP, OP_DATA_8, 1, 2, 3, 4, 5, 6, 7, 8},
|
||||||
|
},
|
||||||
{
|
{
|
||||||
name: "simple case",
|
name: "simple case",
|
||||||
before: []byte{OP_DATA_4, 1, 2, 3, 4},
|
before: []byte{OP_DATA_4, 1, 2, 3, 4},
|
||||||
@ -376,7 +382,9 @@ func TestRemoveOpcodeByData(t *testing.T) {
|
|||||||
bytes.Repeat([]byte{0}, 72)...),
|
bytes.Repeat([]byte{0}, 72)...),
|
||||||
[]byte{1, 2, 3, 4}...),
|
[]byte{1, 2, 3, 4}...),
|
||||||
remove: []byte{1, 2, 3, 4},
|
remove: []byte{1, 2, 3, 4},
|
||||||
after: nil,
|
after: append(append([]byte{OP_PUSHDATA1, 76},
|
||||||
|
bytes.Repeat([]byte{0}, 72)...),
|
||||||
|
[]byte{1, 2, 3, 4}...),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "simple case (pushdata1 miss)",
|
name: "simple case (pushdata1 miss)",
|
||||||
@ -400,7 +408,9 @@ func TestRemoveOpcodeByData(t *testing.T) {
|
|||||||
bytes.Repeat([]byte{0}, 252)...),
|
bytes.Repeat([]byte{0}, 252)...),
|
||||||
[]byte{1, 2, 3, 4}...),
|
[]byte{1, 2, 3, 4}...),
|
||||||
remove: []byte{1, 2, 3, 4},
|
remove: []byte{1, 2, 3, 4},
|
||||||
after: nil,
|
after: append(append([]byte{OP_PUSHDATA2, 0, 1},
|
||||||
|
bytes.Repeat([]byte{0}, 252)...),
|
||||||
|
[]byte{1, 2, 3, 4}...),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "simple case (pushdata2 miss)",
|
name: "simple case (pushdata2 miss)",
|
||||||
@ -425,7 +435,9 @@ func TestRemoveOpcodeByData(t *testing.T) {
|
|||||||
bytes.Repeat([]byte{0}, 65532)...),
|
bytes.Repeat([]byte{0}, 65532)...),
|
||||||
[]byte{1, 2, 3, 4}...),
|
[]byte{1, 2, 3, 4}...),
|
||||||
remove: []byte{1, 2, 3, 4},
|
remove: []byte{1, 2, 3, 4},
|
||||||
after: nil,
|
after: append(append([]byte{OP_PUSHDATA4, 0, 0, 1, 0},
|
||||||
|
bytes.Repeat([]byte{0}, 65532)...),
|
||||||
|
[]byte{1, 2, 3, 4}...),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "simple case (pushdata4 miss noncanonical)",
|
name: "simple case (pushdata4 miss noncanonical)",
|
||||||
@ -465,16 +477,17 @@ func TestRemoveOpcodeByData(t *testing.T) {
|
|||||||
// tstRemoveOpcodeByData is a convenience function to ensure the provided
|
// tstRemoveOpcodeByData is a convenience function to ensure the provided
|
||||||
// script parses before attempting to remove the passed data.
|
// script parses before attempting to remove the passed data.
|
||||||
const scriptVersion = 0
|
const scriptVersion = 0
|
||||||
tstRemoveOpcodeByData := func(script []byte, data []byte) ([]byte, error) {
|
tstRemoveOpcodeByData := func(script []byte, data []byte) ([]byte, bool, error) {
|
||||||
if err := checkScriptParses(scriptVersion, script); err != nil {
|
if err := checkScriptParses(scriptVersion, script); err != nil {
|
||||||
return nil, err
|
return nil, false, err
|
||||||
}
|
}
|
||||||
|
|
||||||
return removeOpcodeByData(script, data), nil
|
result, match := removeOpcodeByData(script, data)
|
||||||
|
return result, match, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, test := range tests {
|
for _, test := range tests {
|
||||||
result, err := tstRemoveOpcodeByData(test.before, test.remove)
|
result, _, err := tstRemoveOpcodeByData(test.before, test.remove)
|
||||||
if e := tstCheckScriptError(err, test.err); e != nil {
|
if e := tstCheckScriptError(err, test.err); e != nil {
|
||||||
t.Errorf("%s: %v", test.name, e)
|
t.Errorf("%s: %v", test.name, e)
|
||||||
continue
|
continue
|
||||||
|
@ -20,9 +20,14 @@ import (
|
|||||||
// pre-segwit, segwit v0, segwit v1 (taproot key spend validation), and the
|
// pre-segwit, segwit v0, segwit v1 (taproot key spend validation), and the
|
||||||
// base tapscript verification.
|
// base tapscript verification.
|
||||||
type signatureVerifier interface {
|
type signatureVerifier interface {
|
||||||
// Verify returns true if the signature verifier context deems the
|
// Verify returns whether or not the signature verifier context deems the
|
||||||
// signature to be valid for the given context.
|
// signature to be valid for the given context.
|
||||||
Verify() bool
|
Verify() verifyResult
|
||||||
|
}
|
||||||
|
|
||||||
|
type verifyResult struct {
|
||||||
|
sigValid bool
|
||||||
|
sigMatch bool
|
||||||
}
|
}
|
||||||
|
|
||||||
// baseSigVerifier is used to verify signatures for the _base_ system, meaning
|
// baseSigVerifier is used to verify signatures for the _base_ system, meaning
|
||||||
@ -147,20 +152,23 @@ func (b *baseSigVerifier) verifySig(sigHash []byte) bool {
|
|||||||
return valid
|
return valid
|
||||||
}
|
}
|
||||||
|
|
||||||
// Verify returns true if the signature verifier context deems the signature to
|
// Verify returns whether or not the signature verifier context deems the
|
||||||
// be valid for the given context.
|
// signature to be valid for the given context.
|
||||||
//
|
//
|
||||||
// NOTE: This is part of the baseSigVerifier interface.
|
// NOTE: This is part of the baseSigVerifier interface.
|
||||||
func (b *baseSigVerifier) Verify() bool {
|
func (b *baseSigVerifier) Verify() verifyResult {
|
||||||
// Remove the signature since there is no way for a signature
|
// Remove the signature since there is no way for a signature
|
||||||
// to sign itself.
|
// to sign itself.
|
||||||
subScript := removeOpcodeByData(b.subScript, b.fullSigBytes)
|
subScript, match := removeOpcodeByData(b.subScript, b.fullSigBytes)
|
||||||
|
|
||||||
sigHash := calcSignatureHash(
|
sigHash := calcSignatureHash(
|
||||||
subScript, b.hashType, &b.vm.tx, b.vm.txIdx,
|
subScript, b.hashType, &b.vm.tx, b.vm.txIdx,
|
||||||
)
|
)
|
||||||
|
|
||||||
return b.verifySig(sigHash)
|
return verifyResult{
|
||||||
|
sigValid: b.verifySig(sigHash),
|
||||||
|
sigMatch: match,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// A compile-time assertion to ensure baseSigVerifier implements the
|
// A compile-time assertion to ensure baseSigVerifier implements the
|
||||||
@ -192,7 +200,7 @@ func newBaseSegwitSigVerifier(pkBytes, fullSigBytes []byte,
|
|||||||
// be valid for the given context.
|
// be valid for the given context.
|
||||||
//
|
//
|
||||||
// NOTE: This is part of the baseSigVerifier interface.
|
// NOTE: This is part of the baseSigVerifier interface.
|
||||||
func (s *baseSegwitSigVerifier) Verify() bool {
|
func (s *baseSegwitSigVerifier) Verify() verifyResult {
|
||||||
var sigHashes *TxSigHashes
|
var sigHashes *TxSigHashes
|
||||||
if s.vm.hashCache != nil {
|
if s.vm.hashCache != nil {
|
||||||
sigHashes = s.vm.hashCache
|
sigHashes = s.vm.hashCache
|
||||||
@ -208,10 +216,12 @@ func (s *baseSegwitSigVerifier) Verify() bool {
|
|||||||
// TODO(roasbeef): this doesn't need to return an error, should
|
// TODO(roasbeef): this doesn't need to return an error, should
|
||||||
// instead be further up the stack? this only returns an error
|
// instead be further up the stack? this only returns an error
|
||||||
// if the input index is greater than the number of inputs
|
// if the input index is greater than the number of inputs
|
||||||
return false
|
return verifyResult{}
|
||||||
}
|
}
|
||||||
|
|
||||||
return s.verifySig(sigHash)
|
return verifyResult{
|
||||||
|
sigValid: s.verifySig(sigHash),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// A compile-time assertion to ensure baseSegwitSigVerifier implements the
|
// A compile-time assertion to ensure baseSegwitSigVerifier implements the
|
||||||
@ -356,11 +366,11 @@ func (t *taprootSigVerifier) verifySig(sigHash []byte) bool {
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
// Verify returns true if the signature verifier context deems the signature to
|
// Verify returns whether or not the signature verifier context deems the
|
||||||
// be valid for the given context.
|
// signature to be valid for the given context.
|
||||||
//
|
//
|
||||||
// NOTE: This is part of the baseSigVerifier interface.
|
// NOTE: This is part of the baseSigVerifier interface.
|
||||||
func (t *taprootSigVerifier) Verify() bool {
|
func (t *taprootSigVerifier) Verify() verifyResult {
|
||||||
var opts []TaprootSigHashOption
|
var opts []TaprootSigHashOption
|
||||||
if t.annex != nil {
|
if t.annex != nil {
|
||||||
opts = append(opts, WithAnnex(t.annex))
|
opts = append(opts, WithAnnex(t.annex))
|
||||||
@ -374,10 +384,12 @@ func (t *taprootSigVerifier) Verify() bool {
|
|||||||
)
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
// TODO(roasbeef): propagate the error here?
|
// TODO(roasbeef): propagate the error here?
|
||||||
return false
|
return verifyResult{}
|
||||||
}
|
}
|
||||||
|
|
||||||
return t.verifySig(sigHash)
|
return verifyResult{
|
||||||
|
sigValid: t.verifySig(sigHash),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// A compile-time assertion to ensure taprootSigVerifier implements the
|
// A compile-time assertion to ensure taprootSigVerifier implements the
|
||||||
@ -439,16 +451,18 @@ func newBaseTapscriptSigVerifier(pkBytes, rawSig []byte,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Verify returns true if the signature verifier context deems the signature to
|
// Verify returns whether or not the signature verifier context deems the
|
||||||
// be valid for the given context.
|
// signature to be valid for the given context.
|
||||||
//
|
//
|
||||||
// NOTE: This is part of the baseSigVerifier interface.
|
// NOTE: This is part of the baseSigVerifier interface.
|
||||||
func (b *baseTapscriptSigVerifier) Verify() bool {
|
func (b *baseTapscriptSigVerifier) Verify() verifyResult {
|
||||||
// If the public key is blank, then that means it wasn't 0 or 32 bytes,
|
// If the public key is blank, then that means it wasn't 0 or 32 bytes,
|
||||||
// so we'll treat this as an unknown public key version and return
|
// so we'll treat this as an unknown public key version and return
|
||||||
// true.
|
// that it's valid.
|
||||||
if b.pubKey == nil {
|
if b.pubKey == nil {
|
||||||
return true
|
return verifyResult{
|
||||||
|
sigValid: true,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var opts []TaprootSigHashOption
|
var opts []TaprootSigHashOption
|
||||||
@ -468,10 +482,12 @@ func (b *baseTapscriptSigVerifier) Verify() bool {
|
|||||||
)
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
// TODO(roasbeef): propagate the error here?
|
// TODO(roasbeef): propagate the error here?
|
||||||
return false
|
return verifyResult{}
|
||||||
}
|
}
|
||||||
|
|
||||||
return b.verifySig(sigHash)
|
return verifyResult{
|
||||||
|
sigValid: b.verifySig(sigHash),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// A compile-time assertion to ensure baseTapscriptSigVerifier implements the
|
// A compile-time assertion to ensure baseTapscriptSigVerifier implements the
|
||||||
|
@ -46,7 +46,8 @@ const (
|
|||||||
ScriptVerifyTaproot |
|
ScriptVerifyTaproot |
|
||||||
ScriptVerifyDiscourageUpgradeableTaprootVersion |
|
ScriptVerifyDiscourageUpgradeableTaprootVersion |
|
||||||
ScriptVerifyDiscourageOpSuccess |
|
ScriptVerifyDiscourageOpSuccess |
|
||||||
ScriptVerifyDiscourageUpgradeablePubkeyType
|
ScriptVerifyDiscourageUpgradeablePubkeyType |
|
||||||
|
ScriptVerifyConstScriptCode
|
||||||
)
|
)
|
||||||
|
|
||||||
// ScriptClass is an enumeration for the list of standard types of script.
|
// ScriptClass is an enumeration for the list of standard types of script.
|
||||||
|
@ -84,8 +84,8 @@ func VerifyTaprootKeySpend(witnessProgram []byte, rawSig []byte, tx *wire.MsgTx,
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
valid := keySpendVerifier.Verify()
|
result := keySpendVerifier.Verify()
|
||||||
if valid {
|
if result.sigValid {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -112,6 +112,14 @@ const (
|
|||||||
maxWitnessItemSize = 4_000_000
|
maxWitnessItemSize = 4_000_000
|
||||||
)
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
// errSuperfluousWitnessRecord is returned during tx deserialization when
|
||||||
|
// a tx has the witness marker flag set but has no witnesses.
|
||||||
|
errSuperfluousWitnessRecord = fmt.Errorf(
|
||||||
|
"witness flag set but tx has no witnesses",
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
// TxFlagMarker is the first byte of the FLAG field in a bitcoin tx
|
// TxFlagMarker is the first byte of the FLAG field in a bitcoin tx
|
||||||
// message. It allows decoders to distinguish a regular serialized
|
// message. It allows decoders to distinguish a regular serialized
|
||||||
// transaction from one that would require a different parsing logic.
|
// transaction from one that would require a different parsing logic.
|
||||||
@ -601,8 +609,7 @@ func (msg *MsgTx) btcDecode(r io.Reader, pver uint32, enc MessageEncoding,
|
|||||||
txin.Witness = make([][]byte, witCount)
|
txin.Witness = make([][]byte, witCount)
|
||||||
for j := uint64(0); j < witCount; j++ {
|
for j := uint64(0); j < witCount; j++ {
|
||||||
txin.Witness[j], err = readScriptBuf(
|
txin.Witness[j], err = readScriptBuf(
|
||||||
r, pver, buf, sbuf, maxWitnessItemSize,
|
r, pver, buf, sbuf, "script witness item",
|
||||||
"script witness item",
|
|
||||||
)
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@ -611,6 +618,12 @@ func (msg *MsgTx) btcDecode(r io.Reader, pver uint32, enc MessageEncoding,
|
|||||||
sbuf = sbuf[len(txin.Witness[j]):]
|
sbuf = sbuf[len(txin.Witness[j]):]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Check that if the witness flag is set that we actually have
|
||||||
|
// witnesses. This check is also done by bitcoind.
|
||||||
|
if !msg.HasWitness() {
|
||||||
|
return errSuperfluousWitnessRecord
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if _, err := io.ReadFull(r, buf[:4]); err != nil {
|
if _, err := io.ReadFull(r, buf[:4]); err != nil {
|
||||||
@ -1004,7 +1017,7 @@ func writeOutPointBuf(w io.Writer, pver uint32, version int32, op *OutPoint,
|
|||||||
//
|
//
|
||||||
// NOTE: b MUST either be nil or at least an 8-byte slice.
|
// NOTE: b MUST either be nil or at least an 8-byte slice.
|
||||||
func readScriptBuf(r io.Reader, pver uint32, buf, s []byte,
|
func readScriptBuf(r io.Reader, pver uint32, buf, s []byte,
|
||||||
maxAllowed uint32, fieldName string) ([]byte, error) {
|
fieldName string) ([]byte, error) {
|
||||||
|
|
||||||
count, err := ReadVarIntBuf(r, pver, buf)
|
count, err := ReadVarIntBuf(r, pver, buf)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -1014,9 +1027,9 @@ func readScriptBuf(r io.Reader, pver uint32, buf, s []byte,
|
|||||||
// Prevent byte array larger than the max message size. It would
|
// Prevent byte array larger than the max message size. It would
|
||||||
// be possible to cause memory exhaustion and panics without a sane
|
// be possible to cause memory exhaustion and panics without a sane
|
||||||
// upper bound on this count.
|
// upper bound on this count.
|
||||||
if count > uint64(maxAllowed) {
|
if count > maxWitnessItemSize {
|
||||||
str := fmt.Sprintf("%s is larger than the max allowed size "+
|
str := fmt.Sprintf("%s is larger than the max allowed size "+
|
||||||
"[count %d, max %d]", fieldName, count, maxAllowed)
|
"[count %d, max %d]", fieldName, count, maxWitnessItemSize)
|
||||||
return nil, messageError("readScript", str)
|
return nil, messageError("readScript", str)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1043,8 +1056,9 @@ func readTxInBuf(r io.Reader, pver uint32, version int32, ti *TxIn,
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
ti.SignatureScript, err = readScriptBuf(r, pver, buf, s, MaxMessagePayload,
|
ti.SignatureScript, err = readScriptBuf(
|
||||||
"transaction input signature script")
|
r, pver, buf, s, "transaction input signature script",
|
||||||
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -1107,8 +1121,7 @@ func readTxOutBuf(r io.Reader, pver uint32, version int32, to *TxOut,
|
|||||||
to.Value = int64(littleEndian.Uint64(buf))
|
to.Value = int64(littleEndian.Uint64(buf))
|
||||||
|
|
||||||
to.PkScript, err = readScriptBuf(
|
to.PkScript, err = readScriptBuf(
|
||||||
r, pver, buf, s, MaxMessagePayload,
|
r, pver, buf, s, "transaction output public key script",
|
||||||
"transaction output public key script",
|
|
||||||
)
|
)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -6,6 +6,7 @@ package wire
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"reflect"
|
"reflect"
|
||||||
@ -877,6 +878,17 @@ func TestTxOutPointFromString(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TestTxSuperfluousWitnessRecord ensures that btcd fails to parse a tx with
|
||||||
|
// the witness marker flag set but without any actual witnesses.
|
||||||
|
func TestTxSuperfluousWitnessRecord(t *testing.T) {
|
||||||
|
m := &MsgTx{}
|
||||||
|
rbuf := bytes.NewReader(multiWitnessFlagNoWitness)
|
||||||
|
err := m.BtcDecode(rbuf, ProtocolVersion, WitnessEncoding)
|
||||||
|
if !errors.Is(err, errSuperfluousWitnessRecord) {
|
||||||
|
t.Fatalf("should have failed with %v", errSuperfluousWitnessRecord)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// multiTx is a MsgTx with an input and output and used in various tests.
|
// multiTx is a MsgTx with an input and output and used in various tests.
|
||||||
var multiTx = &MsgTx{
|
var multiTx = &MsgTx{
|
||||||
Version: 1,
|
Version: 1,
|
||||||
@ -1029,6 +1041,33 @@ var multiWitnessTx = &MsgTx{
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// multiWitnessFlagNoWitness is the wire encoded bytes for multiWitnessTx with
|
||||||
|
// the witness flag set but with witnesses omitted.
|
||||||
|
var multiWitnessFlagNoWitness = []byte{
|
||||||
|
0x1, 0x0, 0x0, 0x0, // Version
|
||||||
|
TxFlagMarker, // Marker byte indicating 0 inputs, or a segwit encoded tx
|
||||||
|
WitnessFlag, // Flag byte
|
||||||
|
0x1, // Varint for number of inputs
|
||||||
|
0xa5, 0x33, 0x52, 0xd5, 0x13, 0x57, 0x66, 0xf0,
|
||||||
|
0x30, 0x76, 0x59, 0x74, 0x18, 0x26, 0x3d, 0xa2,
|
||||||
|
0xd9, 0xc9, 0x58, 0x31, 0x59, 0x68, 0xfe, 0xa8,
|
||||||
|
0x23, 0x52, 0x94, 0x67, 0x48, 0x1f, 0xf9, 0xcd, // Previous output hash
|
||||||
|
0x13, 0x0, 0x0, 0x0, // Little endian previous output index
|
||||||
|
0x0, // No sig script (this is a witness input)
|
||||||
|
0xff, 0xff, 0xff, 0xff, // Sequence
|
||||||
|
0x1, // Varint for number of outputs
|
||||||
|
0xb, 0x7, 0x6, 0x0, 0x0, 0x0, 0x0, 0x0, // Output amount
|
||||||
|
0x16, // Varint for length of pk script
|
||||||
|
0x0, // Version 0 witness program
|
||||||
|
0x14, // OP_DATA_20
|
||||||
|
0x9d, 0xda, 0xc6, 0xf3, 0x9d, 0x51, 0xe0, 0x39,
|
||||||
|
0x8e, 0x53, 0x2a, 0x22, 0xc4, 0x1b, 0xa1, 0x89,
|
||||||
|
0x40, 0x6a, 0x85, 0x23, // 20-byte pub key hash
|
||||||
|
0x00, // No item on the witness stack for the first input
|
||||||
|
0x00, // No item on the witness stack for the second input
|
||||||
|
0x0, 0x0, 0x0, 0x0, // Lock time
|
||||||
|
}
|
||||||
|
|
||||||
// multiWitnessTxEncoded is the wire encoded bytes for multiWitnessTx including inputs
|
// multiWitnessTxEncoded is the wire encoded bytes for multiWitnessTx including inputs
|
||||||
// with witness data using protocol version 70012 and is used in the various
|
// with witness data using protocol version 70012 and is used in the various
|
||||||
// tests.
|
// tests.
|
||||||
|
Loading…
Reference in New Issue
Block a user