mirror of
https://github.com/kaspanet/kaspad.git
synced 2025-03-30 15:08:33 +00:00
[DEV-55] Removed FindAndDelete functionality that deletes signatures
* [DEV-50] Remove the Multisig bug requiring a dummy push * [DEV-53] SigHashSingle now errors when the index is wrong * [DEV-53] Fixed tests for SIGHASH_SINGLE * [DEV-55] Removed FindAndDelete functionality that deletes sognatures * [DEV-55] Removed some more redundant tests * [DEV-55] Fixed redundant comment
This commit is contained in:
parent
3f3a10c695
commit
927b5ec4ec
@ -9,22 +9,10 @@
|
||||
[[["6ca7ec7b1847f6bdbd737176050e6a08d66ccd55bb94ad24f4018024107a5827", 0, "0x41 0x043b640e983c9690a14c039a2037ecc3467b27a0dcd58f19d76c7bc118d09fec45adc5370a1c5bf8067ca9f5557a4cf885fdb0fe0dcc9c3a7137226106fbc779a5 CHECKSIG VERIFY 1"]],
|
||||
"010000000127587a10248001f424ad94bb55cd6cd6086a0e05767173bdbdf647187beca76c000000004948304502201b822ad10d6adc1a341ae8835be3f70a25201bbff31f59cbb9c5353a5f0eca18022100ea7b2f7074e9aa9cf70aa8d0ffee13e6b45dddabf1ab961bda378bcdb778fa4701ffffffff0100f2052a010000001976a914fc50c5907d86fed474ba5ce8b12a66e0a4c139d888ac00000000", "P2SH"],
|
||||
|
||||
["This is the nearly-standard transaction with CHECKSIGVERIFY 1 instead of CHECKSIG from tx_valid.json"],
|
||||
["but with the signature duplicated in the scriptPubKey with a non-standard pushdata prefix"],
|
||||
["See FindAndDelete, which will only remove if it uses the same pushdata prefix as is standard"],
|
||||
[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "DUP HASH160 0x14 0x5b6462475454710f3c22f5fdf0b40704c92f25c3 EQUALVERIFY CHECKSIGVERIFY 1 0x4c 0x47 0x3044022067288ea50aa799543a536ff9306f8e1cba05b9c6b10951175b924f96732555ed022026d7b5265f38d21541519e4a1e55044d5b9e17e15cdbaf29ae3792e99e883e7a01"]],
|
||||
"01000000010001000000000000000000000000000000000000000000000000000000000000000000006a473044022067288ea50aa799543a536ff9306f8e1cba05b9c6b10951175b924f96732555ed022026d7b5265f38d21541519e4a1e55044d5b9e17e15cdbaf29ae3792e99e883e7a012103ba8c8b86dea131c22ab967e6dd99bdae8eff7a1f75a2c35f1f944109e3fe5e22ffffffff010000000000000000015100000000", "P2SH"],
|
||||
|
||||
["Same as above, but with the sig in the scriptSig also pushed with the same non-standard OP_PUSHDATA"],
|
||||
[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "DUP HASH160 0x14 0x5b6462475454710f3c22f5fdf0b40704c92f25c3 EQUALVERIFY CHECKSIGVERIFY 1 0x4c 0x47 0x3044022067288ea50aa799543a536ff9306f8e1cba05b9c6b10951175b924f96732555ed022026d7b5265f38d21541519e4a1e55044d5b9e17e15cdbaf29ae3792e99e883e7a01"]],
|
||||
"01000000010001000000000000000000000000000000000000000000000000000000000000000000006b4c473044022067288ea50aa799543a536ff9306f8e1cba05b9c6b10951175b924f96732555ed022026d7b5265f38d21541519e4a1e55044d5b9e17e15cdbaf29ae3792e99e883e7a012103ba8c8b86dea131c22ab967e6dd99bdae8eff7a1f75a2c35f1f944109e3fe5e22ffffffff010000000000000000015100000000", "P2SH"],
|
||||
|
||||
["This is the nearly-standard transaction with CHECKSIGVERIFY 1 instead of CHECKSIG from tx_valid.json"],
|
||||
["but with the signature duplicated in the scriptPubKey with a different hashtype suffix"],
|
||||
["See FindAndDelete, which will only remove if the signature, including the hash type, matches"],
|
||||
[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "DUP HASH160 0x14 0x5b6462475454710f3c22f5fdf0b40704c92f25c3 EQUALVERIFY CHECKSIGVERIFY 1 0x47 0x3044022067288ea50aa799543a536ff9306f8e1cba05b9c6b10951175b924f96732555ed022026d7b5265f38d21541519e4a1e55044d5b9e17e15cdbaf29ae3792e99e883e7a81"]],
|
||||
"01000000010001000000000000000000000000000000000000000000000000000000000000000000006a473044022067288ea50aa799543a536ff9306f8e1cba05b9c6b10951175b924f96732555ed022026d7b5265f38d21541519e4a1e55044d5b9e17e15cdbaf29ae3792e99e883e7a012103ba8c8b86dea131c22ab967e6dd99bdae8eff7a1f75a2c35f1f944109e3fe5e22ffffffff010000000000000000015100000000", "P2SH"],
|
||||
|
||||
["An invalid P2SH Transaction"],
|
||||
[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "HASH160 0x14 0x7a052c840ba73af26755de42cf01cc9e0a49fef0 EQUAL"]],
|
||||
"010000000100010000000000000000000000000000000000000000000000000000000000000000000009085768617420697320ffffffff010000000000000000015100000000", "P2SH"],
|
||||
|
@ -26,10 +26,6 @@
|
||||
[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "DUP HASH160 0x14 0x5b6462475454710f3c22f5fdf0b40704c92f25c3 EQUALVERIFY CHECKSIGVERIFY 1"]],
|
||||
"01000000010001000000000000000000000000000000000000000000000000000000000000000000006a473044022067288ea50aa799543a536ff9306f8e1cba05b9c6b10951175b924f96732555ed022026d7b5265f38d21541519e4a1e55044d5b9e17e15cdbaf29ae3792e99e883e7a012103ba8c8b86dea131c22ab967e6dd99bdae8eff7a1f75a2c35f1f944109e3fe5e22ffffffff010000000000000000015100000000", "P2SH"],
|
||||
|
||||
["Same as above, but with the signature duplicated in the scriptPubKey with the proper pushdata prefix"],
|
||||
[[["0000000000000000000000000000000000000000000000000000000000000100", 0, "DUP HASH160 0x14 0x5b6462475454710f3c22f5fdf0b40704c92f25c3 EQUALVERIFY CHECKSIGVERIFY 1 0x47 0x3044022067288ea50aa799543a536ff9306f8e1cba05b9c6b10951175b924f96732555ed022026d7b5265f38d21541519e4a1e55044d5b9e17e15cdbaf29ae3792e99e883e7a01"]],
|
||||
"01000000010001000000000000000000000000000000000000000000000000000000000000000000006a473044022067288ea50aa799543a536ff9306f8e1cba05b9c6b10951175b924f96732555ed022026d7b5265f38d21541519e4a1e55044d5b9e17e15cdbaf29ae3792e99e883e7a012103ba8c8b86dea131c22ab967e6dd99bdae8eff7a1f75a2c35f1f944109e3fe5e22ffffffff010000000000000000015100000000", "P2SH"],
|
||||
|
||||
["The following is f7fdd091fa6d8f5e7a8c2458f5c38faffff2d3f1406b6e4fe2c99dcc0d2d1cbb"],
|
||||
["It caught a bug in the workaround for 23b397edccd3740a74adb603c9756370fafcde9bcc4483eb271ecad09a94dd63 in an overly simple implementation"],
|
||||
[[["b464e85df2a238416f8bdae11d120add610380ea07f4ef19c5f9dfd472f96c3d", 0, "DUP HASH160 0x14 0xbef80ecf3a44500fda1bc92176e442891662aed2 EQUALVERIFY CHECKSIG"],
|
||||
@ -146,14 +142,6 @@
|
||||
[[["10c9f0effe83e97f80f067de2b11c6a00c3088a4bce42c5ae761519af9306f3c", 1, "DUP HASH160 0x14 0xee5a6aa40facefb2655ac23c0c28c57c65c41f9b EQUALVERIFY CHECKSIG"]],
|
||||
"01000000013c6f30f99a5161e75a2ce4bca488300ca0c6112bde67f0807fe983feeff0c91001000000e608646561646265656675ab61493046022100ce18d384221a731c993939015e3d1bcebafb16e8c0b5b5d14097ec8177ae6f28022100bcab227af90bab33c3fe0a9abfee03ba976ee25dc6ce542526e9b2e56e14b7f10121038479a0fa998cd35259a2ef0a7a5c68662c1474f88ccb6d08a7677bbec7f22041ac493046022100c3b93edcc0fd6250eb32f2dd8a0bba1754b0f6c3be8ed4100ed582f3db73eba2022100bf75b5bd2eff4d6bf2bda2e34a40fcc07d4aa3cf862ceaa77b47b81eff829f9a01ab21038479a0fa998cd35259a2ef0a7a5c68662c1474f88ccb6d08a7677bbec7f22041ffffffff010000000000000000016a00000000", "P2SH"],
|
||||
|
||||
["Signatures are removed from the script they are in by FindAndDelete() in the CHECKSIG code; even multiple instances of one signature can be removed."],
|
||||
[[["6056ebd549003b10cbbd915cea0d82209fe40b8617104be917a26fa92cbe3d6f", 0, "DUP HASH160 0x14 0xee5a6aa40facefb2655ac23c0c28c57c65c41f9b EQUALVERIFY CHECKSIG"]],
|
||||
"01000000016f3dbe2ca96fa217e94b1017860be49f20820dea5c91bdcb103b0049d5eb566000000000fd1d0147304402203989ac8f9ad36b5d0919d97fa0a7f70c5272abee3b14477dc646288a8b976df5022027d19da84a066af9053ad3d1d7459d171b7e3a80bc6c4ef7a330677a6be548140147304402203989ac8f9ad36b5d0919d97fa0a7f70c5272abee3b14477dc646288a8b976df5022027d19da84a066af9053ad3d1d7459d171b7e3a80bc6c4ef7a330677a6be548140121038479a0fa998cd35259a2ef0a7a5c68662c1474f88ccb6d08a7677bbec7f22041ac47304402203757e937ba807e4a5da8534c17f9d121176056406a6465054bdd260457515c1a02200f02eccf1bec0f3a0d65df37889143c2e88ab7acec61a7b6f5aa264139141a2b0121038479a0fa998cd35259a2ef0a7a5c68662c1474f88ccb6d08a7677bbec7f22041ffffffff010000000000000000016a00000000", "P2SH"],
|
||||
|
||||
["That also includes ahead of the opcode being executed."],
|
||||
[[["5a6b0021a6042a686b6b94abc36b387bef9109847774e8b1e51eb8cc55c53921", 1, "DUP HASH160 0x14 0xee5a6aa40facefb2655ac23c0c28c57c65c41f9b EQUALVERIFY CHECKSIG"]],
|
||||
"01000000012139c555ccb81ee5b1e87477840991ef7b386bc3ab946b6b682a04a621006b5a01000000fdb40148304502201723e692e5f409a7151db386291b63524c5eb2030df652b1f53022fd8207349f022100b90d9bbf2f3366ce176e5e780a00433da67d9e5c79312c6388312a296a5800390148304502201723e692e5f409a7151db386291b63524c5eb2030df652b1f53022fd8207349f022100b90d9bbf2f3366ce176e5e780a00433da67d9e5c79312c6388312a296a5800390121038479a0fa998cd35259a2ef0a7a5c68662c1474f88ccb6d08a7677bbec7f2204148304502201723e692e5f409a7151db386291b63524c5eb2030df652b1f53022fd8207349f022100b90d9bbf2f3366ce176e5e780a00433da67d9e5c79312c6388312a296a5800390175ac4830450220646b72c35beeec51f4d5bc1cbae01863825750d7f490864af354e6ea4f625e9c022100f04b98432df3a9641719dbced53393022e7249fb59db993af1118539830aab870148304502201723e692e5f409a7151db386291b63524c5eb2030df652b1f53022fd8207349f022100b90d9bbf2f3366ce176e5e780a00433da67d9e5c79312c6388312a296a580039017521038479a0fa998cd35259a2ef0a7a5c68662c1474f88ccb6d08a7677bbec7f22041ffffffff010000000000000000016a00000000", "P2SH"],
|
||||
|
||||
["CHECKLOCKTIMEVERIFY tests"],
|
||||
|
||||
["By-height locks, with argument == 0 and == tx nLockTime"],
|
||||
|
@ -2048,10 +2048,6 @@ func opcodeCheckSig(op *parsedOpcode, vm *Engine) error {
|
||||
// Get script starting from the most recent OP_CODESEPARATOR.
|
||||
subScript := vm.subScript()
|
||||
|
||||
// Remove the signature since there is no way for a signature
|
||||
// to sign itself.
|
||||
subScript = removeOpcodeByData(subScript, fullSigBytes)
|
||||
|
||||
// Generate the signature hash based on the signature hash type.
|
||||
hash, err := calcSignatureHash(subScript, hashType, &vm.tx, vm.txIdx)
|
||||
if err != nil {
|
||||
@ -2199,11 +2195,6 @@ func opcodeCheckMultiSig(op *parsedOpcode, vm *Engine) error {
|
||||
// Get script starting from the most recent OP_CODESEPARATOR.
|
||||
script := vm.subScript()
|
||||
|
||||
// Remove the signatures in scripts since there is no way for a signature to sign itself.
|
||||
for _, sigInfo := range signatures {
|
||||
script = removeOpcodeByData(script, sigInfo.signature)
|
||||
}
|
||||
|
||||
success := true
|
||||
numPubKeys++
|
||||
pubKeyIdx := -1
|
||||
|
@ -265,19 +265,6 @@ func canonicalPush(pop parsedOpcode) bool {
|
||||
return true
|
||||
}
|
||||
|
||||
// removeOpcodeByData will return the script minus any opcodes that would push
|
||||
// the passed data to the stack.
|
||||
func removeOpcodeByData(pkscript []parsedOpcode, data []byte) []parsedOpcode {
|
||||
retScript := make([]parsedOpcode, 0, len(pkscript))
|
||||
for _, pop := range pkscript {
|
||||
if !canonicalPush(pop) || !bytes.Contains(pop.data, data) {
|
||||
retScript = append(retScript, pop)
|
||||
}
|
||||
}
|
||||
return retScript
|
||||
|
||||
}
|
||||
|
||||
// shallowCopyTx creates a shallow copy of the transaction for use when
|
||||
// calculating the signature hash. It is used over the Copy method on the
|
||||
// transaction itself since that is a deep copy and therefore does more work and
|
||||
|
@ -3926,155 +3926,6 @@ func TestRemoveOpcodes(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
// TestRemoveOpcodeByData ensures that removing data carrying opcodes based on
|
||||
// the data they contain works as expected.
|
||||
func TestRemoveOpcodeByData(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
before []byte
|
||||
remove []byte
|
||||
err error
|
||||
after []byte
|
||||
}{
|
||||
{
|
||||
name: "nothing to do",
|
||||
before: []byte{OpNop},
|
||||
remove: []byte{1, 2, 3, 4},
|
||||
after: []byte{OpNop},
|
||||
},
|
||||
{
|
||||
name: "simple case",
|
||||
before: []byte{OpData4, 1, 2, 3, 4},
|
||||
remove: []byte{1, 2, 3, 4},
|
||||
after: nil,
|
||||
},
|
||||
{
|
||||
name: "simple case (miss)",
|
||||
before: []byte{OpData4, 1, 2, 3, 4},
|
||||
remove: []byte{1, 2, 3, 5},
|
||||
after: []byte{OpData4, 1, 2, 3, 4},
|
||||
},
|
||||
{
|
||||
// padded to keep it canonical.
|
||||
name: "simple case (pushdata1)",
|
||||
before: append(append([]byte{OpPushData1, 76},
|
||||
bytes.Repeat([]byte{0}, 72)...),
|
||||
[]byte{1, 2, 3, 4}...),
|
||||
remove: []byte{1, 2, 3, 4},
|
||||
after: nil,
|
||||
},
|
||||
{
|
||||
name: "simple case (pushdata1 miss)",
|
||||
before: append(append([]byte{OpPushData1, 76},
|
||||
bytes.Repeat([]byte{0}, 72)...),
|
||||
[]byte{1, 2, 3, 4}...),
|
||||
remove: []byte{1, 2, 3, 5},
|
||||
after: append(append([]byte{OpPushData1, 76},
|
||||
bytes.Repeat([]byte{0}, 72)...),
|
||||
[]byte{1, 2, 3, 4}...),
|
||||
},
|
||||
{
|
||||
name: "simple case (pushdata1 miss noncanonical)",
|
||||
before: []byte{OpPushData1, 4, 1, 2, 3, 4},
|
||||
remove: []byte{1, 2, 3, 4},
|
||||
after: []byte{OpPushData1, 4, 1, 2, 3, 4},
|
||||
},
|
||||
{
|
||||
name: "simple case (pushdata2)",
|
||||
before: append(append([]byte{OpPushData2, 0, 1},
|
||||
bytes.Repeat([]byte{0}, 252)...),
|
||||
[]byte{1, 2, 3, 4}...),
|
||||
remove: []byte{1, 2, 3, 4},
|
||||
after: nil,
|
||||
},
|
||||
{
|
||||
name: "simple case (pushdata2 miss)",
|
||||
before: append(append([]byte{OpPushData2, 0, 1},
|
||||
bytes.Repeat([]byte{0}, 252)...),
|
||||
[]byte{1, 2, 3, 4}...),
|
||||
remove: []byte{1, 2, 3, 4, 5},
|
||||
after: append(append([]byte{OpPushData2, 0, 1},
|
||||
bytes.Repeat([]byte{0}, 252)...),
|
||||
[]byte{1, 2, 3, 4}...),
|
||||
},
|
||||
{
|
||||
name: "simple case (pushdata2 miss noncanonical)",
|
||||
before: []byte{OpPushData2, 4, 0, 1, 2, 3, 4},
|
||||
remove: []byte{1, 2, 3, 4},
|
||||
after: []byte{OpPushData2, 4, 0, 1, 2, 3, 4},
|
||||
},
|
||||
{
|
||||
// This is padded to make the push canonical.
|
||||
name: "simple case (pushdata4)",
|
||||
before: append(append([]byte{OpPushData4, 0, 0, 1, 0},
|
||||
bytes.Repeat([]byte{0}, 65532)...),
|
||||
[]byte{1, 2, 3, 4}...),
|
||||
remove: []byte{1, 2, 3, 4},
|
||||
after: nil,
|
||||
},
|
||||
{
|
||||
name: "simple case (pushdata4 miss noncanonical)",
|
||||
before: []byte{OpPushData4, 4, 0, 0, 0, 1, 2, 3, 4},
|
||||
remove: []byte{1, 2, 3, 4},
|
||||
after: []byte{OpPushData4, 4, 0, 0, 0, 1, 2, 3, 4},
|
||||
},
|
||||
{
|
||||
// This is padded to make the push canonical.
|
||||
name: "simple case (pushdata4 miss)",
|
||||
before: append(append([]byte{OpPushData4, 0, 0, 1, 0},
|
||||
bytes.Repeat([]byte{0}, 65532)...), []byte{1, 2, 3, 4}...),
|
||||
remove: []byte{1, 2, 3, 4, 5},
|
||||
after: append(append([]byte{OpPushData4, 0, 0, 1, 0},
|
||||
bytes.Repeat([]byte{0}, 65532)...), []byte{1, 2, 3, 4}...),
|
||||
},
|
||||
{
|
||||
name: "invalid opcode ",
|
||||
before: []byte{OpUnknown187},
|
||||
remove: []byte{1, 2, 3, 4},
|
||||
after: []byte{OpUnknown187},
|
||||
},
|
||||
{
|
||||
name: "invalid length (instruction)",
|
||||
before: []byte{OpPushData1},
|
||||
remove: []byte{1, 2, 3, 4},
|
||||
err: scriptError(ErrMalformedPush, ""),
|
||||
},
|
||||
{
|
||||
name: "invalid length (data)",
|
||||
before: []byte{OpPushData1, 255, 254},
|
||||
remove: []byte{1, 2, 3, 4},
|
||||
err: scriptError(ErrMalformedPush, ""),
|
||||
},
|
||||
}
|
||||
|
||||
// tstRemoveOpcodeByData is a convenience function to parse the provided
|
||||
// raw script, remove the passed data, then unparse the result back
|
||||
// into a raw script.
|
||||
tstRemoveOpcodeByData := func(script []byte, data []byte) ([]byte, error) {
|
||||
pops, err := parseScript(script)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
pops = removeOpcodeByData(pops, data)
|
||||
return unparseScript(pops)
|
||||
}
|
||||
|
||||
for _, test := range tests {
|
||||
result, err := tstRemoveOpcodeByData(test.before, test.remove)
|
||||
if e := tstCheckScriptError(err, test.err); e != nil {
|
||||
t.Errorf("%s: %v", test.name, e)
|
||||
continue
|
||||
}
|
||||
|
||||
if !bytes.Equal(test.after, result) {
|
||||
t.Errorf("%s: value does not equal expected: exp: %q"+
|
||||
" got: %q", test.name, test.after, result)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// TestIsPayToScriptHash ensures the IsPayToScriptHash function returns the
|
||||
// expected results for all the scripts in scriptClassTests.
|
||||
func TestIsPayToScriptHash(t *testing.T) {
|
||||
@ -4092,7 +3943,7 @@ func TestIsPayToScriptHash(t *testing.T) {
|
||||
}
|
||||
|
||||
// TestHasCanonicalPushes ensures the canonicalPush function properly determines
|
||||
// what is considered a canonical push for the purposes of removeOpcodeByData.
|
||||
// what is considered a canonical push.
|
||||
func TestHasCanonicalPushes(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user