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
|
||||
// replacement.
|
||||
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
|
||||
@ -1355,6 +1359,12 @@ func (mp *TxPool) checkMempoolAcceptance(tx *btcutil.Tx,
|
||||
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
|
||||
// of blockchain which contains the invariant rules for what
|
||||
// transactions are allowed into blocks.
|
||||
|
@ -333,6 +333,32 @@
|
||||
["BIP143: wrong sighash (with FindAndDelete) = 17c50ec2181ecdfdc85ca081174b248199ba81fff730794d4f69b8ec031f2dce"],
|
||||
[[["9628667ad48219a169b41b020800162287d2c0f713c04157e95c484a8dcb7592", 7500, "0x00 0x20 0x9b66c15b4e0b4eb49fa877982cafded24859fe5b0e2dbfbe4f0df1de7743fd52", 200000]],
|
||||
"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"]
|
||||
]
|
||||
|
@ -471,17 +471,17 @@
|
||||
["BIP143 example: P2WSH with OP_CODESEPARATOR and out-of-range SIGHASH_SINGLE."],
|
||||
[[["6eb316926b1c5d567cd6f5e6a84fec606fc53d7b474526d1fff3948020c93dfe", 0, "0x21 0x036d5c20fa14fb2f635474c1dc4ef5909d4568e5569b79fc94d3448486e14685f8 CHECKSIG", 156250000],
|
||||
["f825690aee1b3dc247da796cacb12687a5e802429fd291cfd63e010f02cf1508", 0, "0x00 0x20 0x5d1b56b63d714eebe542309525f484b7e9d6f686b3781b6f61ef925d66d6f6a0", 4900000000]],
|
||||
"01000000000102fe3dc9208094f3ffd12645477b3dc56f60ec4fa8e6f5d67c565d1c6b9216b36e000000004847304402200af4e47c9b9629dbecc21f73af989bdaa911f7e6f6c2e9394588a3aa68f81e9902204f3fcf6ade7e5abb1295b6774c8e0abd94ae62217367096bc02ee5e435b67da201ffffffff0815cf020f013ed6cf91d29f4202e8a58726b1ac6c79da47c23d1bee0a6925f80000000000ffffffff0100f2052a010000001976a914a30741f8145e5acadf23f751864167f32e0963f788ac000347304402200de66acf4527789bfda55fc5459e214fa6083f936b430a762c629656216805ac0220396f550692cd347171cbc1ef1f51e15282e837bb2b30860dc77c8f78bc8501e503473044022027dc95ad6b740fe5129e7e62a75dd00f291a2aeb1200b84b09d9e3789406b6c002201a9ecd315dd6a0e632ab20bbb98948bc0c6fb204f2c286963bb48517a7058e27034721026dccc749adc2a9d0d89497ac511f760f45c47dc5ed9cf352a58ac706453880aeadab210255a9626aebf5e29c0e6538428ba0d1dcf6ca98ffdf086aa8ced5e0d0215ea465ac00000000", "P2SH,WITNESS"],
|
||||
"01000000000102fe3dc9208094f3ffd12645477b3dc56f60ec4fa8e6f5d67c565d1c6b9216b36e000000004847304402200af4e47c9b9629dbecc21f73af989bdaa911f7e6f6c2e9394588a3aa68f81e9902204f3fcf6ade7e5abb1295b6774c8e0abd94ae62217367096bc02ee5e435b67da201ffffffff0815cf020f013ed6cf91d29f4202e8a58726b1ac6c79da47c23d1bee0a6925f80000000000ffffffff0100f2052a010000001976a914a30741f8145e5acadf23f751864167f32e0963f788ac000347304402200de66acf4527789bfda55fc5459e214fa6083f936b430a762c629656216805ac0220396f550692cd347171cbc1ef1f51e15282e837bb2b30860dc77c8f78bc8501e503473044022027dc95ad6b740fe5129e7e62a75dd00f291a2aeb1200b84b09d9e3789406b6c002201a9ecd315dd6a0e632ab20bbb98948bc0c6fb204f2c286963bb48517a7058e27034721026dccc749adc2a9d0d89497ac511f760f45c47dc5ed9cf352a58ac706453880aeadab210255a9626aebf5e29c0e6538428ba0d1dcf6ca98ffdf086aa8ced5e0d0215ea465ac00000000", "P2SH,WITNESS,CONST_SCRIPTCODE"],
|
||||
|
||||
["BIP143 example: P2WSH with unexecuted OP_CODESEPARATOR and SINGLE|ANYONECANPAY"],
|
||||
[[["01c0cf7fba650638e55eb91261b183251fbb466f90dff17f10086817c542b5e9", 0, "0x00 0x20 0xba468eea561b26301e4cf69fa34bde4ad60c81e70f059f045ca9a79931004a4d", 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"],
|
||||
[[["1b2a9a426ba603ba357ce7773cb5805cb9c7c2b386d100d1fc9263513188e680", 0, "0x00 0x20 0xd9bbfbe56af7c4b7f960a70d7ea107156913d9e5a26b0a71429df5e097ca6537", 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"],
|
||||
[[["6eb98797a21c6c10aa74edf29d618be109f48a8e94c694f3701e08ca69186436", 1, "HASH160 0x14 0x9993a429037b5d912407a71c252019287b8d27a5 EQUAL", 987654321]],
|
||||
@ -498,7 +498,7 @@
|
||||
"010000000169c12106097dc2e0526493ef67f21269fe888ef05c7a3a5dacab38e1ac8387f1581b0000b64830450220487fb382c4974de3f7d834c1b617fe15860828c7f96454490edd6d891556dcc9022100baf95feb48f845d5bfc9882eb6aeefa1bc3790e39f59eaa46ff7f15ae626c53e0121037a3fb04bcdb09eba90f69961ba1692a3528e45e67c85b200df820212d7594d334aad4830450220487fb382c4974de3f7d834c1b617fe15860828c7f96454490edd6d891556dcc9022100baf95feb48f845d5bfc9882eb6aeefa1bc3790e39f59eaa46ff7f15ae626c53e01ffffffff0101000000000000000000000000", "P2SH,WITNESS"],
|
||||
["BIP143: correct sighash (without FindAndDelete) = 71c9cd9b2869b9c70b01b1f0360c148f42dee72297db312638df136f43311f23"],
|
||||
[[["f18783ace138abac5d3a7a5cf08e88fe6912f267ef936452e0c27d090621c169", 7500, "0x00 0x20 0x9e1be07558ea5cc8e02ed1d80c0911048afad949affa36d5c3951e3159dbea19", 200000]],
|
||||
"0100000000010169c12106097dc2e0526493ef67f21269fe888ef05c7a3a5dacab38e1ac8387f14c1d000000ffffffff01010000000000000000034830450220487fb382c4974de3f7d834c1b617fe15860828c7f96454490edd6d891556dcc9022100baf95feb48f845d5bfc9882eb6aeefa1bc3790e39f59eaa46ff7f15ae626c53e012102a9781d66b61fb5a7ef00ac5ad5bc6ffc78be7b44a566e3c87870e1079368df4c4aad4830450220487fb382c4974de3f7d834c1b617fe15860828c7f96454490edd6d891556dcc9022100baf95feb48f845d5bfc9882eb6aeefa1bc3790e39f59eaa46ff7f15ae626c53e0100000000", "P2SH,WITNESS"],
|
||||
"0100000000010169c12106097dc2e0526493ef67f21269fe888ef05c7a3a5dacab38e1ac8387f14c1d000000ffffffff01010000000000000000034830450220487fb382c4974de3f7d834c1b617fe15860828c7f96454490edd6d891556dcc9022100baf95feb48f845d5bfc9882eb6aeefa1bc3790e39f59eaa46ff7f15ae626c53e012102a9781d66b61fb5a7ef00ac5ad5bc6ffc78be7b44a566e3c87870e1079368df4c4aad4830450220487fb382c4974de3f7d834c1b617fe15860828c7f96454490edd6d891556dcc9022100baf95feb48f845d5bfc9882eb6aeefa1bc3790e39f59eaa46ff7f15ae626c53e0100000000", "P2SH,WITNESS,CONST_SCRIPTCODE"],
|
||||
["This is multisig version of the FindAndDelete tests"],
|
||||
["Script is 2 CHECKMULTISIGVERIFY <sig1> <sig2> DROP"],
|
||||
["52af4830450220487fb382c4974de3f7d834c1b617fe15860828c7f96454490edd6d891556dcc9022100baf95feb48f845d5bfc9882eb6aeefa1bc3790e39f59eaa46ff7f15ae626c53e0148304502205286f726690b2e9b0207f0345711e63fa7012045b9eb0f19c2458ce1db90cf43022100e89f17f86abc5b149eba4115d4f128bcf45d77fb3ecdd34f594091340c0395960175"],
|
||||
@ -508,7 +508,9 @@
|
||||
"01000000019275cb8d4a485ce95741c013f7c0d28722160008021bb469a11982d47a662896581b0000fd6f01004830450220487fb382c4974de3f7d834c1b617fe15860828c7f96454490edd6d891556dcc9022100baf95feb48f845d5bfc9882eb6aeefa1bc3790e39f59eaa46ff7f15ae626c53e0148304502205286f726690b2e9b0207f0345711e63fa7012045b9eb0f19c2458ce1db90cf43022100e89f17f86abc5b149eba4115d4f128bcf45d77fb3ecdd34f594091340c03959601522102cd74a2809ffeeed0092bc124fd79836706e41f048db3f6ae9df8708cefb83a1c2102e615999372426e46fd107b76eaf007156a507584aa2cc21de9eee3bdbd26d36c4c9552af4830450220487fb382c4974de3f7d834c1b617fe15860828c7f96454490edd6d891556dcc9022100baf95feb48f845d5bfc9882eb6aeefa1bc3790e39f59eaa46ff7f15ae626c53e0148304502205286f726690b2e9b0207f0345711e63fa7012045b9eb0f19c2458ce1db90cf43022100e89f17f86abc5b149eba4115d4f128bcf45d77fb3ecdd34f594091340c0395960175ffffffff0101000000000000000000000000", "P2SH,WITNESS"],
|
||||
["BIP143: correct sighash (without FindAndDelete) = c1628a1e7c67f14ca0c27c06e4fdeec2e6d1a73c7a91d7c046ff83e835aebb72"],
|
||||
[[["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"]
|
||||
]
|
||||
|
@ -114,6 +114,10 @@ const (
|
||||
// ScriptVerifyDiscourageUpgradeablePubkeyType defines if unknown
|
||||
// public key versions (during tapscript execution) is non-standard.
|
||||
ScriptVerifyDiscourageUpgradeablePubkeyType
|
||||
|
||||
// ScriptVerifyConstScriptCode fails non-segwit scripts if a signature
|
||||
// match is found in the script code or if OP_CODESEPARATOR is used.
|
||||
ScriptVerifyConstScriptCode
|
||||
)
|
||||
|
||||
const (
|
||||
|
@ -408,6 +408,14 @@ const (
|
||||
// is exceeded during taproot execution.
|
||||
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
|
||||
// entry MUST be the last entry in the enum.
|
||||
numErrorCodes
|
||||
@ -494,6 +502,8 @@ var errorCodeStrings = map[ErrorCode]string{
|
||||
ErrInvalidTaprootSigLen: "ErrInvalidTaprootSigLen",
|
||||
ErrTaprootPubkeyIsEmpty: "ErrTaprootPubkeyIsEmpty",
|
||||
ErrTaprootMaxSigOps: "ErrTaprootMaxSigOps",
|
||||
ErrNonConstScriptCode: "ErrNonConstScriptCode",
|
||||
ErrCodeSeparator: "ErrCodeSeparator",
|
||||
}
|
||||
|
||||
// String returns the ErrorCode as a human-readable name.
|
||||
|
@ -96,6 +96,8 @@ func TestErrorCodeStringer(t *testing.T) {
|
||||
{ErrInvalidTaprootSigLen, "ErrInvalidTaprootSigLen"},
|
||||
{ErrTaprootPubkeyIsEmpty, "ErrTaprootPubkeyIsEmpty"},
|
||||
{ErrTaprootMaxSigOps, "ErrTaprootMaxSigOps"},
|
||||
{ErrNonConstScriptCode, "ErrNonConstScriptCode"},
|
||||
{ErrCodeSeparator, "ErrCodeSeparator"},
|
||||
{0xffff, "Unknown ErrorCode (65535)"},
|
||||
}
|
||||
|
||||
|
@ -1953,6 +1953,12 @@ func opcodeCodeSeparator(op *opcode, data []byte, vm *Engine) error {
|
||||
|
||||
if vm.taprootCtx != nil {
|
||||
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
|
||||
@ -2073,7 +2079,13 @@ func opcodeCheckSig(op *opcode, data []byte, vm *Engine) 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 {
|
||||
// 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
|
||||
}
|
||||
|
||||
valid := sigVerifier.Verify()
|
||||
result := sigVerifier.Verify()
|
||||
|
||||
// If the signature is invalid, this we fail execution, as it should
|
||||
// have been an empty signature.
|
||||
if !valid {
|
||||
if !result.sigValid {
|
||||
str := "signature not empty on failed checksig"
|
||||
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.
|
||||
if !vm.isWitnessVersionActive(0) {
|
||||
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
|
||||
case "TAPROOT":
|
||||
flags |= ScriptVerifyTaproot
|
||||
case "CONST_SCRIPTCODE":
|
||||
flags |= ScriptVerifyConstScriptCode
|
||||
default:
|
||||
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
|
||||
// does not accept a script version, the results are undefined for other script
|
||||
// versions.
|
||||
func removeOpcodeByData(script []byte, dataToRemove []byte) []byte {
|
||||
func removeOpcodeByData(script []byte, dataToRemove []byte) ([]byte, bool) {
|
||||
// Avoid work when possible.
|
||||
if len(script) == 0 || len(dataToRemove) == 0 {
|
||||
return script
|
||||
return script, false
|
||||
}
|
||||
|
||||
// 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
|
||||
var result []byte
|
||||
var prevOffset int32
|
||||
var match bool
|
||||
tokenizer := MakeScriptTokenizer(scriptVersion, script)
|
||||
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
|
||||
// data since this function is only used during signature verification
|
||||
// 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
|
||||
// is actually a match that needs to be removed.
|
||||
op, data := tokenizer.Opcode(), tokenizer.Data()
|
||||
if isCanonicalPush(op, data) && bytes.Contains(data, dataToRemove) {
|
||||
op, data := t.Opcode(), t.Data()
|
||||
if isCanonicalPush(op, data) && bytes.Equal(data, dataToRemove) {
|
||||
if result == nil {
|
||||
fullPushLen := tokenizer.ByteIndex() - prevOffset
|
||||
fullPushLen := t.ByteIndex() - prevOffset
|
||||
result = make([]byte, 0, int32(len(script))-fullPushLen)
|
||||
result = append(result, script[0:prevOffset]...)
|
||||
}
|
||||
found = true
|
||||
} else if result != nil {
|
||||
result = append(result, script[prevOffset:tokenizer.ByteIndex()]...)
|
||||
result = append(result, script[prevOffset:t.ByteIndex()]...)
|
||||
}
|
||||
|
||||
prevOffset = tokenizer.ByteIndex()
|
||||
}
|
||||
if result == nil {
|
||||
result = script
|
||||
}
|
||||
return result
|
||||
return result, t.ByteIndex(), found
|
||||
}
|
||||
|
||||
// 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},
|
||||
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",
|
||||
before: []byte{OP_DATA_4, 1, 2, 3, 4},
|
||||
@ -376,7 +382,9 @@ func TestRemoveOpcodeByData(t *testing.T) {
|
||||
bytes.Repeat([]byte{0}, 72)...),
|
||||
[]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)",
|
||||
@ -400,7 +408,9 @@ func TestRemoveOpcodeByData(t *testing.T) {
|
||||
bytes.Repeat([]byte{0}, 252)...),
|
||||
[]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)",
|
||||
@ -425,7 +435,9 @@ func TestRemoveOpcodeByData(t *testing.T) {
|
||||
bytes.Repeat([]byte{0}, 65532)...),
|
||||
[]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)",
|
||||
@ -465,16 +477,17 @@ func TestRemoveOpcodeByData(t *testing.T) {
|
||||
// tstRemoveOpcodeByData is a convenience function to ensure the provided
|
||||
// script parses before attempting to remove the passed data.
|
||||
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 {
|
||||
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 {
|
||||
result, err := tstRemoveOpcodeByData(test.before, test.remove)
|
||||
result, _, err := tstRemoveOpcodeByData(test.before, test.remove)
|
||||
if e := tstCheckScriptError(err, test.err); e != nil {
|
||||
t.Errorf("%s: %v", test.name, e)
|
||||
continue
|
||||
|
@ -20,9 +20,14 @@ import (
|
||||
// pre-segwit, segwit v0, segwit v1 (taproot key spend validation), and the
|
||||
// base tapscript verification.
|
||||
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.
|
||||
Verify() bool
|
||||
Verify() verifyResult
|
||||
}
|
||||
|
||||
type verifyResult struct {
|
||||
sigValid bool
|
||||
sigMatch bool
|
||||
}
|
||||
|
||||
// baseSigVerifier is used to verify signatures for the _base_ system, meaning
|
||||
@ -147,20 +152,23 @@ func (b *baseSigVerifier) verifySig(sigHash []byte) bool {
|
||||
return valid
|
||||
}
|
||||
|
||||
// Verify returns true if the signature verifier context deems the signature to
|
||||
// be valid for the given context.
|
||||
// Verify returns whether or not the signature verifier context deems the
|
||||
// signature to be valid for the given context.
|
||||
//
|
||||
// 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
|
||||
// to sign itself.
|
||||
subScript := removeOpcodeByData(b.subScript, b.fullSigBytes)
|
||||
subScript, match := removeOpcodeByData(b.subScript, b.fullSigBytes)
|
||||
|
||||
sigHash := calcSignatureHash(
|
||||
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
|
||||
@ -192,7 +200,7 @@ func newBaseSegwitSigVerifier(pkBytes, fullSigBytes []byte,
|
||||
// be valid for the given context.
|
||||
//
|
||||
// NOTE: This is part of the baseSigVerifier interface.
|
||||
func (s *baseSegwitSigVerifier) Verify() bool {
|
||||
func (s *baseSegwitSigVerifier) Verify() verifyResult {
|
||||
var sigHashes *TxSigHashes
|
||||
if s.vm.hashCache != nil {
|
||||
sigHashes = s.vm.hashCache
|
||||
@ -208,10 +216,12 @@ func (s *baseSegwitSigVerifier) Verify() bool {
|
||||
// TODO(roasbeef): this doesn't need to return an error, should
|
||||
// instead be further up the stack? this only returns an error
|
||||
// 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
|
||||
@ -356,11 +366,11 @@ func (t *taprootSigVerifier) verifySig(sigHash []byte) bool {
|
||||
return false
|
||||
}
|
||||
|
||||
// Verify returns true if the signature verifier context deems the signature to
|
||||
// be valid for the given context.
|
||||
// Verify returns whether or not the signature verifier context deems the
|
||||
// signature to be valid for the given context.
|
||||
//
|
||||
// NOTE: This is part of the baseSigVerifier interface.
|
||||
func (t *taprootSigVerifier) Verify() bool {
|
||||
func (t *taprootSigVerifier) Verify() verifyResult {
|
||||
var opts []TaprootSigHashOption
|
||||
if t.annex != nil {
|
||||
opts = append(opts, WithAnnex(t.annex))
|
||||
@ -374,10 +384,12 @@ func (t *taprootSigVerifier) Verify() bool {
|
||||
)
|
||||
if err != nil {
|
||||
// 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
|
||||
@ -439,16 +451,18 @@ func newBaseTapscriptSigVerifier(pkBytes, rawSig []byte,
|
||||
}
|
||||
}
|
||||
|
||||
// Verify returns true if the signature verifier context deems the signature to
|
||||
// be valid for the given context.
|
||||
// Verify returns whether or not the signature verifier context deems the
|
||||
// signature to be valid for the given context.
|
||||
//
|
||||
// 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,
|
||||
// so we'll treat this as an unknown public key version and return
|
||||
// true.
|
||||
// that it's valid.
|
||||
if b.pubKey == nil {
|
||||
return true
|
||||
return verifyResult{
|
||||
sigValid: true,
|
||||
}
|
||||
}
|
||||
|
||||
var opts []TaprootSigHashOption
|
||||
@ -468,10 +482,12 @@ func (b *baseTapscriptSigVerifier) Verify() bool {
|
||||
)
|
||||
if err != nil {
|
||||
// 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
|
||||
|
@ -46,7 +46,8 @@ const (
|
||||
ScriptVerifyTaproot |
|
||||
ScriptVerifyDiscourageUpgradeableTaprootVersion |
|
||||
ScriptVerifyDiscourageOpSuccess |
|
||||
ScriptVerifyDiscourageUpgradeablePubkeyType
|
||||
ScriptVerifyDiscourageUpgradeablePubkeyType |
|
||||
ScriptVerifyConstScriptCode
|
||||
)
|
||||
|
||||
// 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
|
||||
}
|
||||
|
||||
valid := keySpendVerifier.Verify()
|
||||
if valid {
|
||||
result := keySpendVerifier.Verify()
|
||||
if result.sigValid {
|
||||
return nil
|
||||
}
|
||||
|
||||
|
@ -112,6 +112,14 @@ const (
|
||||
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
|
||||
// message. It allows decoders to distinguish a regular serialized
|
||||
// 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)
|
||||
for j := uint64(0); j < witCount; j++ {
|
||||
txin.Witness[j], err = readScriptBuf(
|
||||
r, pver, buf, sbuf, maxWitnessItemSize,
|
||||
"script witness item",
|
||||
r, pver, buf, sbuf, "script witness item",
|
||||
)
|
||||
if err != nil {
|
||||
return err
|
||||
@ -611,6 +618,12 @@ func (msg *MsgTx) btcDecode(r io.Reader, pver uint32, enc MessageEncoding,
|
||||
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 {
|
||||
@ -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.
|
||||
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)
|
||||
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
|
||||
// be possible to cause memory exhaustion and panics without a sane
|
||||
// upper bound on this count.
|
||||
if count > uint64(maxAllowed) {
|
||||
if count > maxWitnessItemSize {
|
||||
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)
|
||||
}
|
||||
|
||||
@ -1043,8 +1056,9 @@ func readTxInBuf(r io.Reader, pver uint32, version int32, ti *TxIn,
|
||||
return err
|
||||
}
|
||||
|
||||
ti.SignatureScript, err = readScriptBuf(r, pver, buf, s, MaxMessagePayload,
|
||||
"transaction input signature script")
|
||||
ti.SignatureScript, err = readScriptBuf(
|
||||
r, pver, buf, s, "transaction input signature script",
|
||||
)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -1107,8 +1121,7 @@ func readTxOutBuf(r io.Reader, pver uint32, version int32, to *TxOut,
|
||||
to.Value = int64(littleEndian.Uint64(buf))
|
||||
|
||||
to.PkScript, err = readScriptBuf(
|
||||
r, pver, buf, s, MaxMessagePayload,
|
||||
"transaction output public key script",
|
||||
r, pver, buf, s, "transaction output public key script",
|
||||
)
|
||||
return err
|
||||
}
|
||||
|
@ -6,6 +6,7 @@ package wire
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"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.
|
||||
var multiTx = &MsgTx{
|
||||
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
|
||||
// with witness data using protocol version 70012 and is used in the various
|
||||
// tests.
|
||||
|
Loading…
Reference in New Issue
Block a user