7
7
#include "../../ballet/base58/fd_base58.h"
8
8
#include "../../ballet/json/cJSON.h"
9
9
#include "../../flamenco/genesis/fd_genesis_cluster.h"
10
+ #include "../../disco/pack/fd_pack.h"
11
+ #include "../../disco/pack/fd_pack_cost.h"
10
12
11
13
FD_FN_CONST ulong
12
14
fd_gui_align ( void ) {
@@ -103,8 +105,6 @@ fd_gui_new( void * shmem,
103
105
gui -> summary .tile_timers_history_idx = 0UL ;
104
106
for ( ulong i = 0UL ; i < FD_GUI_TILE_TIMER_LEADER_CNT ; i ++ ) gui -> summary .tile_timers_leader_history_slot [ i ] = ULONG_MAX ;
105
107
106
- gui -> cus .offset = 0UL ;
107
-
108
108
gui -> block_engine .has_block_engine = 0 ;
109
109
110
110
gui -> epoch .has_epoch [ 0 ] = 0 ;
@@ -115,6 +115,7 @@ fd_gui_new( void * shmem,
115
115
gui -> validator_info .info_cnt = 0UL ;
116
116
117
117
for ( ulong i = 0UL ; i < FD_GUI_SLOTS_CNT ; i ++ ) gui -> slots [ i ]-> slot = ULONG_MAX ;
118
+ gui -> pack_txn_idx = 0UL ;
118
119
119
120
return gui ;
120
121
}
@@ -970,15 +971,16 @@ fd_gui_clear_slot( fd_gui_t * gui,
970
971
slot -> leader_state = FD_GUI_SLOT_LEADER_UNSTARTED ;
971
972
slot -> completed_time = LONG_MAX ;
972
973
973
- slot -> cus .leader_start_time = LONG_MAX ;
974
- slot -> cus .leader_end_time = LONG_MAX ;
975
- slot -> cus .max_compute_units = UINT_MAX ;
976
- slot -> cus .microblocks_upper_bound = USHORT_MAX ;
977
- slot -> cus .begin_microblocks = 0U ;
978
- slot -> cus .end_microblocks = 0U ;
979
- slot -> cus .reference_ticks = LONG_MAX ;
980
- slot -> cus .reference_nanos = LONG_MAX ;
981
- for ( ulong i = 0UL ; i < 65UL ; i ++ ) slot -> cus .has_offset [ i ] = 0 ;
974
+ slot -> txs .leader_start_time = LONG_MAX ;
975
+ slot -> txs .leader_end_time = LONG_MAX ;
976
+ slot -> txs .max_compute_units = UINT_MAX ;
977
+ slot -> txs .microblocks_upper_bound = USHORT_MAX ;
978
+ slot -> txs .begin_microblocks = 0U ;
979
+ slot -> txs .end_microblocks = 0U ;
980
+ slot -> txs .reference_ticks = LONG_MAX ;
981
+ slot -> txs .reference_nanos = LONG_MAX ;
982
+ slot -> txs .start_offset = ULONG_MAX ;
983
+ slot -> txs .end_offset = ULONG_MAX ;
982
984
983
985
if ( FD_LIKELY ( slot -> mine ) ) {
984
986
/* All slots start off not skipped, until we see it get off the reset
@@ -1618,96 +1620,130 @@ fd_gui_plugin_message( fd_gui_t * gui,
1618
1620
}
1619
1621
}
1620
1622
1623
+ static void
1624
+ fd_gui_init_slot_txns ( fd_gui_t * gui ,
1625
+ long tickcount ,
1626
+ ulong _slot ) {
1627
+ fd_gui_slot_t * slot = gui -> slots [ _slot % FD_GUI_SLOTS_CNT ];
1628
+ if ( FD_UNLIKELY ( slot -> slot != _slot ) ) fd_gui_clear_slot ( gui , _slot , ULONG_MAX );
1629
+
1630
+ /* initialize reference timestamp */
1631
+ if ( FD_UNLIKELY ( LONG_MAX == slot -> txs .reference_ticks ) ) {
1632
+ slot -> txs .reference_ticks = tickcount ;
1633
+ slot -> txs .reference_nanos = fd_log_wallclock () - (long )((double )(fd_tickcount () - slot -> txs .reference_ticks ) / fd_tempo_tick_per_ns ( NULL ));
1634
+ }
1635
+ }
1636
+
1621
1637
void
1622
1638
fd_gui_became_leader ( fd_gui_t * gui ,
1639
+ long tickcount ,
1623
1640
ulong _slot ,
1624
1641
long start_time_nanos ,
1625
1642
long end_time_nanos ,
1626
1643
ulong max_compute_units ,
1627
1644
ulong max_microblocks ) {
1645
+ fd_gui_init_slot_txns ( gui , tickcount , _slot );
1628
1646
fd_gui_slot_t * slot = gui -> slots [ _slot % FD_GUI_SLOTS_CNT ];
1629
- if ( FD_UNLIKELY ( slot -> slot != _slot ) ) fd_gui_clear_slot ( gui , _slot , ULONG_MAX );
1630
-
1631
- slot -> cus .leader_start_time = start_time_nanos ;
1632
1647
1633
- long tickcount = fd_tickcount ();
1634
- if ( FD_LIKELY ( slot -> cus .reference_ticks == LONG_MAX ) ) slot -> cus .reference_ticks = tickcount ;
1635
- slot -> cus .reference_nanos = fd_log_wallclock () - (long )((double )(tickcount - slot -> cus .reference_ticks ) / fd_tempo_tick_per_ns ( NULL ));
1636
-
1637
- slot -> cus .leader_end_time = end_time_nanos ;
1638
- slot -> cus .max_compute_units = (uint )max_compute_units ;
1639
- if ( FD_LIKELY ( slot -> cus .microblocks_upper_bound == USHORT_MAX ) ) slot -> cus .microblocks_upper_bound = (ushort )max_microblocks ;
1648
+ slot -> txs .leader_start_time = start_time_nanos ;
1649
+ slot -> txs .leader_end_time = end_time_nanos ;
1650
+ slot -> txs .max_compute_units = (uint )max_compute_units ;
1651
+ if ( FD_LIKELY ( slot -> txs .microblocks_upper_bound == USHORT_MAX ) ) slot -> txs .microblocks_upper_bound = (ushort )max_microblocks ;
1640
1652
}
1641
1653
1642
1654
void
1643
1655
fd_gui_unbecame_leader ( fd_gui_t * gui ,
1656
+ long tickcount ,
1644
1657
ulong _slot ,
1645
1658
ulong microblocks_in_slot ) {
1659
+ fd_gui_init_slot_txns ( gui , tickcount , _slot );
1646
1660
fd_gui_slot_t * slot = gui -> slots [ _slot % FD_GUI_SLOTS_CNT ];
1647
- if ( FD_UNLIKELY ( slot -> slot != _slot ) ) fd_gui_clear_slot ( gui , _slot , ULONG_MAX );
1648
1661
1649
- slot -> cus .microblocks_upper_bound = (ushort )microblocks_in_slot ;
1662
+ slot -> txs .microblocks_upper_bound = (ushort )microblocks_in_slot ;
1650
1663
}
1651
1664
1652
1665
void
1653
- fd_gui_execution_begin ( fd_gui_t * gui ,
1654
- long tickcount ,
1655
- ulong _slot ,
1656
- ulong bank_idx ,
1657
- ulong txn_cnt ,
1658
- fd_txn_p_t * txns ) {
1666
+ fd_gui_microblock_execution_begin ( fd_gui_t * gui ,
1667
+ long tickcount ,
1668
+ ulong _slot ,
1669
+ fd_txn_p_t * txns ,
1670
+ ulong txn_cnt ,
1671
+ uint microblock_idx ,
1672
+ ulong pack_txn_idx ) {
1673
+ fd_gui_init_slot_txns ( gui , tickcount , _slot );
1659
1674
fd_gui_slot_t * slot = gui -> slots [ _slot % FD_GUI_SLOTS_CNT ];
1660
- if ( FD_UNLIKELY ( slot -> slot != _slot ) ) fd_gui_clear_slot ( gui , _slot , ULONG_MAX );
1661
1675
1662
- if ( FD_UNLIKELY ( !slot -> cus .has_offset [ 64UL ] ) ) slot -> cus .start_offset [ 64UL ] = gui -> cus .offset ;
1663
- slot -> cus .has_offset [ 64UL ] = 1 ;
1664
- if ( FD_UNLIKELY ( slot -> cus .reference_ticks == LONG_MAX ) ) slot -> cus .reference_ticks = tickcount ;
1676
+ if ( FD_UNLIKELY ( slot -> txs .start_offset == ULONG_MAX ) ) slot -> txs .start_offset = pack_txn_idx ;
1677
+ else slot -> txs .start_offset = fd_ulong_min ( slot -> txs .start_offset , pack_txn_idx );
1678
+
1679
+ gui -> pack_txn_idx = fd_ulong_max ( gui -> pack_txn_idx , pack_txn_idx + txn_cnt - 1UL );
1665
1680
1666
1681
for ( ulong i = 0UL ; i < txn_cnt ; i ++ ) {
1667
- fd_txn_p_t * txn = & txns [ i ];
1668
-
1669
- ulong comp = fd_gui_cu_history_compress ( FD_GUI_EXECUTION_TYPE_BEGIN ,
1670
- bank_idx ,
1671
- txn -> pack_cu .non_execution_cus + txn -> pack_cu .requested_exec_plus_acct_data_cus ,
1672
- i == 0UL ,
1673
- slot -> cus .reference_ticks ,
1674
- tickcount );
1675
- gui -> cus .history [ gui -> cus .offset %FD_GUI_COMPUTE_UNITS_HISTORY_SZ ] = comp ;
1676
- gui -> cus .offset ++ ;
1682
+ fd_txn_p_t * txn_payload = & txns [ i ];
1683
+ fd_txn_t * txn = TXN ( txn_payload );
1684
+
1685
+ ulong priority_rewards = ULONG_MAX ;
1686
+ ulong requested_execution_cus = ULONG_MAX ;
1687
+ ulong precompile_sigs = ULONG_MAX ;
1688
+ ulong requested_loaded_accounts_data_cost = ULONG_MAX ;
1689
+ uint _flags ;
1690
+ ulong cost_estimate = fd_pack_compute_cost ( txn , txn_payload -> payload , & _flags , & requested_execution_cus , & priority_rewards , & precompile_sigs , & requested_loaded_accounts_data_cost );
1691
+
1692
+ fd_gui_txn_t * txn_entry = gui -> txs [ (pack_txn_idx + i )%FD_GUI_TXN_HISTORY_SZ ];
1693
+ txn_entry -> compute_units_estimated = cost_estimate & 0x1FFFFFU ;
1694
+ txn_entry -> compute_units_requested = requested_execution_cus & 0x1FFFFFU ;
1695
+ txn_entry -> priority_fee = priority_rewards ;
1696
+ txn_entry -> timestamp_delta_start_nanos = (int )((double )(tickcount - slot -> txs .reference_ticks ) / fd_tempo_tick_per_ns ( NULL ));
1697
+ txn_entry -> microblock_idx = microblock_idx ;
1698
+ txn_entry -> flags |= (uchar )FD_GUI_TXN_FLAGS_STARTED ;
1699
+ txn_entry -> flags |= (uchar )fd_uint_if (txn_payload -> flags & FD_TXN_P_FLAGS_IS_SIMPLE_VOTE , FD_GUI_TXN_FLAGS_IS_SIMPLE_VOTE , 0U );
1700
+ txn_entry -> flags |= (uchar )fd_uint_if ((txn_payload -> flags & FD_TXN_P_FLAGS_BUNDLE ) || (txn_payload -> flags & FD_TXN_P_FLAGS_INITIALIZER_BUNDLE ), FD_GUI_TXN_FLAGS_FROM_BUNDLE , 0U );
1677
1701
}
1678
1702
1679
- slot -> cus .end_offset [ 64UL ] = gui -> cus .offset ;
1680
- slot -> cus .begin_microblocks = (ushort )(slot -> cus .begin_microblocks + txn_cnt );
1703
+ /* At the moment, bank publishes at most 1 transaction per microblock,
1704
+ even if it received microblocks with multiple transactions
1705
+ (i.e. a bundle). This means that we need to calulate microblock
1706
+ count here based on the transaction count. */
1707
+ slot -> txs .begin_microblocks = (ushort )(slot -> txs .begin_microblocks + txn_cnt );
1681
1708
}
1682
1709
1683
1710
void
1684
- fd_gui_execution_end ( fd_gui_t * gui ,
1685
- long tickcount ,
1686
- ulong bank_idx ,
1687
- int is_last_in_bundle ,
1688
- ulong _slot ,
1689
- ulong txn_cnt ,
1690
- fd_txn_p_t * txns ) {
1711
+ fd_gui_microblock_execution_end ( fd_gui_t * gui ,
1712
+ long tickcount ,
1713
+ ulong bank_idx ,
1714
+ ulong _slot ,
1715
+ ulong txn_cnt ,
1716
+ fd_txn_p_t * txns ,
1717
+ ulong pack_txn_idx ,
1718
+ uchar txn_start_pct ,
1719
+ uchar txn_load_end_pct ,
1720
+ uchar txn_end_pct ,
1721
+ ulong tips ) {
1722
+ if ( FD_UNLIKELY ( 1UL != txn_cnt ) ) FD_LOG_ERR (( "gui expects 1 txn per microblock from bank, found %lu" , txn_cnt ));
1723
+
1724
+ fd_gui_init_slot_txns ( gui , tickcount , _slot );
1691
1725
fd_gui_slot_t * slot = gui -> slots [ _slot % FD_GUI_SLOTS_CNT ];
1692
- if ( FD_UNLIKELY ( slot -> slot != _slot ) ) fd_gui_clear_slot ( gui , _slot , ULONG_MAX );
1693
1726
1694
- if ( FD_UNLIKELY ( !slot -> cus .has_offset [ bank_idx ] ) ) slot -> cus .start_offset [ bank_idx ] = gui -> cus .offset ;
1695
- slot -> cus .has_offset [ bank_idx ] = 1 ;
1696
- if ( FD_UNLIKELY ( slot -> cus .reference_ticks == LONG_MAX ) ) slot -> cus .reference_ticks = tickcount ;
1727
+ if ( FD_UNLIKELY ( slot -> txs .end_offset == ULONG_MAX ) ) slot -> txs .end_offset = pack_txn_idx + txn_cnt ;
1728
+ else slot -> txs .end_offset = fd_ulong_max ( slot -> txs .end_offset , pack_txn_idx + txn_cnt );
1729
+
1730
+ gui -> pack_txn_idx = fd_ulong_max ( gui -> pack_txn_idx , pack_txn_idx + txn_cnt - 1UL );
1697
1731
1698
1732
for ( ulong i = 0UL ; i < txn_cnt ; i ++ ) {
1699
- fd_txn_p_t * txn = & txns [ i ];
1700
-
1701
- ulong comp = fd_gui_cu_history_compress ( FD_GUI_EXECUTION_TYPE_END ,
1702
- bank_idx ,
1703
- txn -> bank_cu .rebated_cus ,
1704
- is_last_in_bundle ,
1705
- slot -> cus .reference_ticks ,
1706
- tickcount );
1707
- gui -> cus .history [ gui -> cus .offset %FD_GUI_COMPUTE_UNITS_HISTORY_SZ ] = comp ;
1708
- gui -> cus .offset ++ ;
1733
+ fd_txn_p_t * txn_p = & txns [ i ];
1734
+
1735
+ fd_gui_txn_t * txn_entry = gui -> txs [ (pack_txn_idx + i )%FD_GUI_TXN_HISTORY_SZ ];
1736
+ txn_entry -> bank_idx = bank_idx & 0x3FU ;
1737
+ txn_entry -> actual_consumed_cus = txn_p -> bank_cu .actual_consumed_cus & 0x1FFFFFU ;
1738
+ txn_entry -> error_code = (txn_p -> flags >> 24 ) & 0x3FU ;
1739
+ txn_entry -> timestamp_delta_end_nanos = (int )((double )(tickcount - slot -> txs .reference_ticks ) / fd_tempo_tick_per_ns ( NULL ));
1740
+ txn_entry -> txn_start_pct = txn_start_pct ;
1741
+ txn_entry -> txn_load_end_pct = txn_load_end_pct ;
1742
+ txn_entry -> txn_end_pct = txn_end_pct ;
1743
+ txn_entry -> tips = tips ;
1744
+ txn_entry -> flags |= (uchar )FD_GUI_TXN_FLAGS_ENDED ;
1745
+ txn_entry -> flags |= (uchar )fd_uint_if (txn_p -> flags & FD_TXN_P_FLAGS_EXECUTE_SUCCESS , FD_GUI_TXN_FLAGS_LANDED_IN_BLOCK , 0U );
1709
1746
}
1710
1747
1711
- slot -> cus .end_offset [ bank_idx ] = gui -> cus .offset ;
1712
- slot -> cus .end_microblocks = (ushort )(slot -> cus .end_microblocks + txn_cnt );
1748
+ slot -> txs .end_microblocks = slot -> txs .end_microblocks + (uint )txn_cnt ;
1713
1749
}
0 commit comments