Skip to content
Bitcoin Roots

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. Before is on the left; after is on the right. Unified view fits narrow screens more easily.

src/test/transaction_tests.cpp CHANGED
@@ -14,6 +14,7 @@
14
  #include <consensus/tx_verify.h>
15
  #include <consensus/validation.h>
16
  #include <core_io.h>
 
17
  #include <key.h>
18
  #include <policy/policy.h>
19
  #include <policy/settings.h>
@@ -49,8 +50,8 @@ using util::ToString;
49
 
50
  typedef std::vector<unsigned char> valtype;
51
 
52
- static CFeeRate g_dust{DUST_RELAY_TX_FEE};
53
- static bool g_bare_multi{DEFAULT_PERMIT_BAREMULTISIG};
54
 
55
  static const std::map<std::string, script_verify_flag_name>& mapFlagNames = ScriptFlagNamesToEnum();
56
 
@@ -764,21 +765,30 @@ BOOST_AUTO_TEST_CASE(test_IsStandard)
764
  CKey key = GenerateRandomKey();
765
  t.vout[0].scriptPubKey = GetScriptForDestination(PKHash(key.GetPubKey()));
766
 
767
- constexpr auto CheckIsStandard = [](const auto& t, const unsigned int max_op_return_relay = MAX_OP_RETURN_RELAY) {
768
  std::string reason;
769
- BOOST_CHECK(IsStandardTx(CTransaction{t}, max_op_return_relay, g_bare_multi, g_dust, reason));
 
 
770
  BOOST_CHECK(reason.empty());
771
  };
772
- constexpr auto CheckIsNotStandard = [](const auto& t, const std::string& reason_in, const unsigned int max_op_return_relay = MAX_OP_RETURN_RELAY) {
773
  std::string reason;
774
- BOOST_CHECK(!IsStandardTx(CTransaction{t}, max_op_return_relay, g_bare_multi, g_dust, reason));
 
 
775
  BOOST_CHECK_EQUAL(reason_in, reason);
776
  };
777
 
 
778
  CheckIsStandard(t);
779
 
 
 
 
 
780
  // Check dust with default relay fee:
781
- CAmount nDustThreshold = 182 * g_dust.GetFeePerK() / 1000;
782
  BOOST_CHECK_EQUAL(nDustThreshold, 546);
783
 
784
  // Add dust outputs up to allowed maximum, still standard!
@@ -813,25 +823,66 @@ BOOST_AUTO_TEST_CASE(test_IsStandard)
813
 
814
  // Check dust with odd relay fee to verify rounding:
815
  // nDustThreshold = 182 * 3702 / 1000
816
- g_dust = CFeeRate(3702);
817
  // dust:
818
  t.vout[0].nValue = 674 - 1;
819
  CheckIsNotStandard(t, "dust");
820
  // not dust:
821
  t.vout[0].nValue = 674;
822
  CheckIsStandard(t);
823
- g_dust = CFeeRate{DUST_RELAY_TX_FEE};
824
 
825
  t.vout[0].scriptPubKey = CScript() << OP_1;
826
  CheckIsNotStandard(t, "scriptpubkey");
827
 
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);
 
 
 
 
 
 
 
832
 
833
- // Non-standard if max_op_return_relay datacarrier arg is one less
834
- CheckIsNotStandard(t, "datacarrier", /*max_op_return_relay=*/82);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
835
 
836
  // Data payload can be encoded in any way...
837
  t.vout[0].scriptPubKey = CScript() << OP_RETURN << ""_hex;
@@ -853,28 +904,40 @@ BOOST_AUTO_TEST_CASE(test_IsStandard)
853
  t.vout[0].scriptPubKey = CScript() << OP_RETURN;
854
  CheckIsStandard(t);
855
 
856
- // Multiple TxoutType::NULL_DATA are permitted
857
  t.vout.resize(2);
858
  t.vout[0].scriptPubKey = CScript() << OP_RETURN << "04678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef38"_hex;
859
  t.vout[0].nValue = 0;
860
  t.vout[1].scriptPubKey = CScript() << OP_RETURN << "04678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef38"_hex;
861
  t.vout[1].nValue = 0;
862
- CheckIsStandard(t);
 
863
 
864
  t.vout[0].scriptPubKey = CScript() << OP_RETURN << "04678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef38"_hex;
865
  t.vout[1].scriptPubKey = CScript() << OP_RETURN;
866
- CheckIsStandard(t);
 
867
 
868
  t.vout[0].scriptPubKey = CScript() << OP_RETURN;
