mirror of
https://github.com/bitcoin/bitcoin.git
synced 2026-06-04 02:02:42 +02:00
test: Tests for PSBT AddInput and AddOutput
This commit is contained in:
@@ -41,4 +41,130 @@ BOOST_AUTO_TEST_CASE(psbt2_timelock_test)
|
||||
CheckTimeLock("cHNidP8BAgQCAAAAAQMEAAAAAAEEAQIBBQEBAfsEAgAAAAABDiAPdY2/vU2nwWyKMwnDyB4RAPVh6mRttbAXUsSF4b3enwEPBAEAAAABEgQQJwAAAAEOIDobOzyDfWSJ6nox2ObH3VA8ABvvPgaVjnV0gI1oynilAQ8EAAAAAAERBIyNxGIAAQMIT5M1dwAAAAABBBYAFAsTUsrNA89qobfzyNY4hnGzSl4RAA==", std::nullopt);
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(psbt2_addinput)
|
||||
{
|
||||
FastRandomContext rng(/*fDeterministic=*/true);
|
||||
|
||||
CMutableTransaction mtx;
|
||||
PartiallySignedTransaction psbt(mtx, /*version=*/2);
|
||||
psbt.m_tx_modifiable.emplace();
|
||||
psbt.m_tx_modifiable->set(0, true);
|
||||
BOOST_CHECK_EQUAL(psbt.inputs.size(), 0);
|
||||
|
||||
// Same PSBT version is required
|
||||
uint256 txid;
|
||||
rng.fillrand(MakeWritableByteSpan(txid));
|
||||
PSBTInput psbtin_v0(/*psbt_version=*/0, Txid::FromUint256(txid), /*prev_out=*/0);
|
||||
BOOST_CHECK(!psbt.AddInput(psbtin_v0));
|
||||
BOOST_CHECK_EQUAL(psbt.inputs.size(), 0);
|
||||
rng.fillrand(MakeWritableByteSpan(txid));
|
||||
PSBTInput psbtin(/*psbt_version=*/2, Txid::FromUint256(txid), /*prev_out=*/0);
|
||||
BOOST_CHECK(psbt.AddInput(psbtin));
|
||||
BOOST_CHECK_EQUAL(psbt.inputs.size(), 1);
|
||||
|
||||
// Duplicates are not allowed
|
||||
BOOST_CHECK(!psbt.AddInput(psbtin));
|
||||
BOOST_CHECK_EQUAL(psbt.inputs.size(), 1);
|
||||
|
||||
// Input with a unique txid is allowed
|
||||
rng.fillrand(MakeWritableByteSpan(txid));
|
||||
PSBTInput psbtin2(/*psbt_version=*/2, Txid::FromUint256(txid), /*prev_out=*/0);
|
||||
BOOST_CHECK(psbt.AddInput(psbtin2));
|
||||
BOOST_CHECK_EQUAL(psbt.inputs.size(), 2);
|
||||
|
||||
// Disabling inputs modifiable flag prevents adding new inputs
|
||||
psbt.m_tx_modifiable->set(0, false);
|
||||
rng.fillrand(MakeWritableByteSpan(txid));
|
||||
PSBTInput psbtin3(/*psbt_version=*/2, Txid::FromUint256(txid), /*prev_out=*/0);
|
||||
BOOST_CHECK(!psbt.AddInput(psbtin3));
|
||||
BOOST_CHECK_EQUAL(psbt.inputs.size(), 2);
|
||||
psbt.m_tx_modifiable->set(0, true);
|
||||
|
||||
// Make sure that timelock compatibility checks are working
|
||||
// No previous required timelocks, new input with both height and time timelocks is allowed
|
||||
rng.fillrand(MakeWritableByteSpan(txid));
|
||||
PSBTInput psbtin4(/*psbt_version=*/2, Txid::FromUint256(txid), /*prev_out=*/0);
|
||||
psbtin4.time_locktime = LOCKTIME_THRESHOLD;
|
||||
psbtin4.height_locktime = 100;
|
||||
BOOST_CHECK(psbt.AddInput(psbtin4));
|
||||
BOOST_CHECK_EQUAL(psbt.inputs.size(), 3);
|
||||
|
||||
// Input with only a time timelock is allowed
|
||||
rng.fillrand(MakeWritableByteSpan(txid));
|
||||
PSBTInput psbtin5(/*psbt_version=*/2, Txid::FromUint256(txid), /*prev_out=*/0);
|
||||
psbtin5.time_locktime = LOCKTIME_THRESHOLD + 1;
|
||||
BOOST_CHECK(psbt.AddInput(psbtin5));
|
||||
BOOST_CHECK_EQUAL(psbt.inputs.size(), 4);
|
||||
|
||||
// Input with only a height timelock is not allowed because of previous
|
||||
rng.fillrand(MakeWritableByteSpan(txid));
|
||||
PSBTInput psbtin6(/*psbt_version=*/2, Txid::FromUint256(txid), /*prev_out=*/0);
|
||||
psbtin6.height_locktime = 100;
|
||||
BOOST_CHECK(!psbt.AddInput(psbtin6));
|
||||
BOOST_CHECK_EQUAL(psbt.inputs.size(), 4);
|
||||
|
||||
// Adding an input that already has a signature is allowed
|
||||
rng.fillrand(MakeWritableByteSpan(txid));
|
||||
PSBTInput psbtin7(/*psbt_version=*/2, Txid::FromUint256(txid), /*prev_out=*/0);
|
||||
psbtin7.final_script_sig << OP_1;
|
||||
BOOST_CHECK(psbt.AddInput(psbtin7));
|
||||
BOOST_CHECK_EQUAL(psbt.inputs.size(), 5);
|
||||
|
||||
// Same thing, but with other things that have signatures
|
||||
psbtin7.final_script_sig.clear();
|
||||
psbtin7.final_script_witness.stack.emplace_back();
|
||||
BOOST_CHECK(!psbt.AddInput(psbtin7));
|
||||
BOOST_CHECK_EQUAL(psbt.inputs.size(), 5);
|
||||
psbtin7.final_script_witness.SetNull();
|
||||
psbtin7.partial_sigs.emplace();
|
||||
BOOST_CHECK(!psbt.AddInput(psbtin7));
|
||||
BOOST_CHECK_EQUAL(psbt.inputs.size(), 5);
|
||||
psbtin7.partial_sigs.clear();
|
||||
psbtin7.m_tap_key_sig.push_back(0);
|
||||
BOOST_CHECK(!psbt.AddInput(psbtin7));
|
||||
BOOST_CHECK_EQUAL(psbt.inputs.size(), 5);
|
||||
psbtin7.m_tap_key_sig.clear();
|
||||
psbtin7.m_tap_script_sigs.emplace();
|
||||
BOOST_CHECK(!psbt.AddInput(psbtin7));
|
||||
BOOST_CHECK_EQUAL(psbt.inputs.size(), 5);
|
||||
psbtin7.m_tap_script_sigs.clear();
|
||||
psbtin7.m_musig2_partial_sigs.emplace();
|
||||
BOOST_CHECK(!psbt.AddInput(psbtin7));
|
||||
BOOST_CHECK_EQUAL(psbt.inputs.size(), 5);
|
||||
|
||||
// Adding an input that changes the timelock is no longer allowed
|
||||
rng.fillrand(MakeWritableByteSpan(txid));
|
||||
PSBTInput psbtin8(/*psbt_version=*/2, Txid::FromUint256(txid), /*prev_out=*/0);
|
||||
psbtin8.time_locktime = LOCKTIME_THRESHOLD + 2;
|
||||
BOOST_CHECK(!psbt.AddInput(psbtin8));
|
||||
BOOST_CHECK_EQUAL(psbt.inputs.size(), 5);
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(psbt2_addoutput)
|
||||
{
|
||||
CMutableTransaction mtx;
|
||||
PartiallySignedTransaction psbt(mtx, /*version=*/2);
|
||||
psbt.m_tx_modifiable.emplace();
|
||||
psbt.m_tx_modifiable->set(1, true);
|
||||
BOOST_CHECK_EQUAL(psbt.outputs.size(), 0);
|
||||
|
||||
// Same PSBT version is required
|
||||
PSBTOutput psbtout_v0(/*psbt_version=*/0, /*amount=*/1, CScript());
|
||||
BOOST_CHECK(!psbt.AddOutput(psbtout_v0));
|
||||
BOOST_CHECK_EQUAL(psbt.outputs.size(), 0);
|
||||
PSBTOutput psbtout(/*psbt_version=*/2, /*amount=*/1, CScript());
|
||||
BOOST_CHECK(psbt.AddOutput(psbtout));
|
||||
BOOST_CHECK_EQUAL(psbt.outputs.size(), 1);
|
||||
|
||||
// Disabling outputs modifiable flag prevents adding new outputs
|
||||
psbt.m_tx_modifiable->set(1, false);
|
||||
PSBTOutput psbtout2(/*psbt_version=*/2, /*amount=*/1, CScript());
|
||||
BOOST_CHECK(!psbt.AddOutput(psbtout2));
|
||||
BOOST_CHECK_EQUAL(psbt.outputs.size(), 1);
|
||||
psbt.m_tx_modifiable->set(1, true);
|
||||
PSBTOutput psbtout3(/*psbt_version=*/2, /*amount=*/1, CScript());
|
||||
BOOST_CHECK(psbt.AddOutput(psbtout3));
|
||||
BOOST_CHECK_EQUAL(psbt.outputs.size(), 2);
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_SUITE_END()
|
||||
|
||||
Reference in New Issue
Block a user