@@ -1066,5 +1066,234 @@ BOOST_AUTO_TEST_SUITE(slice_tests)
10661066 BOOST_REQUIRE (!block2);
10671067 }
10681068
1069+ // Verify basics of get_trx_block_number()
1070+ BOOST_FIXTURE_TEST_CASE (test_get_trx_block_number_basic, test_fixture)
1071+ {
1072+ chain::transaction_id_type trx_id1 = " 0000000000000000000000000000000000000000000000000000000000000001" _h;
1073+ chain::transaction_id_type trx_id2 = " 0000000000000000000000000000000000000000000000000000000000000002" _h;
1074+ uint32_t block_num1 = 1 ;
1075+ uint32_t block_num2 = 2 ;
1076+
1077+ transaction_trace_v2 trx_trace1 {
1078+ trx_id1,
1079+ actions,
1080+ fc::enum_type<uint8_t , chain::transaction_receipt_header::status_enum>{chain::transaction_receipt_header::status_enum::executed},
1081+ 10 ,
1082+ 5 ,
1083+ { chain::signature_type () },
1084+ { chain::time_point_sec (), 1 , 0 , 100 , 50 , 0 }
1085+ };
1086+
1087+ transaction_trace_v2 trx_trace2 {
1088+ trx_id2,
1089+ actions,
1090+ fc::enum_type<uint8_t , chain::transaction_receipt_header::status_enum>{chain::transaction_receipt_header::status_enum::executed},
1091+ 10 ,
1092+ 5 ,
1093+ { chain::signature_type () },
1094+ { chain::time_point_sec (), 1 , 0 , 100 , 50 , 0 }
1095+ };
1096+
1097+ // block 1 includes trx_trace1
1098+ block_trace_v2 block_trace1 {
1099+ " b000000000000000000000000000000000000000000000000000000000000001" _h,
1100+ block_num1,
1101+ " 0000000000000000000000000000000000000000000000000000000000000000" _h,
1102+ chain::block_timestamp_type (0 ),
1103+ " test" _n,
1104+ " 0000000000000000000000000000000000000000000000000000000000000000" _h,
1105+ " 0000000000000000000000000000000000000000000000000000000000000000" _h,
1106+ 0 ,
1107+ std::vector<transaction_trace_v2> {
1108+ trx_trace1
1109+ }
1110+ };
1111+
1112+ // block 2 includes trx_trace2
1113+ block_trace_v2 block_trace2 {
1114+ " b000000000000000000000000000000000000000000000000000000000000003" _h,
1115+ block_num2,
1116+ " 0000000000000000000000000000000000000000000000000000000000000000" _h,
1117+ chain::block_timestamp_type (0 ),
1118+ " test" _n,
1119+ " 0000000000000000000000000000000000000000000000000000000000000000" _h,
1120+ " 0000000000000000000000000000000000000000000000000000000000000000" _h,
1121+ 0 ,
1122+ std::vector<transaction_trace_v2> {
1123+ trx_trace2
1124+ }
1125+ };
1126+
1127+ block_trxs_entry block_trxs_entry1 {
1128+ .ids = {trx_id1},
1129+ .block_num = block_num1
1130+ };
1131+
1132+ block_trxs_entry block_trxs_entry2 {
1133+ .ids = {trx_id2},
1134+ .block_num = block_num2
1135+ };
1136+
1137+ fc::temp_directory tempdir;
1138+ store_provider sp (tempdir.path (), 100 , std::optional<uint32_t >(), std::optional<uint32_t >(), 0 );
1139+
1140+ // on_accepted_block of block 1
1141+ sp.append (block_trace1);
1142+ sp.append_trx_ids (block_trxs_entry1);
1143+
1144+ // block 1 is reversible and get_trx_block_number should find trx_id1 in block 1
1145+ get_block_n block_num = sp.get_trx_block_number (trx_id1, {});
1146+ BOOST_REQUIRE (block_num);
1147+ BOOST_REQUIRE_EQUAL (*block_num, block_num1);
1148+
1149+ // block 1 becomes final
1150+ sp.append_lib (block_num1);
1151+
1152+ // get_trx_block_number should find trx_id1 in block 1
1153+ block_num = sp.get_trx_block_number (trx_id1, {});
1154+ BOOST_REQUIRE (block_num);
1155+ BOOST_REQUIRE_EQUAL (*block_num, block_num1);
1156+
1157+ // on_accepted_block of block 2
1158+ sp.append (block_trace2);
1159+ sp.append_trx_ids (block_trxs_entry2);
1160+
1161+ // get_trx_block_number should find both trx_id1 and trx_id2
1162+ block_num = sp.get_trx_block_number (trx_id1, {});
1163+ BOOST_REQUIRE (block_num);
1164+ BOOST_REQUIRE_EQUAL (*block_num, block_num1);
1165+ block_num = sp.get_trx_block_number (trx_id2, {});
1166+ BOOST_REQUIRE (block_num);
1167+ BOOST_REQUIRE_EQUAL (*block_num, block_num2);
1168+
1169+ // block 2 becomes final
1170+ sp.append_lib (block_num2);
1171+
1172+ // get_trx_block_number should still find both trx_id1 and trx_id2
1173+ block_num = sp.get_trx_block_number (trx_id1, {});
1174+ BOOST_REQUIRE (block_num);
1175+ BOOST_REQUIRE_EQUAL (*block_num, block_num1);
1176+ block_num = sp.get_trx_block_number (trx_id2, {});
1177+ BOOST_REQUIRE (block_num);
1178+ BOOST_REQUIRE_EQUAL (*block_num, block_num2);
1179+ }
1180+
1181+ // This test verifies the bug reported by https://github.com/AntelopeIO/spring/issues/942
1182+ // is fixed. The bug was if the block containing a transaction forked out,
1183+ // get_trx_block_number() always returned the latest block whose block number was
1184+ // the same as the initial block's, but this latest block might not include the
1185+ // transaction anymore.
1186+ BOOST_FIXTURE_TEST_CASE (test_get_trx_block_number_forked, test_fixture)
1187+ {
1188+ chain::transaction_id_type target_trx_id = " 0000000000000000000000000000000000000000000000000000000000000001" _h;
1189+ uint32_t initial_block_num = 1 ;
1190+ uint32_t final_block_num = 3 ;
1191+
1192+ transaction_trace_v2 trx_trace1 {
1193+ target_trx_id,
1194+ actions,
1195+ fc::enum_type<uint8_t , chain::transaction_receipt_header::status_enum>{chain::transaction_receipt_header::status_enum::executed},
1196+ 10 ,
1197+ 5 ,
1198+ { chain::signature_type () },
1199+ { chain::time_point_sec (), 1 , 0 , 100 , 50 , 0 }
1200+ };
1201+
1202+ transaction_trace_v2 trx_trace2 {
1203+ " 0000000000000000000000000000000000000000000000000000000000000002" _h,
1204+ actions,
1205+ fc::enum_type<uint8_t , chain::transaction_receipt_header::status_enum>{chain::transaction_receipt_header::status_enum::executed},
1206+ 10 ,
1207+ 5 ,
1208+ { chain::signature_type () },
1209+ { chain::time_point_sec (), 1 , 0 , 100 , 50 , 0 }
1210+ };
1211+
1212+ // Initial block including trx_trace1
1213+ block_trace_v2 initial_block_trace {
1214+ " b000000000000000000000000000000000000000000000000000000000000001" _h,
1215+ initial_block_num,
1216+ " 0000000000000000000000000000000000000000000000000000000000000000" _h,
1217+ chain::block_timestamp_type (0 ),
1218+ " test" _n,
1219+ " 0000000000000000000000000000000000000000000000000000000000000000" _h,
1220+ " 0000000000000000000000000000000000000000000000000000000000000000" _h,
1221+ 0 ,
1222+ std::vector<transaction_trace_v2> {
1223+ trx_trace1
1224+ }
1225+ };
1226+
1227+ // Initial block is forked. The original trx_trace1 is forked out and
1228+ // replaced by trx_trace2.
1229+ block_trace_v2 forked_block_trace = initial_block_trace;
1230+ forked_block_trace.transactions = std::vector<transaction_trace_v2> { trx_trace2 };
1231+
1232+ // Final block including original trx_trace1
1233+ block_trace_v2 final_block_trace {
1234+ " b000000000000000000000000000000000000000000000000000000000000003" _h,
1235+ final_block_num,
1236+ " 0000000000000000000000000000000000000000000000000000000000000000" _h,
1237+ chain::block_timestamp_type (0 ),
1238+ " test" _n,
1239+ " 0000000000000000000000000000000000000000000000000000000000000000" _h,
1240+ " 0000000000000000000000000000000000000000000000000000000000000000" _h,
1241+ 0 ,
1242+ std::vector<transaction_trace_v2> {
1243+ trx_trace1
1244+ }
1245+ };
1246+
1247+ block_trxs_entry initial_block_trxs_entry {
1248+ .ids = {target_trx_id},
1249+ .block_num = initial_block_num
1250+ };
1251+
1252+ block_trxs_entry forked_block_trxs_entry {
1253+ .ids = {trx_trace2.id },
1254+ .block_num = initial_block_num
1255+ };
1256+
1257+ block_trxs_entry final_block_trxs_entry {
1258+ .ids = {target_trx_id},
1259+ .block_num = final_block_num
1260+ };
1261+
1262+ fc::temp_directory tempdir;
1263+ store_provider sp (tempdir.path (), 100 , std::optional<uint32_t >(), std::optional<uint32_t >(), 0 );
1264+
1265+ // on_accepted_block of the initial block
1266+ sp.append (initial_block_trace); // block 1
1267+ sp.append_trx_ids (initial_block_trxs_entry); // block 1
1268+
1269+ // target trx is in the first block (is still reversible)
1270+ get_block_n block_num = sp.get_trx_block_number (target_trx_id, {});
1271+ BOOST_REQUIRE (block_num);
1272+ BOOST_REQUIRE_EQUAL (*block_num, initial_block_num);
1273+
1274+ // initial block forks out
1275+ sp.append (forked_block_trace); // block 1
1276+ sp.append_trx_ids (forked_block_trxs_entry); // block 1
1277+
1278+ // forked block becomes final
1279+ sp.append_lib (initial_block_num); // block 1
1280+
1281+ // target trx is forked out. block 1 does not include
1282+ // target_trx (trx_trace1) but trx_trace2;
1283+ // therefore no block is found for target_trx_id.
1284+ block_num = sp.get_trx_block_number (target_trx_id, {});
1285+ BOOST_REQUIRE (!block_num);
1286+
1287+ // on_accepted_block of the final block
1288+ sp.append (final_block_trace); // block 3
1289+ sp.append_trx_ids (final_block_trxs_entry); // block 3
1290+
1291+ // final block becomes final
1292+ sp.append_lib (final_block_num); // block 3
1293+
1294+ block_num = sp.get_trx_block_number (target_trx_id, {});
1295+ BOOST_REQUIRE (block_num);
1296+ BOOST_REQUIRE_EQUAL (*block_num, final_block_num); // target trx is in final block
1297+ }
10691298
10701299BOOST_AUTO_TEST_SUITE_END ()
0 commit comments