A library whose CGpuTx is not this build's speaks no ABI the binding reads

Two version 7 libraries lay a tx out differently: one built before CGpuTx
carried the fee cap and tip has a 112-byte tx and no gpu_abi_tx_size. init
compares the library's gpu_abi_tx_size with its own sizeof(CGpuTx) and, on
a difference, declines every block as it declines a library of another
ABI; a library without the symbol does not link. The tip needs no width
check of its own: it is at most the fee cap, which has one.

Co-authored-by: Hanzo Dev <[email protected]>
This commit is contained in:
2026-09-23 14:33:46 -07:00
co-authored by Hanzo Dev
parent 1d08088efd
commit 2815437287
3 changed files with 17 additions and 11 deletions
+4 -2
View File
@@ -45,8 +45,10 @@
// build does not compile against a header that names another, and init reads
// the loaded library's gpu_abi_version(): against a library of another ABI,
// ExecuteBlock sends it no block and declines every one, so the caller runs
// them all on its own EVM. It catches a library built against another ABI number;
// two libraries that report the same number are not told apart.
// them all on its own EVM. It catches a library built against another ABI
// number, and a version 7 library whose CGpuTx is not this build's
// (gpu_abi_tx_size), which one built before the tx carried its fee cap and tip
// is not; two libraries alike in both are not told apart.
//
// Use Health() at startup to see which lanes can run a block: it runs a
// funded plain transfer on each.
+11 -5
View File
@@ -87,9 +87,11 @@ var (
_ [unsafe.Sizeof(BlockContext{}) - unsafe.Sizeof(C.CBlockContext{})]struct{}
)
// libraryABI is the ABI the loaded library reports (gpu_abi_version), read
// once in init. The library a binary loads at run time need not be the one
// whose header it was built against.
// libraryABI is the ABI the loaded library speaks, read once in init: the one
// it reports (gpu_abi_version), or 0 where its CGpuTx is not this file's
// (gpu_abi_tx_size), as it is not in a version 7 library built before the tx
// carried its fee cap and tip. The library a binary loads at run time need not
// be the one whose header it was built against.
var libraryABI uint32
// init reads the loaded library's ABI. A library of another ABI lays the
@@ -97,6 +99,9 @@ var libraryABI uint32
// every block is declined, and the caller runs it on its own EVM.
func init() {
libraryABI = uint32(C.gpu_abi_version())
if uint32(C.gpu_abi_tx_size()) != uint32(unsafe.Sizeof(C.CGpuTx{})) {
libraryABI = 0
}
}
// errOtherABI is ExecuteBlock's decline when the loaded library, or a result
@@ -327,8 +332,9 @@ func AvailableBackends() []Backend {
return out
}
// LibraryABIVersion returns the ABI the loaded library reports. When it is
// not ABIVersion, ExecuteBlock declines every block.
// LibraryABIVersion returns the ABI the loaded library speaks: the one it
// reports, or 0 where its CGpuTx is not this build's. When it is not
// ABIVersion, ExecuteBlock declines every block.
func LibraryABIVersion() uint32 {
return libraryABI
}
+2 -4
View File
@@ -232,10 +232,8 @@ func shape(txs types.Transactions, senders []common.Address, statedb *state.Stat
if !ok {
return out, i
}
tipCap, ok := fits(tx.GasTipCap())
if !ok {
return out, i
}
// The tip is at most the fee cap (carried), so it fits too.
tipCap := tx.GasTipCap().Uint64()
ct := cevm.Transaction{
GasLimit: tx.Gas(),
Nonce: tx.Nonce(),