Skip to content

Commit b18c201

Browse files
authored
Make requested CU amount and price in upd_price transactions configurable in pythd (#306)
* Make requested CU amount and price in upd_price transactions configurable in pythd * Clarify comment
1 parent e225595 commit b18c201

File tree

6 files changed

+98
-27
lines changed

6 files changed

+98
-27
lines changed

pc/manager.cpp

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,9 @@ using namespace pc;
1414
#define PC_MAX_BATCH 8
1515
// Flush partial batches if not completed within 400 ms.
1616
#define PC_FLUSH_INTERVAL (400L*PC_NSECS_IN_MSEC)
17+
// Compute units requested per price update instruction
18+
// The biggest instruction appears to be about ~10300 CUs, so we overestimate by 100%.
19+
#define PC_UPD_PRICE_COMPUTE_UNITS 20000
1720

1821
///////////////////////////////////////////////////////////////////////////
1922
// manager_sub
@@ -76,6 +79,8 @@ manager::manager()
7679
is_pub_( false ),
7780
cmt_( commitment::e_confirmed ),
7881
max_batch_( PC_MAX_BATCH ),
82+
requested_upd_price_cu_units_( PC_UPD_PRICE_COMPUTE_UNITS ),
83+
requested_upd_price_cu_price_( 0UL ),
7984
sreq_{ { commitment::e_processed } },
8085
secondary_{ nullptr },
8186
is_secondary_( false )
@@ -189,6 +194,22 @@ int64_t manager::get_publish_interval() const
189194
return pub_int_ / PC_NSECS_IN_MSEC;
190195
}
191196

