Merge pull request #2178 from ProofOfKeags/standardness-cleanup

Update standardness rules congruent to Bitcoin Core
This commit is contained in:
Olaoluwa Osuntokun 2024-05-21 15:44:24 -07:00 committed by GitHub
commit c4ed92fb52
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
15 changed files with 243 additions and 71 deletions

View File

@ -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.

View File

@ -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"]
] ]

View File

@ -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"]
] ]

View File

@ -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 (

View File

@ -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.

View File

@ -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)"},
} }

View File

@ -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)
}
} }
} }

View File

@ -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)
} }

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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.

View File

@ -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
} }

View File

@ -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
} }

View File

@ -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.