@@ -438,33 +438,57 @@ def setup_new_gen(
438
438
# we also use BlockBuilder to compress these transactions as well.
439
439
assert wallet is not None
440
440
assert rng is not None
441
- # these never reset, we keep adding to them until we reach the target cost
442
- ADJUSTED_MAX_COST : uint64 = uint64 (test_constants .MAX_BLOCK_COST_CLVM * block_fillrate / 100 )
441
+ # function constants
442
+ adjusted_max_cost : uint64 = uint64 (self .constants .MAX_BLOCK_COST_CLVM * block_fillrate / 100 )
443
+ static_cost : uint64 = uint64 (4839648 ) # cond + exec cost per sb
444
+ static_comp_cost : uint64 = uint64 (7684000 ) # byte cost per sb after compression
445
+ max_batch_size : int = int (1400 * 0.10 * block_fillrate / 100 ) # 10% of the way done with the block
446
+
447
+ # start building the block
448
+ avail_coins : set [Coin ] = available_coins .copy () # don't modify the original set
443
449
builder : BlockBuilder = BlockBuilder ()
450
+ block_full = False
451
+ total_cost : uint64 = uint64 (0 )
444
452
additions = []
445
453
removals = []
446
- avail_coins : set [Coin ] = available_coins .copy ()
447
454
455
+ batch_bundles : list [SpendBundle ] = []
456
+ batch_removals : list [Coin ] = []
457
+ batch_additions : list [Coin ] = []
448
458
while len (avail_coins ) > 0 :
449
- # This is simplified logic from the mempool, as we can afford to be inefficient here.
450
-
459
+ val_after_next_sb = (len (batch_bundles ) + 1 ) * static_comp_cost + total_cost
460
+ if val_after_next_sb > adjusted_max_cost or len (batch_bundles ) == max_batch_size :
461
+ # max batch size used to allow the cost to better match reality
462
+ added , block_full = builder .add_spend_bundles (
463
+ batch_bundles , uint64 (static_cost * len (batch_bundles )), self .constants
464
+ )
465
+ total_cost = builder .cost ()
466
+ if added :
467
+ removals .extend (batch_removals )
468
+ additions .extend (batch_additions )
469
+ elif not added :
470
+ # if it wasn't added, we put the coin back
471
+ avail_coins .update (batch_removals )
472
+ if block_full or total_cost > adjusted_max_cost :
473
+ break
474
+ batch_bundles = []
475
+ batch_removals = []
476
+ batch_additions = []
451
477
new_selection = avail_coins .pop () # this is what we would also add to removals
452
478
new_spend , new_additions = make_sb (wallet , new_selection )
453
- spend_cost : uint64 = uint64 (155000000 ) # TODO: Get Real Cost
454
-
455
- added , done = builder .add_spend_bundles ([new_spend ], spend_cost , test_constants )
456
- total_cost : uint64 = builder .cost ()
457
-
458
- if added :
459
- removals .append (new_selection )
460
- additions .extend (new_additions )
461
- elif not added :
462
- # if it wasn't added, we put the coin back
463
- avail_coins .add (new_selection )
464
- if done or total_cost > ADJUSTED_MAX_COST :
465
- break
479
+ batch_removals .append (new_selection )
480
+ batch_additions .extend (new_additions )
481
+ batch_bundles .append (new_spend )
482
+
483
+ if len (batch_bundles ) > 0 and not block_full :
484
+ added , _ = builder .add_spend_bundles (
485
+ batch_bundles , uint64 (static_cost * len (batch_bundles )), self .constants
486
+ )
487
+ assert added
488
+ removals .extend (batch_removals )
489
+ additions .extend (batch_additions )
466
490
467
- block_program , signature , final_cost = builder .finalize (test_constants )
491
+ block_program , signature , final_cost = builder .finalize (self . constants )
468
492
return NewBlockGenerator (
469
493
SerializedProgram .from_bytes (block_program ),
470
494
[],
@@ -796,6 +820,7 @@ def get_consecutive_blocks(
796
820
tx_block_heights .append (b .height )
797
821
798
822
constants = self .constants
823
+ new_gen_cache : Optional [NewBlockGenerator ] = None
799
824
800
825
if time_per_block is None :
801
826
time_per_block = float (constants .SUB_SLOT_TIME_TARGET ) / float (constants .SLOT_BLOCKS_TARGET )
@@ -976,20 +1001,22 @@ def get_consecutive_blocks(
976
1001
pool_target = PoolTarget (pool_reward_puzzle_hash , uint32 (0 ))
977
1002
else :
978
1003
pool_target = PoolTarget (self .pool_ph , uint32 (0 ))
979
-
980
- new_gen = self .setup_new_gen (
981
- tx_block_heights ,
982
- curr ,
983
- wallet ,
984
- rng ,
985
- self .available_coins ,
986
- prev_tx_height = prev_tx_height ,
987
- dummy_block_references = dummy_block_references ,
988
- transaction_data = transaction_data ,
989
- include_transactions = include_transactions ,
990
- block_refs = block_refs ,
991
- block_fillrate = block_fillrate ,
992
- )
1004
+ if new_gen_cache is None :
1005
+ new_gen = self .setup_new_gen (
1006
+ tx_block_heights ,
1007
+ curr ,
1008
+ wallet ,
1009
+ rng ,
1010
+ self .available_coins ,
1011
+ prev_tx_height = prev_tx_height ,
1012
+ dummy_block_references = dummy_block_references ,
1013
+ transaction_data = transaction_data ,
1014
+ include_transactions = include_transactions ,
1015
+ block_refs = block_refs ,
1016
+ block_fillrate = block_fillrate ,
1017
+ )
1018
+ else :
1019
+ new_gen = new_gen_cache
993
1020
994
1021
(
995
1022
full_block ,
@@ -1028,8 +1055,11 @@ def get_consecutive_blocks(
1028
1055
block_refs = []
1029
1056
keep_going_until_tx_block = False
1030
1057
assert full_block .foliage_transaction_block is not None
1031
- elif guarantee_transaction_block :
1032
- continue
1058
+ new_gen_cache = None
1059
+ elif keep_going_until_tx_block or guarantee_transaction_block :
1060
+ new_gen_cache = new_gen # cache the generator for the next block
1061
+ if guarantee_transaction_block :
1062
+ continue
1033
1063
# print(f"{full_block.height:4}: difficulty {difficulty} "
1034
1064
# f"time: {new_timestamp - last_timestamp:0.2f} "
1035
1065
# f"additions: {len(new_gen.additions) if block_record.is_transaction_block else 0:2} "
@@ -1275,20 +1305,22 @@ def get_consecutive_blocks(
1275
1305
else :
1276
1306
pool_target = PoolTarget (self .pool_ph , uint32 (0 ))
1277
1307
1278
- new_gen = self .setup_new_gen (
1279
- tx_block_heights ,
1280
- curr ,
1281
- wallet ,
1282
- rng ,
1283
- self .available_coins ,
1284
- prev_tx_height = prev_tx_height ,
1285
- dummy_block_references = dummy_block_references ,
1286
- transaction_data = transaction_data ,
1287
- include_transactions = include_transactions ,
1288
- block_refs = block_refs ,
1289
- block_fillrate = block_fillrate ,
1290
- )
1291
-
1308
+ if new_gen_cache is None :
1309
+ new_gen = self .setup_new_gen (
1310
+ tx_block_heights ,
1311
+ curr ,
1312
+ wallet ,
1313
+ rng ,
1314
+ self .available_coins ,
1315
+ prev_tx_height = prev_tx_height ,
1316
+ dummy_block_references = dummy_block_references ,
1317
+ transaction_data = transaction_data ,
1318
+ include_transactions = include_transactions ,
1319
+ block_refs = block_refs ,
1320
+ block_fillrate = block_fillrate ,
1321
+ )
1322
+ else :
1323
+ new_gen = new_gen_cache
1292
1324
(
1293
1325
full_block ,
1294
1326
block_record ,
@@ -1326,8 +1358,11 @@ def get_consecutive_blocks(
1326
1358
block_refs = []
1327
1359
keep_going_until_tx_block = False
1328
1360
assert full_block .foliage_transaction_block is not None
1329
- elif guarantee_transaction_block :
1330
- continue
1361
+ new_gen_cache = None
1362
+ elif keep_going_until_tx_block or guarantee_transaction_block :
1363
+ new_gen_cache = new_gen # cache the generator for the next block
1364
+ if guarantee_transaction_block :
1365
+ continue
1331
1366
# print(f"{full_block.height:4}: difficulty {difficulty} "
1332
1367
# f"time: {new_timestamp - last_timestamp:0.2f} "
1333
1368
# f"additions: {len(new_gen.additions) if block_record.is_transaction_block else 0:2} "
0 commit comments