v31.1-roots.1 · Commit 2: [PATCH 02/17] feat(policy): preserve Roots parsing and local transaction checks
src/test/transaction_tests.cpp
Before: src/test/transaction_tests.cpp · After: src/test/transaction_tests.cpp
File metadata
index 916f565c04df41b909ad35e50b917cdb04caaa4f..4db01b19c3d6bfe187f78cac51c09f832b335c93 100644
Download original patch · Release notes
Diff rows 1–291 of 291. Line numbers refer to the original before/after files.
+ Added− RemovedUnmarked lines are context.
Scroll the code area horizontally to read long lines. The two line-number columns refer to before and after.
src/test/transaction_tests.cpp
CHANGED
|
@@ -14,6 +14,7 @@
|
|
|
14
14
|
#include <consensus/tx_verify.h>
|
|
15
15
|
#include <consensus/validation.h>
|
|
16
16
|
#include <core_io.h>
|
|
17
|
+
#include <kernel/mempool_options.h>
|
|
17
18
|
#include <key.h>
|
|
18
19
|
#include <policy/policy.h>
|
|
19
20
|
#include <policy/settings.h>
|
|
@@ -49,8 +50,8 @@ using util::ToString;
|
|
|
49
50
|
|
|
50
51
|
typedef std::vector<unsigned char> valtype;
|
|
51
52
|
|
|
52
|
-
static CFeeRate g_dust{DUST_RELAY_TX_FEE};
|
|
53
|
-
static bool g_bare_multi{DEFAULT_PERMIT_BAREMULTISIG};
|
|
53
|
+
|
|
54
|
+
static kernel::MemPoolOptions g_mempool_opts;
|
|
54
55
|
|
|
55
56
|
static const std::map<std::string, script_verify_flag_name>& mapFlagNames = ScriptFlagNamesToEnum();
|
|
56
57
|
|
|
@@ -764,21 +765,30 @@ BOOST_AUTO_TEST_CASE(test_IsStandard)
|
|
|
764
765
|
CKey key = GenerateRandomKey();
|
|
765
766
|
t.vout[0].scriptPubKey = GetScriptForDestination(PKHash(key.GetPubKey()));
|
|
766
767
|
|
|
767
|
-
constexpr auto CheckIsStandard = [](const auto& t, const unsigned int max_op_return_relay = MAX_OP_RETURN_RELAY) {
|
|
768
|
+
constexpr auto CheckIsStandard = [](const auto& t, const unsigned int max_op_return_relay = MAX_OP_RETURN_RELAY, const ignore_rejects_type& ignore_rejects = empty_ignore_rejects) {
|
|
768
769
|
std::string reason;
|
|
769
|
-
BOOST_CHECK(IsStandardTx(CTransaction{t}, max_op_return_relay, g_bare_multi, g_dust, reason));
|
|
770
|
+
auto opts = g_mempool_opts;
|
|
771
|
+
opts.max_datacarrier_bytes = max_op_return_relay;
|
|
772
|
+
BOOST_CHECK(IsStandardTx(CTransaction{t}, opts, reason, ignore_rejects));
|
|
770
773
|
BOOST_CHECK(reason.empty());
|
|
771
774
|
};
|
|
772
|
-
constexpr auto CheckIsNotStandard = [](const auto& t, const std::string& reason_in, const unsigned int max_op_return_relay = MAX_OP_RETURN_RELAY) {
|
|
775
|
+
constexpr auto CheckIsNotStandard = [](const auto& t, const std::string& reason_in, const unsigned int max_op_return_relay = MAX_OP_RETURN_RELAY, const ignore_rejects_type& ignore_rejects = empty_ignore_rejects) {
|
|
773
776
|
std::string reason;
|
|
774
|
-
BOOST_CHECK(!IsStandardTx(CTransaction{t}, max_op_return_relay, g_bare_multi, g_dust, reason));
|
|
777
|
+
auto opts = g_mempool_opts;
|
|
778
|
+
opts.max_datacarrier_bytes = max_op_return_relay;
|
|
779
|
+
BOOST_CHECK(!IsStandardTx(CTransaction{t}, opts, reason, ignore_rejects));
|
|
775
780
|
BOOST_CHECK_EQUAL(reason_in, reason);
|
|
776
781
|
};
|
|
777
782
|
|
|
783
|
+
g_mempool_opts.permit_bare_pubkey = true;
|
|
778
784
|
CheckIsStandard(t);
|
|
779
785
|
|
|
786
|
+
g_mempool_opts.permitephemeral_anchor = true;
|
|
787
|
+
g_mempool_opts.permitephemeral_dust = true;
|
|
788
|
+
g_mempool_opts.permitephemeral_send = true;
|
|
789
|
+
|
|
780
790
|
// Check dust with default relay fee:
|
|
781
|
-
CAmount nDustThreshold = 182 * g_dust.GetFeePerK() / 1000;
|
|
791
|
+
CAmount nDustThreshold = 182 * g_mempool_opts.dust_relay_feerate.GetFeePerK() / 1000;
|
|
782
792
|
BOOST_CHECK_EQUAL(nDustThreshold, 546);
|
|
783
793
|
|
|
784
794
|
// Add dust outputs up to allowed maximum, still standard!
|
|
@@ -813,25 +823,66 @@ BOOST_AUTO_TEST_CASE(test_IsStandard)
|
|
|
813
823
|
|
|
814
824
|
// Check dust with odd relay fee to verify rounding:
|
|
815
825
|
// nDustThreshold = 182 * 3702 / 1000
|
|
816
|
-
g_dust = CFeeRate(3702);
|
|
826
|
+
g_mempool_opts.dust_relay_feerate = CFeeRate(3702);
|
|
817
827
|
// dust:
|
|
818
828
|
t.vout[0].nValue = 674 - 1;
|
|
819
829
|
CheckIsNotStandard(t, "dust");
|
|
820
830
|
// not dust:
|
|
821
831
|
t.vout[0].nValue = 674;
|
|
822
832
|
CheckIsStandard(t);
|
|
823
|
-
g_dust = CFeeRate{DUST_RELAY_TX_FEE};
|
|
833
|
+
g_mempool_opts.dust_relay_feerate = CFeeRate{DUST_RELAY_TX_FEE};
|
|
824
834
|
|
|
825
835
|
t.vout[0].scriptPubKey = CScript() << OP_1;
|
|
826
836
|
CheckIsNotStandard(t, "scriptpubkey");
|
|
827
837
|
|
|
828
|
-
// Custom 83-byte TxoutType::NULL_DATA (standard with max_op_return_relay of 83)
|
|
829
|
-
t.vout[0].scriptPubKey = CScript() << OP_RETURN << "04678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef3804678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef38"_hex;
|
|
830
|
-
BOOST_CHECK_EQUAL(83, t.vout[0].scriptPubKey.size());
|
|
831
|
-
CheckIsStandard(t, /*max_op_return_relay=*/83);
|
|
838
|
+
// Test rejectparasites
|
|
839
|
+
t.vout[0].scriptPubKey = CScript() << OP_RETURN;
|
|
840
|
+
t.vout.emplace_back(674, GetScriptForDestination(PKHash(key.GetPubKey())));
|
|
841
|
+
t.nLockTime = PARASITE_CAT21_LOCKTIME;
|
|
842
|
+
g_mempool_opts.reject_parasites = false;
|
|
843
|
+
CheckIsStandard(t);
|
|
844
|
+
g_mempool_opts.reject_parasites = true;
|
|
845
|
+
CheckIsNotStandard(t, "parasite-cat21");
|
|
846
|
+
t.nLockTime = 0;
|
|
847
|
+
CheckIsStandard(t);
|
|
848
|
+
g_mempool_opts.reject_parasites = false;
|
|
832
849
|
|
|
833
|
-
// Non-standard if max_op_return_relay datacarrier arg is one less
|
|
834
|
-
CheckIsNotStandard(t, "datacarrier", /*max_op_return_relay=*/82);
|
|
850
|
+
// Test rejecttokens
|
|
851
|
+
t.vout[0].scriptPubKey = CScript() << OP_RETURN << OP_13 << OP_FALSE;
|
|
852
|
+
g_mempool_opts.reject_tokens = false;
|
|
853
|
+
CheckIsStandard(t);
|
|
854
|
+
g_mempool_opts.reject_tokens = true;
|
|
855
|
+
CheckIsNotStandard(t, "tokens-runes");
|
|
856
|
+
// At least one data push is needed after OP_13 to match
|
|
857
|
+
t.vout[0].scriptPubKey = CScript() << OP_RETURN << OP_13;
|
|
858
|
+
CheckIsStandard(t);
|
|
859
|
+
// Test rejecttokens applying to OLGA
|
|
860
|
+
const auto olga_header = CScript() << OP_0 << "003e7374616d703a000000000000000000000000000000000000000000000000"_hex;
|
|
861
|
+
t.vout[0].scriptPubKey = olga_header;
|
|
862
|
+
t.vout.resize(1);
|
|
863
|
+
// Missing a second output, so not OLGA
|
|
864
|
+
CheckIsStandard(t);
|
|
865
|
+
t.vout.emplace_back(1000, olga_header);
|
|
866
|
+
CheckIsNotStandard(t, "tokens-olga");
|
|
867
|
+
t.vout.emplace_back(1000, olga_header);
|
|
868
|
+
CheckIsNotStandard(t, "tokens-olga");
|
|
869
|
+
g_mempool_opts.reject_tokens = false;
|
|
870
|
+
CheckIsStandard(t);
|
|
871
|
+
t.vout.resize(1);
|
|
872
|
+
|
|
873
|
+
// MAX_OP_RETURN_RELAY-byte TxoutType::NULL_DATA (standard)
|
|
874
|
+
g_mempool_opts.permitbaredatacarrier = true;
|
|
875
|
+
t.vout[0].scriptPubKey = CScript() << OP_RETURN;
|
|
876
|
+
while (t.vout[0].scriptPubKey.size() < MAX_OP_RETURN_RELAY) {
|
|
877
|
+
t.vout[0].scriptPubKey << OP_0;
|
|
878
|
+
}
|
|
879
|
+
BOOST_CHECK_EQUAL(MAX_OP_RETURN_RELAY, t.vout[0].scriptPubKey.size());
|
|
880
|
+
CheckIsStandard(t);
|
|
881
|
+
|
|
882
|
+
// MAX_OP_RETURN_RELAY+1-byte TxoutType::NULL_DATA (non-standard)
|
|
883
|
+
t.vout[0].scriptPubKey << OP_0;
|
|
884
|
+
BOOST_CHECK_EQUAL(MAX_OP_RETURN_RELAY + 1, t.vout[0].scriptPubKey.size());
|
|
885
|
+
CheckIsNotStandard(t, "datacarrier");
|
|
835
886
|
|
|
836
887
|
// Data payload can be encoded in any way...
|
|
837
888
|
t.vout[0].scriptPubKey = CScript() << OP_RETURN << ""_hex;
|
|
@@ -853,28 +904,40 @@ BOOST_AUTO_TEST_CASE(test_IsStandard)
|
|
|
853
904
|
t.vout[0].scriptPubKey = CScript() << OP_RETURN;
|
|
854
905
|
CheckIsStandard(t);
|
|
855
906
|
|
|
856
|
-
// Multiple TxoutType::NULL_DATA are permitted
|
|
907
|
+
// Multiple carriers require an explicit local policy relaxation
|
|
857
908
|
t.vout.resize(2);
|
|
858
909
|
t.vout[0].scriptPubKey = CScript() << OP_RETURN << "04678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef38"_hex;
|
|
859
910
|
t.vout[0].nValue = 0;
|
|
860
911
|
t.vout[1].scriptPubKey = CScript() << OP_RETURN << "04678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef38"_hex;
|
|
861
912
|
t.vout[1].nValue = 0;
|
|
862
|
-
CheckIsStandard(t);
|
|
913
|
+
CheckIsNotStandard(t, "multi-op-return", MAX_STANDARD_TX_WEIGHT / WITNESS_SCALE_FACTOR);
|
|
914
|
+
CheckIsStandard(t, MAX_STANDARD_TX_WEIGHT / WITNESS_SCALE_FACTOR, {"multi-op-return"});
|
|
863
915
|
|
|
864
916
|
t.vout[0].scriptPubKey = CScript() << OP_RETURN << "04678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef38"_hex;
|
|
865
917
|
t.vout[1].scriptPubKey = CScript() << OP_RETURN;
|
|
866
|
-
CheckIsStandard(t);
|
|
918
|
+
CheckIsNotStandard(t, "multi-op-return", MAX_STANDARD_TX_WEIGHT / WITNESS_SCALE_FACTOR);
|
|
919
|
+
CheckIsStandard(t, MAX_STANDARD_TX_WEIGHT / WITNESS_SCALE_FACTOR, {"multi-op-return"});
|
|
867
920
|
|
|
868
921
|
t.vout[0].scriptPubKey = CScript() << OP_RETURN;
|
|
869
922
|
t.vout[1].scriptPubKey = CScript() << OP_RETURN;
|
|
870
|
-
CheckIsStandard(t);
|
|
923
|
+
CheckIsNotStandard(t, "multi-op-return", MAX_STANDARD_TX_WEIGHT / WITNESS_SCALE_FACTOR);
|
|
924
|
+
CheckIsStandard(t, MAX_STANDARD_TX_WEIGHT / WITNESS_SCALE_FACTOR, {"multi-op-return"});
|
|
871
925
|
|
|
872
926
|
t.vout[0].scriptPubKey = CScript() << OP_RETURN << "04678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef3804678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef38"_hex;
|
|
873
927
|
t.vout[1].scriptPubKey = CScript() << OP_RETURN << "04678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef3804678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef38"_hex;
|
|
874
928
|
const auto datacarrier_size = t.vout[0].scriptPubKey.size() + t.vout[1].scriptPubKey.size();
|
|
875
|
-
CheckIsStandard(t); // Default max relay should never trigger
|
|
876
|
-
CheckIsStandard(t, /*max_op_return_relay=*/datacarrier_size);
|
|
877
|
-
CheckIsNotStandard(t, "datacarrier", /*max_op_return_relay=*/datacarrier_size-1);
|
|
929
|
+
CheckIsNotStandard(t, "datacarrier");
|
|
930
|
+
CheckIsStandard(t, MAX_STANDARD_TX_WEIGHT / WITNESS_SCALE_FACTOR, {"multi-op-return"}); // Explicit generous aggregate limit
|
|
931
|
+
CheckIsStandard(t, /*max_op_return_relay=*/datacarrier_size, {"multi-op-return"});
|
|
932
|
+
CheckIsNotStandard(t, "datacarrier", /*max_op_return_relay=*/datacarrier_size-1, {"multi-op-return"});
|
|
933
|
+
|
|
934
|
+
// Bare carrier transactions still require explicit permission.
|
|
935
|
+
t.vout.resize(1);
|
|
936
|
+
t.vout[0].scriptPubKey = CScript() << OP_RETURN;
|
|
937
|
+
g_mempool_opts.permitbaredatacarrier = false;
|
|
938
|
+
CheckIsNotStandard(t, "bare-datacarrier");
|
|
939
|
+
g_mempool_opts.permitbaredatacarrier = true;
|
|
940
|
+
CheckIsStandard(t);
|
|
878
941
|
|
|
879
942
|
// Check large scriptSig (non-standard if size is >1650 bytes)
|
|
880
943
|
t.vout.resize(1);
|
|
@@ -937,16 +1000,16 @@ BOOST_AUTO_TEST_CASE(test_IsStandard)
|
|
|
937
1000
|
BOOST_CHECK_EQUAL(GetTransactionWeight(CTransaction(t)), 400004);
|
|
938
1001
|
CheckIsNotStandard(t, "tx-size");
|
|
939
1002
|
|
|
940
|
-
// Check bare multisig (standard if policy flag g_bare_multi is set)
|
|
941
|
-
g_bare_multi = true;
|
|
1003
|
+
// Check bare multisig (standard if the policy flag is set)
|
|
1004
|
+
g_mempool_opts.permit_bare_multisig = true;
|
|
942
1005
|
t.vout[0].scriptPubKey = GetScriptForMultisig(1, {key.GetPubKey()}); // simple 1-of-1
|
|
943
1006
|
t.vin.resize(1);
|
|
944
1007
|
t.vin[0].scriptSig = CScript() << std::vector<unsigned char>(65, 0);
|
|
945
1008
|
CheckIsStandard(t);
|
|
946
1009
|
|
|
947
|
-
g_bare_multi = false;
|
|
1010
|
+
g_mempool_opts.permit_bare_multisig = false;
|
|
948
1011
|
CheckIsNotStandard(t, "bare-multisig");
|
|
949
|
-
g_bare_multi = DEFAULT_PERMIT_BAREMULTISIG;
|
|
1012
|
+
g_mempool_opts.permit_bare_multisig = true;
|
|
950
1013
|
|
|
951
1014
|
// Add dust outputs up to allowed maximum
|
|
952
1015
|
assert(t.vout.size() == 1);
|
|
@@ -1005,6 +1068,9 @@ BOOST_AUTO_TEST_CASE(test_IsStandard)
|
|
|
1005
1068
|
for (int op = OP_1; op <= OP_16; op += 1) {
|
|
1006
1069
|
t.vout[0].scriptPubKey = CScript() << (opcodetype)op << std::vector<unsigned char>(2, 0);
|
|
1007
1070
|
t.vout[0].nValue = 240;
|
|
1071
|
+
g_mempool_opts.acceptunknownwitness = false;
|
|
1072
|
+
CheckIsNotStandard(t, "scriptpubkey-unknown-witnessversion");
|
|
1073
|
+
g_mempool_opts.acceptunknownwitness = true;
|
|
1008
1074
|
CheckIsStandard(t);
|
|
1009
1075
|
|
|
1010
1076
|
t.vout[0].nValue = 239;
|
|
@@ -1018,6 +1084,34 @@ BOOST_AUTO_TEST_CASE(test_IsStandard)
|
|
|
1018
1084
|
CheckIsStandard(t);
|
|
1019
1085
|
t.vout[0].nValue = 239;
|
|
1020
1086
|
CheckIsNotStandard(t, "dust");
|
|
1087
|
+
|
|
1088
|
+
// Test permitbareanchor
|
|
1089
|
+
g_mempool_opts.permitbareanchor = false;
|
|
1090
|
+
t.vout[1].scriptPubKey = GetScriptForDestination(PKHash(key.GetPubKey()));
|
|
1091
|
+
t.vout[1].nValue = COIN;
|
|
1092
|
+
CheckIsStandard(t);
|
|
1093
|
+
t.vout.resize(1);
|
|
1094
|
+
CheckIsNotStandard(t, "bare-anchor");
|
|
1095
|
+
g_mempool_opts.permitbareanchor = true;
|
|
1096
|
+
CheckIsStandard(t);
|
|
1097
|
+
|
|
1098
|
+
// Test permitephemeral
|
|
1099
|
+
g_mempool_opts.permitephemeral_anchor = false;
|
|
1100
|
+
CheckIsNotStandard(t, "anchor");
|
|
1101
|
+
t.vout[0].nValue = 0;
|
|
1102
|
+
CheckIsNotStandard(t, "anchor");
|
|
1103
|
+
g_mempool_opts.permitephemeral_anchor = true;
|
|
1104
|
+
g_mempool_opts.permitephemeral_dust = false;
|
|
1105
|
+
CheckIsStandard(t);
|
|
1106
|
+
t.vout[0].nValue = 1;
|
|
1107
|
+
CheckIsNotStandard(t, "dust-nonzero");
|
|
1108
|
+
g_mempool_opts.permitephemeral_dust = true;
|
|
1109
|
+
g_mempool_opts.permitephemeral_send = false;
|
|
1110
|
+
CheckIsStandard(t);
|
|
1111
|
+
t.vout[0].scriptPubKey = GetScriptForDestination(PKHash(key.GetPubKey()));
|
|
1112
|
+
CheckIsNotStandard(t, "dust-nonanchor");
|
|
1113
|
+
g_mempool_opts.permitephemeral_send = true;
|
|
1114
|
+
CheckIsStandard(t);
|
|
1021
1115
|
}
|
|
1022
1116
|
|
|
1023
1117
|
BOOST_AUTO_TEST_CASE(max_standard_legacy_sigops)
|
|
@@ -1115,55 +1209,6 @@ BOOST_AUTO_TEST_CASE(max_standard_legacy_sigops)
|
|
|
1115
1209
|
BOOST_CHECK(!::AreInputsStandard(CTransaction(tx_max_sigops), coins));
|
|
1116
1210
|
}
|
|
1117
1211
|
|
|
1118
|
-
BOOST_AUTO_TEST_CASE(checktxinputs_invalid_transactions_test)
|
|
1119
|
-
{
|
|
1120
|
-
auto check_invalid{[](CAmount input_value, CAmount output_value, bool coinbase, int spend_height, TxValidationResult expected_result, std::string_view expected_reason) {
|
|
1121
|
-
CCoinsView coins_dummy;
|
|
1122
|
-
CCoinsViewCache inputs(&coins_dummy);
|
|
1123
|
-
|
|
1124
|
-
const COutPoint prevout{Txid::FromUint256(uint256::ONE), 0};
|
|
1125
|
-
inputs.AddCoin(prevout, Coin{{input_value, CScript() << OP_TRUE}, /*nHeightIn=*/1, coinbase}, /*possible_overwrite=*/false);
|
|
1126
|
-
|
|
1127
|
-
CMutableTransaction mtx;
|
|
1128
|
-
mtx.vin.emplace_back(prevout);
|
|
1129
|
-
mtx.vout.emplace_back(output_value, CScript() << OP_TRUE);
|
|
1130
|
-
|
|
1131
|
-
TxValidationState state;
|
|
1132
|
-
CAmount txfee{0};
|
|
1133
|
-
BOOST_CHECK(!Consensus::CheckTxInputs(CTransaction{mtx}, state, inputs, spend_height, txfee));
|
|
1134
|
-
BOOST_CHECK(state.IsInvalid());
|
|
1135
|
-
BOOST_CHECK_EQUAL(state.GetResult(), expected_result);
|
|
1136
|
-
BOOST_CHECK_EQUAL(state.GetRejectReason(), expected_reason);
|
|
1137
|
-
}};
|
|
1138
|
-
|
|
1139
|
-
check_invalid(/*input_value=*/MAX_MONEY + 1,
|
|
1140
|
-
/*output_value=*/0,
|
|
1141
|
-
/*coinbase=*/false,
|
|
1142
|
-
/*spend_height=*/2,
|
|
1143
|
-
TxValidationResult::TX_CONSENSUS, /*expected_reason=*/"bad-txns-inputvalues-outofrange");
|
|
1144
|
-
|
|
1145
|
-
check_invalid(/*input_value=*/1 * COIN,
|
|
1146
|
-
/*output_value=*/2 * COIN,
|
|
1147
|
-
/*coinbase=*/false,
|
|
1148
|
-
/*spend_height=*/2,
|
|
1149
|
-
TxValidationResult::TX_CONSENSUS, /*expected_reason=*/"bad-txns-in-belowout");
|
|
1150
|
-
|
|
1151
|
-
check_invalid(/*input_value=*/1 * COIN,
|
|
1152
|
-
/*output_value=*/0,
|
|
1153
|
-
/*coinbase=*/true,
|
|
1154
|
-
/*spend_height=*/COINBASE_MATURITY,
|
|
1155
|
-
TxValidationResult::TX_PREMATURE_SPEND, /*expected_reason=*/"bad-txns-premature-spend-of-coinbase");
|
|
1156
|
-
}
|
|
1157
|
-
|
|
1158
|
-
BOOST_AUTO_TEST_CASE(getvalueout_out_of_range_throws)
|
|
1159
|
-
{
|
|
1160
|
-
CMutableTransaction mtx;
|
|
1161
|
-
mtx.vout.emplace_back(MAX_MONEY + 1, CScript() << OP_TRUE);
|
|
1162
|
-
|
|
1163
|
-
const CTransaction tx{mtx};
|
|
1164
|
-
BOOST_CHECK_EXCEPTION(tx.GetValueOut(), std::runtime_error, HasReason("GetValueOut: value out of range"));
|
|
1165
|
-
}
|
|
1166
|
-
|
|
1167
1212
|
/** Sanity check the return value of SpendsNonAnchorWitnessProg for various output types. */
|
|
1168
1213
|
BOOST_AUTO_TEST_CASE(spends_witness_prog)
|
|
1169
1214
|
{
|