Skip to content

Commit

Permalink
fd_txn_parse: fail transactions that include an ALT but don't load fr…
Browse files Browse the repository at this point in the history
…om it.

This is to match Solana Lab's behavior.
Shrinks the max fd_txn_t size by 8 bytes, which has some other
implications.
  • Loading branch information
ptaffet-jump committed Dec 21, 2023
1 parent 85c7050 commit dee1142
Show file tree
Hide file tree
Showing 6 changed files with 13 additions and 11 deletions.
2 changes: 1 addition & 1 deletion solana
5 changes: 3 additions & 2 deletions src/ballet/txn/fd_txn.h
Original file line number Diff line number Diff line change
Expand Up @@ -90,8 +90,9 @@
take up, including the instruction array and any address tables. The
worst-case transaction is a V0 transaction with only two account
addresses (a program and a fee payer), and tons of empty instructions (no
accounts, no data) and as many address table lookups as possible. */
#define FD_TXN_MAX_SZ (860UL)
accounts, no data) and as many address table lookups loading a single
account as possible. */
#define FD_TXN_MAX_SZ (852UL)


/* FD_TXN_MTU: The maximum size (in bytes, inclusive) of a serialized
Expand Down
3 changes: 2 additions & 1 deletion src/ballet/txn/fd_txn_parse.c
Original file line number Diff line number Diff line change
Expand Up @@ -202,8 +202,9 @@ fd_txn_parse_core( uchar const * payload,
READ_CHECKED_COMPACT_U16( bytes_consumed, readonly_cnt, i ); i+=bytes_consumed;
CHECK_LEFT( readonly_cnt ); ulong readonly_off = i ; i+=readonly_cnt;

CHECK( writable_cnt<=FD_TXN_ACCT_ADDR_MAX-acct_addr_cnt ); /* implies <256 */
CHECK( writable_cnt<=FD_TXN_ACCT_ADDR_MAX-acct_addr_cnt ); /* implies <256 ... */
CHECK( readonly_cnt<=FD_TXN_ACCT_ADDR_MAX-acct_addr_cnt );
CHECK( (ushort)1 <=writable_cnt+readonly_cnt ); /* ... so the sum can't overflow */
if( address_tables ) {
address_tables[ j ].addr_off = (ushort)addr_off;
address_tables[ j ].writable_cnt = (uchar )writable_cnt;
Expand Down
Binary file modified src/ballet/txn/fixtures/transaction3.bin
Binary file not shown.
12 changes: 6 additions & 6 deletions src/ballet/txn/test_txn.c
Original file line number Diff line number Diff line change
Expand Up @@ -8,29 +8,29 @@ FD_STATIC_ASSERT( FD_TXN_MTU<=USHORT_MAX, fd_txn_mtu );
/* Calculate the max size for an fd_txn_t */

/* A worst-case instruction takes 3B of the payload and is stored as 10 B. A
worst-case address lookup table takes 34B of the payload and is stored as 8B.
worst-case address lookup table takes 35B of the payload and is stored as 8B.
This gives the optimization problem:
Maximize sizeof(fd_txn_t) + x * sizeof(fd_txn_instr_t) + y * sizeof(fd_txn_acct_addr_lut_t)
subject to:
MIN_FIXED_SIZE_SECTION
+ (x>0 ? 32 : 0) + len_compact_u16(x) + 3*x
+ (y>0 ? 1 : 0) + len_compact_u16(y) + 34*y <= 1232
+ (y>0 ? 1 : 0) + len_compact_u16(y) + 35*y <= 1232
0 <= x <= FD_TXN_INSTR_MAX
0 <= y <= FD_TXN_ADDR_TABLE_LOOKUP_MAX
x, y integers
which has solution (not hard to see by hand):
x == FD_TXN_INSTR_MAX
y == floor((1232 - ... )/34)==25,
giving an objective of 860.
y == floor((1232 - ... )/35)==24,
giving an objective of 852.
*/
#define MIN_PAYLOAD_SZ( instr_cnt, alt_cnt ) \
( 1 + FD_TXN_SIGNATURE_SZ \
+ ((alt_cnt) ? 1 : 0) + 3 \
+ 1 + ((instr_cnt) ? 2 : 1)*FD_TXN_ACCT_ADDR_SZ \
+ FD_TXN_BLOCKHASH_SZ \
+ 1 + 3*(instr_cnt) \
+ 1 + 34*(alt_cnt) )
+ 1 + 35*(alt_cnt) )

#define PARSED_SZ( instr_cnt, alt_cnt ) \
sizeof(fd_txn_t) \
Expand All @@ -43,7 +43,7 @@ FD_STATIC_ASSERT( FD_TXN_MTU<=USHORT_MAX, fd_txn_mtu );
+ FD_TXN_BLOCKHASH_SZ )
#define WORST_CASE_INSTR_CNT FD_TXN_INSTR_MAX
#define WORST_CASE_INSTR_PAYLOAD (1 + WORST_CASE_INSTR_CNT*3 )
#define WORST_CASE_ALT_CNT ((1232 - MIN_FIXED_SIZE_SECTION - FD_TXN_ACCT_ADDR_SZ - WORST_CASE_INSTR_PAYLOAD - 1)/(34))
#define WORST_CASE_ALT_CNT ((1232 - MIN_FIXED_SIZE_SECTION - FD_TXN_ACCT_ADDR_SZ - WORST_CASE_INSTR_PAYLOAD - 1)/(35))
FD_STATIC_ASSERT( FD_TXN_MAX_SZ==sizeof(fd_txn_t) +
WORST_CASE_INSTR_CNT*sizeof(fd_txn_instr_t) +
WORST_CASE_ALT_CNT*sizeof(fd_txn_acct_addr_lut_t), fd_txn );
Expand Down
2 changes: 1 addition & 1 deletion src/disco/fd_disco_base.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@
/* The literal value of FD_TPU_DCACHE_MTU is used in some of the Rust
shims, so if the value changes, this acts as a reminder to change it
in the Rust code. */
FD_STATIC_ASSERT( FD_TPU_DCACHE_MTU==2094UL, tpu_dcache_mtu_check );
FD_STATIC_ASSERT( FD_TPU_DCACHE_MTU==2086UL, tpu_dcache_mtu_check );

#define FD_NETMUX_SIG_MIN_HDR_SZ ( 42UL) /* The default header size, which means no vlan tags and no IP options. */
#define FD_NETMUX_SIG_IGNORE_HDR_SZ (102UL) /* Outside the allowable range, but still fits in 4 bits when compressed */
Expand Down

0 comments on commit dee1142

Please sign in to comment.