869
  t.vout[1].scriptPubKey = CScript() << OP_RETURN;
870
- CheckIsStandard(t);
 
871
 
872
  t.vout[0].scriptPubKey = CScript() << OP_RETURN << "04678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef3804678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef38"_hex;
873
  t.vout[1].scriptPubKey = CScript() << OP_RETURN << "04678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef3804678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef38"_hex;
874
  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);
 
 
 
 
 
 
 
 
 
878
 
879
  // Check large scriptSig (non-standard if size is >1650 bytes)
880
  t.vout.resize(1);
@@ -937,16 +1000,16 @@ BOOST_AUTO_TEST_CASE(test_IsStandard)
937
  BOOST_CHECK_EQUAL(GetTransactionWeight(CTransaction(t)), 400004);
938
  CheckIsNotStandard(t, "tx-size");
939
 
940
- // Check bare multisig (standard if policy flag g_bare_multi is set)
941
- g_bare_multi = true;
942
  t.vout[0].scriptPubKey = GetScriptForMultisig(1, {key.GetPubKey()}); // simple 1-of-1
943
  t.vin.resize(1);
944
  t.vin[0].scriptSig = CScript() << std::vector<unsigned char>(65, 0);
945
  CheckIsStandard(t);
946
 
947
- g_bare_multi = false;
948
  CheckIsNotStandard(t, "bare-multisig");
949
- g_bare_multi = DEFAULT_PERMIT_BAREMULTISIG;
950
 
951
  // Add dust outputs up to allowed maximum
952
  assert(t.vout.size() == 1);
@@ -1005,6 +1068,9 @@ BOOST_AUTO_TEST_CASE(test_IsStandard)
1005
  for (int op = OP_1; op <= OP_16; op += 1) {
1006
  t.vout[0].scriptPubKey = CScript() << (opcodetype)op << std::vector<unsigned char>(2, 0);
1007
  t.vout[0].nValue = 240;
 
 
 
1008
  CheckIsStandard(t);
1009
 
1010
  t.vout[0].nValue = 239;
@@ -1018,6 +1084,34 @@ BOOST_AUTO_TEST_CASE(test_IsStandard)
1018
  CheckIsStandard(t);
1019
  t.vout[0].nValue = 239;
1020
  CheckIsNotStandard(t, "dust");
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1021
  }
1022
 
1023
  BOOST_AUTO_TEST_CASE(max_standard_legacy_sigops)
@@ -1115,55 +1209,6 @@ BOOST_AUTO_TEST_CASE(max_standard_legacy_sigops)
1115
  BOOST_CHECK(!::AreInputsStandard(CTransaction(tx_max_sigops), coins));
1116
  }
1117
 
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
  /** Sanity check the return value of SpendsNonAnchorWitnessProg for various output types. */
1168
  BOOST_AUTO_TEST_CASE(spends_witness_prog)
1169
  {
 
14
  #include <consensus/tx_verify.h>
15
  #include <consensus/validation.h>
16
  #include <core_io.h>
17
+ #include <kernel/mempool_options.h>
18
  #include <key.h>
19
  #include <policy/policy.h>
20
  #include <policy/settings.h>
 
50
 
51
  typedef std::vector<unsigned char> valtype;
52
 
53
+
54
+ static kernel::MemPoolOptions g_mempool_opts;
55
 
56
  static const std::map<std::string, script_verify_flag_name>& mapFlagNames = ScriptFlagNamesToEnum();
57
 
 
765
  CKey key = GenerateRandomKey();
766
  t.vout[0].scriptPubKey = GetScriptForDestination(PKHash(key.GetPubKey()));
767
 
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) {
769
  std::string 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));
773
  BOOST_CHECK(reason.empty());
774
  };
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) {
776
  std::string 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));
780
  BOOST_CHECK_EQUAL(reason_in, reason);
781
  };
782
 
783
+ g_mempool_opts.permit_bare_pubkey = true;
784
  CheckIsStandard(t);
785
 
786
+ g_mempool_opts.permitephemeral_anchor = true;
787
+ g_mempool_opts.permitephemeral_dust = true;
788
+ g_mempool_opts.permitephemeral_send = true;
789
+
790
  // Check dust with default relay fee:
791
+ CAmount nDustThreshold = 182 * g_mempool_opts.dust_relay_feerate.GetFeePerK() / 1000;
792
  BOOST_CHECK_EQUAL(nDustThreshold, 546);
793
 
