Newer
Older
4001
4002
4003
4004
4005
4006
4007
4008
4009
4010
4011
4012
4013
4014
4015
4016
4017
4018
4019
4020
4021
4022
4023
4024
4025
4026
4027
4028
4029
4030
4031
4032
4033
4034
4035
4036
4037
4038
4039
4040
4041
4042
4043
4044
// <sig> <msg> <pubKey> OP_CHECKDATASIGVERIFY fails if 15 November 2018 protocol upgrade is not yet activated.
basic_test_with_flags(&correct_signature_script, &incorrect_flags, Err(Error::DisabledOpcode(Opcode::OP_CHECKDATASIGVERIFY)), vec![].into());
// <sig> <msg> OP_CHECKDATASIGVERIFY fails if there are fewer than 3 item on stack.
let too_few_args_sig_script = Builder::default()
.push_data(&[1u8; 32])
.push_data(&*message)
.push_opcode(Opcode::OP_CHECKDATASIGVERIFY)
.into_script();
basic_test_with_flags(&too_few_args_sig_script, &correct_flags, Err(Error::InvalidStackOperation), vec![].into());
// <sig> <msg> <pubKey> OP_CHECKDATASIGVERIFYfails if <pubKey> is not a validly encoded public key.
let incorrect_pubkey_script = Builder::default()
.push_data(&*correct_signature)
.push_data(&*message)
.push_data(&[77u8; 15])
.push_opcode(Opcode::OP_CHECKDATASIGVERIFY)
.into_script();
basic_test_with_flags(&incorrect_pubkey_script, &correct_flags, Err(Error::PubkeyType), vec![].into());
// assuming that check_signature_encoding correctness is proved by other tests:
// <sig> <msg> <pubKey> OP_CHECKDATASIGVERIFY fails if <sig> is not a validly encoded signature with strict DER encoding.
// <sig> <msg> <pubKey> OP_CHECKDATASIGVERIFY fails if signature <sig> is not empty and does not pass the Low S check.
let incorrectly_encoded_signature_script = Builder::default()
.push_data(&[0u8; 65])
.push_data(&*message)
.push_data(&*pubkey)
.push_opcode(Opcode::OP_CHECKDATASIGVERIFY)
.into_script();
basic_test_with_flags(&incorrectly_encoded_signature_script, &correct_flags, Err(Error::SignatureDer), vec![].into());
// <sig> <msg> <pubKey> OP_CHECKDATASIGVERIFY fails if <sig> is not a valid signature of <msg> with respect to <pubKey>.
let incorrect_signature_script = Builder::default()
.push_data(&*correct_signature_for_other_message)
.push_data(&*message)
.push_data(&*pubkey)
.push_opcode(Opcode::OP_CHECKDATASIGVERIFY)
.into_script();
basic_test_with_flags(&incorrect_signature_script, &correct_flags, Err(Error::CheckDataSigVerify), vec![].into());
// <sig> <msg> <pubKey> OP_CHECKDATASIGVERIFY pops the top three stack elements if <sig> is a valid signature of <msg> with respect to <pubKey>.
// Ok(false) means success here, because OP_CHECKDATASIGVERIFY leaves empty stack
basic_test_with_flags(&correct_signature_script, &correct_flags, Ok(false), vec![].into());
}
4045
4046
4047
4048
4049
4050
4051
4052
4053
4054
4055
4056
4057
4058
4059
4060
4061
4062
4063
4064
4065
4066
4067
4068
4069
#[test]
fn op_equal_push_empty_bytes_to_stack() {
// tx #95 from testnet block:
// https://testnet.blockexplorer.com/block/00000000c7169675fc165bfeceb11b572129977ca9f9e6ca5953e3184cb403dd
// https://tbtc.bitaps.com/raw/transaction/27c94c0ca2f66fcc09d11b510e04d21adfe19f459673029e709024d7d9a7f4b4
// and its donor tx:
// https://tbtc.bitaps.com/raw/transaction/25e140942ecf79d24619908185a881f95d9ecb23a7be050f7c44cd378aae26eb
//
// the issue was that our comparison ops implementation (OP_EQUAL, OP_WITHIN, OP_CHECKSIG, ***)
// were pushing non-empty value (vec![0]) when comparison has failed
// => in combination with verify_nnulldummy this caused consensus issue
let tx: Transaction = "0100000001eb26ae8a37cd447c0f05bea723cb9e5df981a88581901946d279cf2e9440e1250000000091473044022057e887c4cb773a6ec513b285dde1209ee4213209c21bb9da9e284ffe7477979302201aba367cf84bf2c6ccfd1b18d2bec0d705e2acacfeb42324cdc0fe63fbe2524a01483045022100e3f2e5e2a0b6bb75f2a506d7b190d8ba48b1e9108dd4fc4a740fbc921d0067a3022070fccd6eec2415d6d75f7aa3d0604988ee84d856db2acde4cc01d9c43f0237a301ffffffff0100350c00000000001976a9149e2be3b4d5e7274e8fd739b09fc6fd223054616088ac00000000".into();
let signer: TransactionInputSigner = tx.into();
let checker = TransactionSignatureChecker {
signer: signer,
input_index: 0,
input_amount: 1000000,
};
let input: Script = "473044022057e887c4cb773a6ec513b285dde1209ee4213209c21bb9da9e284ffe7477979302201aba367cf84bf2c6ccfd1b18d2bec0d705e2acacfeb42324cdc0fe63fbe2524a01483045022100e3f2e5e2a0b6bb75f2a506d7b190d8ba48b1e9108dd4fc4a740fbc921d0067a3022070fccd6eec2415d6d75f7aa3d0604988ee84d856db2acde4cc01d9c43f0237a301".into();
let output: Script = "5253877c5121027fe085933328a89d0ad069071dee3bd4c908fddc852032356a318324c9ab0f6c210321e7c9eea060c099747ddcf741e9498a2b90fe8f362e2c85370722df0f88d1782102a5bc779306b40927648e73e144d430dc1b7c0730f6a3ab5bbd130374d8fe4a5a53af2102a70faff961b367875336396076a72293bf3adaa084404f8a5cbec23f41645b87ac".into();
let flags = VerificationFlags::default().verify_nulldummy(true);
assert_eq!(verify_script(&input, &output, &ScriptWitness::default(), &flags, &checker, SignatureVersion::Base), Ok(()));
}