197+
void manager::set_requested_upd_price_cu_units( unsigned cu_units ) {
198+
requested_upd_price_cu_units_ = cu_units;
199+
}
200+
201+
unsigned manager::get_requested_upd_price_cu_units() const {
202+
return requested_upd_price_cu_units_;
203+
}
204+
205+
void manager::set_requested_upd_price_cu_price( unsigned cu_price ) {
206+
requested_upd_price_cu_price_ = cu_price;
207+
}
208+
209+
unsigned manager::get_requested_upd_price_cu_price() const {
210+
return requested_upd_price_cu_price_;
211+
}
212+
192213
void manager::set_max_batch_size( unsigned batch_size )
193214
{
194215
max_batch_ = batch_size;

pc/manager.hpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,14 @@ namespace pc
100100
void set_publish_interval( int64_t mill_secs );
101101
int64_t get_publish_interval() const;
102102

103+
// override the amount of requested CU units per upd_price transaction
104+
void set_requested_upd_price_cu_units( unsigned cu_units );
105+
unsigned get_requested_upd_price_cu_units() const;
106+
107+
// override the price per CU for upd_price transaction
108+
void set_requested_upd_price_cu_price( unsigned cu_price );
109+
unsigned get_requested_upd_price_cu_price() const;
110+
103111
// override the default maximum number of price updates to send in a batch
104112
void set_max_batch_size( unsigned batch_size );
105113
unsigned get_max_batch_size() const;
@@ -275,6 +283,8 @@ namespace pc
275283
tx_parser txp_; // handle unexpected errors
276284
commitment cmt_; // account get/subscribe commitment
277285
unsigned max_batch_;// maximum number of price updates that can be sent in a single batch
286+
unsigned requested_upd_price_cu_units_; // amount of requested CU units per upd_price transaction
287+
unsigned requested_upd_price_cu_price_; // price per CU for upd_price transaction
278288

279289
// requests
280290
rpc::get_slot sreq_[1]; // slot subscription

pc/request.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -801,7 +801,7 @@ bool price::send( price *prices[], const unsigned n )
801801
) {
802802
if ( mgr->get_do_tx() ) {
803803
net_wtr msg;
804-
if ( rpc::upd_price::build( msg, &upds_[ 0 ], upds_.size() ) ) {
804+
if ( rpc::upd_price::build( msg, &upds_[ 0 ], upds_.size(), mgr->get_requested_upd_price_cu_units(), mgr->get_requested_upd_price_cu_units() ) ) {
805805
mgr->submit( msg );
806806
}
807807
else {
@@ -814,7 +814,7 @@ bool price::send( price *prices[], const unsigned n )
814814
}
815815
}
816816
else {
817-
p->get_rpc_client()->send( &upds_[ 0 ], upds_.size() );
817+
p->get_rpc_client()->send( &upds_[ 0 ], upds_.size(), mgr->get_requested_upd_price_cu_units(), mgr->get_requested_upd_price_cu_price() );
818818
for ( unsigned k = j; k <= i; ++k ) {
819819
price *const p1 = prices[ k ];
820820
p1->tvec_.emplace_back(

pc/rpc_client.cpp

Lines changed: 50 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -184,7 +184,7 @@ void rpc_client::send( rpc_request *rptr )
184184
}
185185
}
186186

187-
void rpc_client::send( rpc::upd_price *upds[], const unsigned n )
187+
void rpc_client::send( rpc::upd_price *upds[], const unsigned n, unsigned cu_units, unsigned cu_price )
188188
{
189189
if ( ! n ) {
190190
return;
@@ -212,7 +212,7 @@ void rpc_client::send( rpc::upd_price *upds[], const unsigned n )
212212
jw.add_val( json_wtr::e_obj );
213213
jw.add_key( "jsonrpc", "2.0" );
214214
jw.add_key( "id", id );
215-
rpc::upd_price::request( jw, upds, n );
215+
rpc::upd_price::request( jw, upds, n, cu_units, cu_price );
216216
jw.pop();
217217
// jw.print();
218218
if ( upds[ 0 ]->get_is_http() ) {
@@ -888,8 +888,16 @@ class tx_wtr : public net_wtr
888888
}
889889
};
890890

891+
// Populates the given tx with the given upd_price requests. This function allows
892+
// specifying the number of requested cu units, and a price per cu unit, to enable
893+
// priority fees. If these parameters are emitted these are left as unspecified in
894+
// the transaction.
891895
bool rpc::upd_price::build_tx(
892-
bincode& tx, upd_price* upds[], const unsigned n
896+
bincode& tx,
897+
upd_price* upds[],
898+
const unsigned n,
899+
unsigned cu_units,
900+
unsigned cu_price
893901
)
894902
{
895903
if ( ! n ) {
@@ -923,28 +931,34 @@ bool rpc::upd_price::build_tx(
923931
tx.add( *first.bhash_ ); // recent block hash
924932

925933
// instructions section
926-
tx.add_len( n + 1 + 1 ); // 1 compute limit instruction, 1 compute unit price instruction, n upd_price instruction(s)
934+
unsigned instruction_count = n; // n upd_price instruction(s)
935+
if ( cu_units > 0 ) {
936+
instruction_count += 1; // Extra instruction for specifying number of cus per instructions
937+
}
938+
if ( cu_price > 0 ) {
939+
instruction_count += 1; // Extra instruction for specifying compute unit price
940+
}
941+
tx.add_len( instruction_count ); // 1 compute limit instruction, 1 compute unit price instruction, n upd_price instruction(s)
927942

928943
// Set compute limit
929-
tx.add( (uint8_t)( n + 3 ) ); // compute budget program id index in accounts list
930-
tx.add_len<0>(); // no accounts
931-
// compute limit instruction parameters
932-
tx.add_len<sizeof(uint8_t) + sizeof(uint32_t)>(); // uint8_t enum variant + uint32_t requested compute units
933-
tx.add( (uint8_t) 2 ); // SetComputeLimit enum variant
934-
tx.add( (uint32_t) CU_BUDGET_PER_IX * n ); // the budget (scaled for number of instructions)
935-
936-
// Requested price per compute unit, in micro lamports
937-
// We want to pay 5000 lamports in total, so ((5000/20000) / 8) * (10^6)
938-
// assuming upper bound of 20000 CUs and 8 instructions.
939-
const uint64_t cu_price_micro_lamports = 31250;
944+
if ( cu_units > 0 ) {
945+
tx.add( (uint8_t)( n + 3 ) ); // compute budget program id index in accounts list
946+
tx.add_len<0>(); // no accounts
947+
// compute limit instruction parameters
948+
tx.add_len<sizeof(uint8_t) + sizeof(uint32_t)>(); // uint8_t enum variant + uint32_t requested compute units
949+
tx.add( (uint8_t) 2 ); // SetComputeLimit enum variant
950+
tx.add( (uint32_t) ( cu_units * n ) ); // the budget (scaled for number of instructions)
951+
}
940952

941953
// Set compute unit price
942-
tx.add( (uint8_t)( n + 3 ) );
943-
tx.add_len<0>(); // no accounts
944-
// compute unit price instruction parameters
945-
tx.add_len<sizeof(uint8_t) + sizeof(uint64_t)>(); // uint8_t enum variant + uint62_t compute price
946-
tx.add( (uint8_t) 3 ); // SetComputePrice enum variant
947-
tx.add( (uint64_t) cu_price_micro_lamports ); // price we are willing to pay per compute unit in Micro Lamports
954+
if ( cu_price > 0 ) {
955+
tx.add( (uint8_t)( n + 3 ) );
956+
tx.add_len<0>(); // no accounts
957+
// compute unit price instruction parameters
958+
tx.add_len<sizeof(uint8_t) + sizeof(uint64_t)>(); // uint8_t enum variant + uint62_t compute price
959+
tx.add( (uint8_t) 3 ); // SetComputePrice enum variant
960+
tx.add( (uint64_t) cu_price ); // price we are willing to pay per compute unit in Micro Lamports
961+
}
948962

949963
for ( unsigned i = 0; i < n; ++i ) {
950964
tx.add( (uint8_t)( n + 2 ) ); // program_id index
@@ -989,10 +1003,17 @@ void rpc::upd_price::request( json_wtr& msg )
9891003
bool rpc::upd_price::build(
9901004
net_wtr& wtr, upd_price* upds[], const unsigned n
9911005
)
1006+
{
1007+
return build( wtr, upds, n, 0, 0 );
1008+
}
1009+
1010+
bool rpc::upd_price::build(
1011+
net_wtr& wtr, upd_price* upds[], const unsigned n, unsigned cu_units, unsigned cu_price
1012+
)
9921013
{
9931014
bincode tx;
9941015
static_cast< tx_wtr& >( wtr ).init( tx );
995-
if ( ! build_tx( tx, upds, n ) ) {
1016+
if ( ! build_tx( tx, upds, n, cu_units, cu_price ) ) {
9961017
return false;
9971018
}
9981019
static_cast< tx_wtr& >( wtr ).commit( tx );
@@ -1001,12 +1022,18 @@ bool rpc::upd_price::build(
10011022

10021023
bool rpc::upd_price::request(
10031024
json_wtr& msg, upd_price* upds[], const unsigned n
1025+
) {
1026+
return request( msg, upds, n, 0, 0 );
1027+
}
1028+
1029+
bool rpc::upd_price::request(
1030+
json_wtr& msg, upd_price* upds[], const unsigned n, unsigned cu_units, unsigned cu_price
10041031
)
10051032
{
10061033
// construct binary transaction
10071034
net_buf *bptr = net_buf::alloc();
10081035
bincode tx( bptr->buf_ );
1009-
if ( ! build_tx( tx, upds, n ) ) {
1036+
if ( ! build_tx( tx, upds, n, cu_units, cu_price ) ) {
10101037
return false;
10111038
}
10121039

pc/rpc_client.hpp

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,7 @@ namespace pc
8787

8888
// submit rpc request (and bundled callback)
8989
void send( rpc_request * );
90-
void send( rpc::upd_price *[], unsigned n );
90+
void send( rpc::upd_price *[], unsigned n, unsigned cu_units, unsigned cu_price );
9191

9292
public:
9393

@@ -428,8 +428,11 @@ namespace pc
428428
static bool build( net_wtr&, upd_price*[], unsigned n );
429429
static bool request( json_wtr&, upd_price*[], const unsigned n );
430430

431+
static bool build( net_wtr&, upd_price*[], unsigned n, unsigned cu_units, unsigned cu_price );
432+
static bool request( json_wtr&, upd_price*[], const unsigned n, unsigned cu_units, unsigned cu_price );
433+
431434
private:
432-
static bool build_tx( bincode&, upd_price*[], unsigned n );
435+
static bool build_tx( bincode&, upd_price*[], unsigned n, unsigned cu_units, unsigned cu_price );
433436

434437
hash *bhash_;
435438
key_pair *pkey_;

pcapps/pythd.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,10 @@ int usage()
7272
std::cerr << " -d" << std::endl;
7373
std::cerr << " Turn on debug logging. Can also toggle this on/off via "
7474
"kill -s SIGUSR1 <pid>\n" << std::endl;
75+
std::cerr << " -u" << std::endl;
76+
std::cerr << " Number of compute units requested by each upd_price transaction (default 20000)" << std::endl;
77+
std::cerr << " -v" << std::endl;
78+
std::cerr << " Price per compute unit for each upd_price transaction, in micro lamports (the default is not to specify a specific price)" << std::endl;
7579
return 1;
7680
}
7781

@@ -104,6 +108,8 @@ int main(int argc, char **argv)
104108
int pyth_port = get_port();
105109
int opt = 0;
106110
int pub_int = 1000;
111+
unsigned cu_units = 20000;
112+
unsigned cu_price = 0;
107113
unsigned max_batch_size = 0;
108114
bool do_wait = true, do_tx = true, do_ws = true, do_debug = false;
109115
while( (opt = ::getopt(argc,argv, "r:s:t:p:i:k:w:c:l:m:b:dnxhz" )) != -1 ) {
@@ -123,6 +129,8 @@ int main(int argc, char **argv)
123129
case 'x': do_tx = false; break;
124130
case 'z': do_ws = false; break;
125131
case 'd': do_debug = true; break;
132+
case 'u': cu_units = strtoul(optarg, NULL, 0); break;
133+
case 'v': cu_price = strtoul(optarg, NULL, 0); break;
126134
default: return usage();
127135
}
128136
}
@@ -153,6 +161,8 @@ int main(int argc, char **argv)
153161
mgr.set_do_capture( !cap_file.empty() );
154162
mgr.set_commitment( cmt );
155163
mgr.set_publish_interval( pub_int );
164+
mgr.set_requested_upd_price_cu_units( cu_units );
165+
mgr.set_requested_upd_price_cu_price( cu_price );
156166

157167
bool do_secondary = !secondary_rpc_host.empty();
158168
if ( do_secondary ) {

0 commit comments

Comments
 (0)