794
  // Add dust outputs up to allowed maximum, still standard!
 
823
 
824
  // Check dust with odd relay fee to verify rounding:
825
  // nDustThreshold = 182 * 3702 / 1000
826
+ g_mempool_opts.dust_relay_feerate = CFeeRate(3702);
827
  // dust:
828
  t.vout[0].nValue = 674 - 1;
829
  CheckIsNotStandard(t, "dust");
830
  // not dust:
831
  t.vout[0].nValue = 674;
832
  CheckIsStandard(t);
833
+ g_mempool_opts.dust_relay_feerate = CFeeRate{DUST_RELAY_TX_FEE};
834
 
835
  t.vout[0].scriptPubKey = CScript() << OP_1;
836
  CheckIsNotStandard(t, "scriptpubkey");
837
 
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;
849
 
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");
886
 
887
  // Data payload can be encoded in any way...
888
  t.vout[0].scriptPubKey = CScript() << OP_RETURN << ""_hex;
 
904
  t.vout[0].scriptPubKey = CScript() << OP_RETURN;
905
  CheckIsStandard(t);
906
 
907
+ // Multiple carriers require an explicit local policy relaxation
908
  t.vout.resize(2);
909
  t.vout[0].scriptPubKey = CScript() << OP_RETURN << "04678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef38"_hex;
910
  t.vout[0].nValue = 0;
911
  t.vout[1].scriptPubKey = CScript() << OP_RETURN << "04678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef38"_hex;
912
  t.vout[1].nValue = 0;
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"});
915
 
916
  t.vout[0].scriptPubKey = CScript() << OP_RETURN << "04678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef38"_hex;
917
  t.vout[1].scriptPubKey = CScript() << OP_RETURN;
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"});
920
 
921
  t.vout[0].scriptPubKey = CScript() << OP_RETURN;
922
  t.vout[1].scriptPubKey = CScript() << OP_RETURN;
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"});
925
 
926
  t.vout[0].scriptPubKey = CScript() << OP_RETURN << "04678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef3804678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef38"_hex;
927
  t.vout[1].scriptPubKey = CScript() << OP_RETURN << "04678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef3804678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef38"_hex;
928
  const auto datacarrier_size = t.vout[0].scriptPubKey.size() + t.vout[1].scriptPubKey.size();
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);
941
 
942
  // Check large scriptSig (non-standard if size is >1650 bytes)
943
  t.vout.resize(1);
 
1000
  BOOST_CHECK_EQUAL(GetTransactionWeight(CTransaction(t)), 400004);
1001
  CheckIsNotStandard(t, "tx-size");
1002
 
1003
+ // Check bare multisig (standard if the policy flag is set)
1004
+ g_mempool_opts.permit_bare_multisig = true;
1005
  t.vout[0].scriptPubKey = GetScriptForMultisig(1, {key.GetPubKey()}); // simple 1-of-1
1006
  t.vin.resize(1);
1007
  t.vin[0].scriptSig = CScript() << std::vector<unsigned char>(65, 0);
1008
  CheckIsStandard(t);
1009
 
1010
+ g_mempool_opts.permit_bare_multisig = false;
1011
  CheckIsNotStandard(t, "bare-multisig");
1012
+ g_mempool_opts.permit_bare_multisig = true;
1013
 
1014
  // Add dust outputs up to allowed maximum
1015
  assert(t.vout.size() == 1);
 
1068
  for (int op = OP_1; op <= OP_16; op += 1) {
1069
  t.vout[0].scriptPubKey = CScript() << (opcodetype)op << std::vector<unsigned char>(2, 0);
1070
  t.vout[0].nValue = 240;
1071
+ g_mempool_opts.acceptunknownwitness = false;
1072
+ CheckIsNotStandard(t, "scriptpubkey-unknown-witnessversion");
1073
+ g_mempool_opts.acceptunknownwitness = true;
1074
  CheckIsStandard(t);
1075
 
1076
  t.vout[0].nValue = 239;
 
1084
  CheckIsStandard(t);
1085
  t.vout[0].nValue = 239;
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);
1115
  }
1116
 
1117
  BOOST_AUTO_TEST_CASE(max_standard_legacy_sigops)
 
1209
  BOOST_CHECK(!::AreInputsStandard(CTransaction(tx_max_sigops), coins));
1210
  }
1211
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1212
  /** Sanity check the return value of SpendsNonAnchorWitnessProg for various output types. */
1213
  BOOST_AUTO_TEST_CASE(spends_witness_prog)
1214
  {