Skip to content
Bitcoin Roots

v29.4-roots.3 · Commit 3: [PATCH 03/30] policy: restore conservative relay and network controls

src/test/transaction_tests.cpp

Before: src/test/transaction_tests.cpp · After: src/test/transaction_tests.cpp

File metadata
index 5844ab23bc8d2984ebbaab4416d107959c48adc1..c0d7f0d29e90caba9047994fa7405b85e72ef193 100644

Download original patch · Release notes

Diff rows 1–192 of 192. 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
@@ -13,6 +13,7 @@
13
  #include <consensus/tx_verify.h>
14
  #include <consensus/validation.h>
15
  #include <core_io.h>
 
16
  #include <key.h>
17
  #include <policy/policy.h>
18
  #include <policy/settings.h>
@@ -46,8 +47,7 @@ using util::ToString;
46
 
47
  typedef std::vector<unsigned char> valtype;
48
 
49
- static CFeeRate g_dust{DUST_RELAY_TX_FEE};
50
- static bool g_bare_multi{DEFAULT_PERMIT_BAREMULTISIG};
51
 
52
  static std::map<std::string, unsigned int> mapFlagNames = {
53
  {std::string("P2SH"), (unsigned int)SCRIPT_VERIFY_P2SH},
@@ -800,19 +800,24 @@ BOOST_AUTO_TEST_CASE(test_IsStandard)
800
 
801
  constexpr auto CheckIsStandard = [](const auto& t) {
802
  std::string reason;
803
- BOOST_CHECK(IsStandardTx(CTransaction{t}, MAX_OP_RETURN_RELAY, g_bare_multi, g_dust, reason));
804
  BOOST_CHECK(reason.empty());
805
  };
806
  constexpr auto CheckIsNotStandard = [](const auto& t, const std::string& reason_in) {
807
  std::string reason;
808
- BOOST_CHECK(!IsStandardTx(CTransaction{t}, MAX_OP_RETURN_RELAY, g_bare_multi, g_dust, reason));
809
  BOOST_CHECK_EQUAL(reason_in, reason);
810
  };
811
 
 
812
  CheckIsStandard(t);
813
 
 
 
 
 
814
  // Check dust with default relay fee:
815
- CAmount nDustThreshold = 182 * g_dust.GetFeePerK() / 1000;
816
  BOOST_CHECK_EQUAL(nDustThreshold, 546);
817
 
818
  // Add dust outputs up to allowed maximum, still standard!
@@ -847,25 +852,64 @@ BOOST_AUTO_TEST_CASE(test_IsStandard)
847
 
848
  // Check dust with odd relay fee to verify rounding:
849
  // nDustThreshold = 182 * 3702 / 1000
850
- g_dust = CFeeRate(3702);
851
  // dust:
852
  t.vout[0].nValue = 674 - 1;
853
  CheckIsNotStandard(t, "dust");
854
  // not dust:
855
  t.vout[0].nValue = 674;
856
  CheckIsStandard(t);
857
- g_dust = CFeeRate{DUST_RELAY_TX_FEE};
858
 
859
  t.vout[0].scriptPubKey = CScript() << OP_1;
860
  CheckIsNotStandard(t, "scriptpubkey");
861
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
862
  // MAX_OP_RETURN_RELAY-byte TxoutType::NULL_DATA (standard)
863
- t.vout[0].scriptPubKey = CScript() << OP_RETURN << "04678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef3804678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef38"_hex;
 
 
 
 
864
  BOOST_CHECK_EQUAL(MAX_OP_RETURN_RELAY, t.vout[0].scriptPubKey.size());
865
  CheckIsStandard(t);
866
 
867
  // MAX_OP_RETURN_RELAY+1-byte TxoutType::NULL_DATA (non-standard)
868
- t.vout[0].scriptPubKey = CScript() << OP_RETURN << "04678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef3804678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef3800"_hex;
869
  BOOST_CHECK_EQUAL(MAX_OP_RETURN_RELAY + 1, t.vout[0].scriptPubKey.size());
870
  CheckIsNotStandard(t, "scriptpubkey");
871
 
@@ -901,9 +945,15 @@ BOOST_AUTO_TEST_CASE(test_IsStandard)
901
  t.vout[1].scriptPubKey = CScript() << OP_RETURN;
902
  CheckIsNotStandard(t, "multi-op-return");
903
 
904
- t.vout[0].scriptPubKey = CScript() << OP_RETURN;
905
- t.vout[1].scriptPubKey = CScript() << OP_RETURN;
906
- CheckIsNotStandard(t, "multi-op-return");
 
 
 
 
 
 
907
 
908
  // Check large scriptSig (non-standard if size is >1650 bytes)
909
  t.vout.resize(1);
@@ -966,16 +1016,16 @@ BOOST_AUTO_TEST_CASE(test_IsStandard)
966
  BOOST_CHECK_EQUAL(GetTransactionWeight(CTransaction(t)), 400004);
967
  CheckIsNotStandard(t, "tx-size");
968
 
969
- // Check bare multisig (standard if policy flag g_bare_multi is set)
970
- g_bare_multi = true;
971
  t.vout[0].scriptPubKey = GetScriptForMultisig(1, {key.GetPubKey()}); // simple 1-of-1
972
  t.vin.resize(1);
973
  t.vin[0].scriptSig = CScript() << std::vector<unsigned char>(65, 0);
974
  CheckIsStandard(t);
975
 
976
- g_bare_multi = false;
977
  CheckIsNotStandard(t, "bare-multisig");
978
- g_bare_multi = DEFAULT_PERMIT_BAREMULTISIG;
979
 
980
  // Add dust outputs up to allowed maximum
981
  assert(t.vout.size() == 1);
@@ -1034,6 +1084,9 @@ BOOST_AUTO_TEST_CASE(test_IsStandard)
1034
  for (int op = OP_1; op <= OP_16; op += 1) {
1035
  t.vout[0].scriptPubKey = CScript() << (opcodetype)op << std::vector<unsigned char>(2, 0);
1036
  t.vout[0].nValue = 240;
 
 
 
1037
  CheckIsStandard(t);
1038
 
1039
  t.vout[0].nValue = 239;
@@ -1047,6 +1100,34 @@ BOOST_AUTO_TEST_CASE(test_IsStandard)
1047
  CheckIsStandard(t);
1048
  t.vout[0].nValue = 239;
1049
  CheckIsNotStandard(t, "dust");
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1050
  }
1051
 
1052
  BOOST_AUTO_TEST_CASE(max_standard_legacy_sigops)
 
13
  #include <consensus/tx_verify.h>
14
  #include <consensus/validation.h>
15
  #include <core_io.h>
16
+ #include <kernel/mempool_options.h>
17
  #include <key.h>
18
  #include <policy/policy.h>
19
  #include <policy/settings.h>
 
47
 
48
  typedef std::vector<unsigned char> valtype;
49
 
50
+ static kernel::MemPoolOptions g_mempool_opts;
 
51
 
52
  static std::map<std::string, unsigned int> mapFlagNames = {
53
  {std::string("P2SH"), (unsigned int)SCRIPT_VERIFY_P2SH},
 
800
 
801
  constexpr auto CheckIsStandard = [](const auto& t) {
802
  std::string reason;
803
+ BOOST_CHECK(IsStandardTx(CTransaction{t}, g_mempool_opts, reason));
804
  BOOST_CHECK(reason.empty());
805
  };
806
  constexpr auto CheckIsNotStandard = [](const auto& t, const std::string& reason_in) {
807
  std::string reason;
808
+ BOOST_CHECK(!IsStandardTx(CTransaction{t}, g_mempool_opts, reason));
809
  BOOST_CHECK_EQUAL(reason_in, reason);
810
  };
811
 
812
+ g_mempool_opts.permit_bare_pubkey = true;
813
  CheckIsStandard(t);
814
 
815
+ g_mempool_opts.permitephemeral_anchor = true;
816
+ g_mempool_opts.permitephemeral_dust = true;
817
+ g_mempool_opts.permitephemeral_send = true;
818
+
819
  // Check dust with default relay fee:
820
+ CAmount nDustThreshold = 182 * g_mempool_opts.dust_relay_feerate.GetFeePerK() / 1000;
821
  BOOST_CHECK_EQUAL(nDustThreshold, 546);
822
 
823
  // Add dust outputs up to allowed maximum, still standard!
 
852
 
853
  // Check dust with odd relay fee to verify rounding:
854
  // nDustThreshold = 182 * 3702 / 1000
855
+ g_mempool_opts.dust_relay_feerate = CFeeRate(3702);
856
  // dust:
857
  t.vout[0].nValue = 674 - 1;
858
  CheckIsNotStandard(t, "dust");
859
  // not dust:
860
  t.vout[0].nValue = 674;
861
  CheckIsStandard(t);
862
+ g_mempool_opts.dust_relay_feerate = CFeeRate{DUST_RELAY_TX_FEE};
863
 
864
  t.vout[0].scriptPubKey = CScript() << OP_1;
865
  CheckIsNotStandard(t, "scriptpubkey");
866
 
867
+ // Test rejectparasites
868
+ t.vout[0].scriptPubKey = CScript() << OP_RETURN;
869
+ t.vout.emplace_back(674, GetScriptForDestination(PKHash(key.GetPubKey())));
870
+ t.nLockTime = 21;
871
+ g_mempool_opts.reject_parasites = false;
872
+ CheckIsStandard(t);
873
+ g_mempool_opts.reject_parasites = true;
874
+ CheckIsNotStandard(t, "parasite-cat21");
875
+ t.nLockTime = 0;
876
+ CheckIsStandard(t);
877
+ g_mempool_opts.reject_parasites = false;
878
+
879
+ // Test rejecttokens
880
+ t.vout[0].scriptPubKey = CScript() << OP_RETURN << OP_13 << OP_FALSE;
881
+ g_mempool_opts.reject_tokens = false;
882
+ CheckIsStandard(t);
883
+ g_mempool_opts.reject_tokens = true;
884
+ CheckIsNotStandard(t, "tokens-runes");
885
+ // At least one data push is needed after OP_13 to match
886
+ t.vout[0].scriptPubKey = CScript() << OP_RETURN << OP_13;
887
+ CheckIsStandard(t);
888
+ // Test rejecttokens applying to OLGA
889
+ const auto olga_header = CScript() << OP_0 << "003e7374616d703a000000000000000000000000000000000000000000000000"_hex;
890
+ t.vout[0].scriptPubKey = olga_header;
891
+ t.vout.resize(1);
892
+ // Missing a second output, so not OLGA
893
+ CheckIsStandard(t);
894
+ t.vout.emplace_back(1000, olga_header);
895
+ CheckIsNotStandard(t, "tokens-olga");
896
+ t.vout.emplace_back(1000, olga_header);
897
+ CheckIsNotStandard(t, "tokens-olga");
898
+ g_mempool_opts.reject_tokens = false;
899
+ CheckIsStandard(t);
900
+ t.vout.resize(1);
901
+
902
  // MAX_OP_RETURN_RELAY-byte TxoutType::NULL_DATA (standard)
903
+ g_mempool_opts.permitbaredatacarrier = true;
904
+ t.vout[0].scriptPubKey = CScript() << OP_RETURN;
905
+ while (t.vout[0].scriptPubKey.size() < MAX_OP_RETURN_RELAY) {
906
+ t.vout[0].scriptPubKey << OP_0;
907
+ }
908
  BOOST_CHECK_EQUAL(MAX_OP_RETURN_RELAY, t.vout[0].scriptPubKey.size());
909
  CheckIsStandard(t);
910
 
911
  // MAX_OP_RETURN_RELAY+1-byte TxoutType::NULL_DATA (non-standard)
912
+ t.vout[0].scriptPubKey << OP_0;
913
  BOOST_CHECK_EQUAL(MAX_OP_RETURN_RELAY + 1, t.vout[0].scriptPubKey.size());
914
  CheckIsNotStandard(t, "scriptpubkey");
915
 
 
945
  t.vout[1].scriptPubKey = CScript() << OP_RETURN;
946
  CheckIsNotStandard(t, "multi-op-return");
947
 
948
+ // Test permitbaredatacarrier
949
+ g_mempool_opts.permitbaredatacarrier = false;
950
+ t.vout[1].scriptPubKey = GetScriptForDestination(PKHash(key.GetPubKey()));
951
+ t.vout[1].nValue = COIN;
952
+ CheckIsStandard(t);
953
+ t.vout.resize(1);
954
+ CheckIsNotStandard(t, "bare-datacarrier");
955
+ g_mempool_opts.permitbaredatacarrier = true;
956
+ CheckIsStandard(t);
957
 
958
  // Check large scriptSig (non-standard if size is >1650 bytes)
959
  t.vout.resize(1);
 
1016
  BOOST_CHECK_EQUAL(GetTransactionWeight(CTransaction(t)), 400004);
1017
  CheckIsNotStandard(t, "tx-size");
1018
 
1019
+ // Check bare multisig (standard if the policy flag is set)
1020
+ g_mempool_opts.permit_bare_multisig = true;
1021
  t.vout[0].scriptPubKey = GetScriptForMultisig(1, {key.GetPubKey()}); // simple 1-of-1
1022
  t.vin.resize(1);
1023
  t.vin[0].scriptSig = CScript() << std::vector<unsigned char>(65, 0);
1024
  CheckIsStandard(t);
1025
 
1026
+ g_mempool_opts.permit_bare_multisig = false;
1027
  CheckIsNotStandard(t, "bare-multisig");
1028
+ g_mempool_opts.permit_bare_multisig = true;
1029
 
1030
  // Add dust outputs up to allowed maximum
1031
  assert(t.vout.size() == 1);
 
1084
  for (int op = OP_1; op <= OP_16; op += 1) {
1085
  t.vout[0].scriptPubKey = CScript() << (opcodetype)op << std::vector<unsigned char>(2, 0);
1086
  t.vout[0].nValue = 240;
1087
+ g_mempool_opts.acceptunknownwitness = false;
1088
+ CheckIsNotStandard(t, "scriptpubkey-unknown-witnessversion");
1089
+ g_mempool_opts.acceptunknownwitness = true;
1090
  CheckIsStandard(t);
1091
 
1092
  t.vout[0].nValue = 239;
 
1100
  CheckIsStandard(t);
1101
  t.vout[0].nValue = 239;
1102
  CheckIsNotStandard(t, "dust");
1103
+
1104
+ // Test permitbareanchor
1105
+ g_mempool_opts.permitbareanchor = false;
1106
+ t.vout[1].scriptPubKey = GetScriptForDestination(PKHash(key.GetPubKey()));
1107
+ t.vout[1].nValue = COIN;
1108
+ CheckIsStandard(t);
1109
+ t.vout.resize(1);
1110
+ CheckIsNotStandard(t, "bare-anchor");
1111
+ g_mempool_opts.permitbareanchor = true;
1112
+ CheckIsStandard(t);
1113
+
1114
+ // Test permitephemeral
1115
+ g_mempool_opts.permitephemeral_anchor = false;
1116
+ CheckIsNotStandard(t, "anchor");
1117
+ t.vout[0].nValue = 0;
1118
+ CheckIsNotStandard(t, "anchor");
1119
+ g_mempool_opts.permitephemeral_anchor = true;
1120
+ g_mempool_opts.permitephemeral_dust = false;
1121
+ CheckIsStandard(t);
1122
+ t.vout[0].nValue = 1;
1123
+ CheckIsNotStandard(t, "dust-nonzero");
1124
+ g_mempool_opts.permitephemeral_dust = true;
1125
+ g_mempool_opts.permitephemeral_send = false;
1126
+ CheckIsStandard(t);
1127
+ t.vout[0].scriptPubKey = GetScriptForDestination(PKHash(key.GetPubKey()));
1128
+ CheckIsNotStandard(t, "dust-nonanchor");
1129
+ g_mempool_opts.permitephemeral_send = true;
1130
+ CheckIsStandard(t);
1131
  }
1132
 
1133
  BOOST_AUTO_TEST_CASE(max_standard_legacy_sigops)