bitcoin-test 0.1.12-alpha.0

test framework for the bitcoin system
Documentation
crate::ix!();



//-------------------------------------------[.cpp/bitcoin/src/test/multisig_tests.cpp]

#[cfg(test)]
#[BasicTestingSetup]
pub mod multisig_tests {

    pub fn sign_multisig(
            script_pub_key: &Script,
            keys:           &Vec<Key>,
            transaction:    &Transaction,
            which_in:       i32) -> Script {
        
        todo!();
            /*
                uint256 hash = SignatureHash(scriptPubKey, transaction, whichIn, SIGHASH_ALL, 0, SigVersion::BASE);

                CScript result;
                result << OP_0; // CHECKMULTISIG bug workaround
                for (const CKey &key : keys)
                {
                    std::vector<unsigned char> vchSig;
                    BOOST_CHECK(key.Sign(hash, vchSig));
                    vchSig.push_back((unsigned char)SIGHASH_ALL);
                    result << vchSig;
                }
                return result;
            */
    }

    #[test] fn multisig_verify() {
        todo!();
        /*
        
            unsigned int flags = SCRIPT_VERIFY_P2SH | SCRIPT_VERIFY_STRICTENC;

            ScriptError err;
            CKey key[4];
            CAmount amount = 0;
            for (int i = 0; i < 4; i++)
                key[i].MakeNewKey(true);

            CScript a_and_b;
            a_and_b << OP_2 << ToByteVector(key[0].GetPubKey()) << ToByteVector(key[1].GetPubKey()) << OP_2 << OP_CHECKMULTISIG;

            CScript a_or_b;
            a_or_b << OP_1 << ToByteVector(key[0].GetPubKey()) << ToByteVector(key[1].GetPubKey()) << OP_2 << OP_CHECKMULTISIG;

            CScript escrow;
            escrow << OP_2 << ToByteVector(key[0].GetPubKey()) << ToByteVector(key[1].GetPubKey()) << ToByteVector(key[2].GetPubKey()) << OP_3 << OP_CHECKMULTISIG;

            CMutableTransaction txFrom;  // Funding transaction
            txFrom.vout.resize(3);
            txFrom.vout[0].scriptPubKey = a_and_b;
            txFrom.vout[1].scriptPubKey = a_or_b;
            txFrom.vout[2].scriptPubKey = escrow;

            CMutableTransaction txTo[3]; // Spending transaction
            for (int i = 0; i < 3; i++)
            {
                txTo[i].vin.resize(1);
                txTo[i].vout.resize(1);
                txTo[i].vin[0].prevout.n = i;
                txTo[i].vin[0].prevout.hash = txFrom.GetHash();
                txTo[i].vout[0].nValue = 1;
            }

            std::vector<CKey> keys;
            CScript s;

            // Test a AND b:
            keys.assign(1,key[0]);
            keys.push_back(key[1]);
            s = sign_multisig(a_and_b, keys, CTransaction(txTo[0]), 0);
            BOOST_CHECK(VerifyScript(s, a_and_b, nullptr, flags, MutableTransactionSignatureChecker(&txTo[0], 0, amount, MissingDataBehavior::ASSERT_FAIL), &err));
            BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_OK, ScriptErrorString(err));

            for (int i = 0; i < 4; i++)
            {
                keys.assign(1,key[i]);
                s = sign_multisig(a_and_b, keys, CTransaction(txTo[0]), 0);
                BOOST_CHECK_MESSAGE(!VerifyScript(s, a_and_b, nullptr, flags, MutableTransactionSignatureChecker(&txTo[0], 0, amount, MissingDataBehavior::ASSERT_FAIL), &err), strprintf("a&b 1: %d", i));
                BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_INVALID_STACK_OPERATION, ScriptErrorString(err));

                keys.assign(1,key[1]);
                keys.push_back(key[i]);
                s = sign_multisig(a_and_b, keys, CTransaction(txTo[0]), 0);
                BOOST_CHECK_MESSAGE(!VerifyScript(s, a_and_b, nullptr, flags, MutableTransactionSignatureChecker(&txTo[0], 0, amount, MissingDataBehavior::ASSERT_FAIL), &err), strprintf("a&b 2: %d", i));
                BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_EVAL_FALSE, ScriptErrorString(err));
            }

            // Test a OR b:
            for (int i = 0; i < 4; i++)
            {
                keys.assign(1,key[i]);
                s = sign_multisig(a_or_b, keys, CTransaction(txTo[1]), 0);
                if (i == 0 || i == 1)
                {
                    BOOST_CHECK_MESSAGE(VerifyScript(s, a_or_b, nullptr, flags, MutableTransactionSignatureChecker(&txTo[1], 0, amount, MissingDataBehavior::ASSERT_FAIL), &err), strprintf("a|b: %d", i));
                    BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_OK, ScriptErrorString(err));
                }
                else
                {
                    BOOST_CHECK_MESSAGE(!VerifyScript(s, a_or_b, nullptr, flags, MutableTransactionSignatureChecker(&txTo[1], 0, amount, MissingDataBehavior::ASSERT_FAIL), &err), strprintf("a|b: %d", i));
                    BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_EVAL_FALSE, ScriptErrorString(err));
                }
            }
            s.clear();
            s << OP_0 << OP_1;
            BOOST_CHECK(!VerifyScript(s, a_or_b, nullptr, flags, MutableTransactionSignatureChecker(&txTo[1], 0, amount, MissingDataBehavior::ASSERT_FAIL), &err));
            BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_SIG_DER, ScriptErrorString(err));


            for (int i = 0; i < 4; i++)
                for (int j = 0; j < 4; j++)
                {
                    keys.assign(1,key[i]);
                    keys.push_back(key[j]);
                    s = sign_multisig(escrow, keys, CTransaction(txTo[2]), 0);
                    if (i < j && i < 3 && j < 3)
                    {
                        BOOST_CHECK_MESSAGE(VerifyScript(s, escrow, nullptr, flags, MutableTransactionSignatureChecker(&txTo[2], 0, amount, MissingDataBehavior::ASSERT_FAIL), &err), strprintf("escrow 1: %d %d", i, j));
                        BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_OK, ScriptErrorString(err));
                    }
                    else
                    {
                        BOOST_CHECK_MESSAGE(!VerifyScript(s, escrow, nullptr, flags, MutableTransactionSignatureChecker(&txTo[2], 0, amount, MissingDataBehavior::ASSERT_FAIL), &err), strprintf("escrow 2: %d %d", i, j));
                        BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_EVAL_FALSE, ScriptErrorString(err));
                    }
                }

        */
    }

    #[test] fn multisig_is_standard() {
        todo!();
        /*
        
            CKey key[4];
            for (int i = 0; i < 4; i++)
                key[i].MakeNewKey(true);

            TxoutType whichType;

            CScript a_and_b;
            a_and_b << OP_2 << ToByteVector(key[0].GetPubKey()) << ToByteVector(key[1].GetPubKey()) << OP_2 << OP_CHECKMULTISIG;
            BOOST_CHECK(::IsStandard(a_and_b, whichType));

            CScript a_or_b;
            a_or_b  << OP_1 << ToByteVector(key[0].GetPubKey()) << ToByteVector(key[1].GetPubKey()) << OP_2 << OP_CHECKMULTISIG;
            BOOST_CHECK(::IsStandard(a_or_b, whichType));

            CScript escrow;
            escrow << OP_2 << ToByteVector(key[0].GetPubKey()) << ToByteVector(key[1].GetPubKey()) << ToByteVector(key[2].GetPubKey()) << OP_3 << OP_CHECKMULTISIG;
            BOOST_CHECK(::IsStandard(escrow, whichType));

            CScript one_of_four;
            one_of_four << OP_1 << ToByteVector(key[0].GetPubKey()) << ToByteVector(key[1].GetPubKey()) << ToByteVector(key[2].GetPubKey()) << ToByteVector(key[3].GetPubKey()) << OP_4 << OP_CHECKMULTISIG;
            BOOST_CHECK(!::IsStandard(one_of_four, whichType));

            CScript malformed[6];
            malformed[0] << OP_3 << ToByteVector(key[0].GetPubKey()) << ToByteVector(key[1].GetPubKey()) << OP_2 << OP_CHECKMULTISIG;
            malformed[1] << OP_2 << ToByteVector(key[0].GetPubKey()) << ToByteVector(key[1].GetPubKey()) << OP_3 << OP_CHECKMULTISIG;
            malformed[2] << OP_0 << ToByteVector(key[0].GetPubKey()) << ToByteVector(key[1].GetPubKey()) << OP_2 << OP_CHECKMULTISIG;
            malformed[3] << OP_1 << ToByteVector(key[0].GetPubKey()) << ToByteVector(key[1].GetPubKey()) << OP_0 << OP_CHECKMULTISIG;
            malformed[4] << OP_1 << ToByteVector(key[0].GetPubKey()) << ToByteVector(key[1].GetPubKey()) << OP_CHECKMULTISIG;
            malformed[5] << OP_1 << ToByteVector(key[0].GetPubKey()) << ToByteVector(key[1].GetPubKey());

            for (int i = 0; i < 6; i++)
                BOOST_CHECK(!::IsStandard(malformed[i], whichType));

        */
    }

    #[test] fn multisig_sign() {
        todo!();
        /*
        
            // Test SignSignature() (and therefore the version of Solver() that signs transactions)
            FillableSigningProvider keystore;
            CKey key[4];
            for (int i = 0; i < 4; i++)
            {
                key[i].MakeNewKey(true);
                BOOST_CHECK(keystore.AddKey(key[i]));
            }

            CScript a_and_b;
            a_and_b << OP_2 << ToByteVector(key[0].GetPubKey()) << ToByteVector(key[1].GetPubKey()) << OP_2 << OP_CHECKMULTISIG;

            CScript a_or_b;
            a_or_b  << OP_1 << ToByteVector(key[0].GetPubKey()) << ToByteVector(key[1].GetPubKey()) << OP_2 << OP_CHECKMULTISIG;

            CScript escrow;
            escrow << OP_2 << ToByteVector(key[0].GetPubKey()) << ToByteVector(key[1].GetPubKey()) << ToByteVector(key[2].GetPubKey()) << OP_3 << OP_CHECKMULTISIG;

            CMutableTransaction txFrom;  // Funding transaction
            txFrom.vout.resize(3);
            txFrom.vout[0].scriptPubKey = a_and_b;
            txFrom.vout[1].scriptPubKey = a_or_b;
            txFrom.vout[2].scriptPubKey = escrow;

            CMutableTransaction txTo[3]; // Spending transaction
            for (int i = 0; i < 3; i++)
            {
                txTo[i].vin.resize(1);
                txTo[i].vout.resize(1);
                txTo[i].vin[0].prevout.n = i;
                txTo[i].vin[0].prevout.hash = txFrom.GetHash();
                txTo[i].vout[0].nValue = 1;
            }

            for (int i = 0; i < 3; i++)
            {
                BOOST_CHECK_MESSAGE(SignSignature(keystore, CTransaction(txFrom), txTo[i], 0, SIGHASH_ALL), strprintf("SignSignature %d", i));
            }

        */
    }
}