From dee1142a3ee29d5ff7770f046082c8a5f28d4f53 Mon Sep 17 00:00:00 2001 From: Philip Taffet Date: Thu, 21 Dec 2023 16:56:21 +0000 Subject: [PATCH] fd_txn_parse: fail transactions that include an ALT but don't load from it. This is to match Solana Lab's behavior. Shrinks the max fd_txn_t size by 8 bytes, which has some other implications. --- solana | 2 +- src/ballet/txn/fd_txn.h | 5 +++-- src/ballet/txn/fd_txn_parse.c | 3 ++- src/ballet/txn/fixtures/transaction3.bin | Bin 1210 -> 1200 bytes src/ballet/txn/test_txn.c | 12 ++++++------ src/disco/fd_disco_base.h | 2 +- 6 files changed, 13 insertions(+), 11 deletions(-) diff --git a/solana b/solana index 53ce15065f..eef8bb75d6 160000 --- a/solana +++ b/solana @@ -1 +1 @@ -Subproject commit 53ce15065f7d5db79c6b3aad9107e6dac951d8c2 +Subproject commit eef8bb75d67109570a2b34a82f2c18c6bf03f06d diff --git a/src/ballet/txn/fd_txn.h b/src/ballet/txn/fd_txn.h index 8cc1a267ff..82dd9c6db8 100644 --- a/src/ballet/txn/fd_txn.h +++ b/src/ballet/txn/fd_txn.h @@ -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 diff --git a/src/ballet/txn/fd_txn_parse.c b/src/ballet/txn/fd_txn_parse.c index 891f280e86..0f3b18dc65 100644 --- a/src/ballet/txn/fd_txn_parse.c +++ b/src/ballet/txn/fd_txn_parse.c @@ -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; diff --git a/src/ballet/txn/fixtures/transaction3.bin b/src/ballet/txn/fixtures/transaction3.bin index dd4d9d849b12c2e2415ec1365b9a6c8b69b827ff..65ed71a6d374c7eacbc2b2b427b0b06ab894e862 100644 GIT binary patch literal 1200 zcmZS7-t%0=e%`!b(X%tnD)cl=WV9}~T)Lbd@U>@!#EgxqzddWxig+Vl%YX6S?QKxB z-6oaI`_jw*2N+x9@3Hx8WKAZ70Jg)ACLrLA$DUvM7ARhvK2Ul`X zD}CSkC;w#6+dH40>HXdYG$kLWJTb2{6nkR-zd!5-3b+S98_TP1$UBO=@0Z(U{`zx z&6GnT!smGmey;9%(ik#x)Bc@*GvdwBOgZFI=iTzl^+;f-;{ugi?bo^{c}+w&rR2r& zzlSH@6+g!KdIOXHXYoCzZ_rIy8thWmbNA~#vqR?AS`z$Ao+-Man{svUf%jord`p%$ zH606lpkpM!vk=Xc!)zM18S-W7*%D6Y0xMT|?6>^>8_kr%W|MY4cyY+Vu#;Kx&ccFJ zpXA43=%%FoHH+ND7xDe);neh#7L7N1&uu_AWqSIiOVv?@`?8uheEP^RFKzoSZgf+Q zU()w>S=QBZ+xbtO#ED&>A1+NrH|2-T>La|L7JK`!cyKyQxZcP;;Q*Q`M>Lje*j%^U zBe>_tw>N;H*{O>%TG`gm>r*9if&40jiO%WwYT%;xoWN2 z{!&+?Gw3|JDLbFdU2d$*mdejsW_o|4=hn@3TIi;{3Y3!nlP|AbfAru%_R2J;yP7Rf FQve6ZiyQy| literal 1210 zcmZR)qFNDl(=*wtyIE3JcxY8 z#^iQ#Y9j-Mz=4s0VMrrMXaLj^42XJyDjEo?AROLJ1kGqBsG^0SidKRu+6by>C#a%> zpo&g{D!K@&=q9M5hoFjHf-3q5s^}-EVgf-G6A7xAL{P0 ? 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 \ @@ -30,7 +30,7 @@ FD_STATIC_ASSERT( FD_TXN_MTU<=USHORT_MAX, fd_txn_mtu ); + 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) \ @@ -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 ); diff --git a/src/disco/fd_disco_base.h b/src/disco/fd_disco_base.h index 91b93bbadb..1ecea6db4b 100644 --- a/src/disco/fd_disco_base.h +++ b/src/disco/fd_disco_base.h @@ -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 */