Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
4d2aa89
feat: implement temporary authorized account priority transaction ord…
hominlee-wemade Nov 11, 2025
aaf4be9
test: add test cases for authorized account transaction ordering
hominlee-wemade Nov 11, 2025
b780da4
chore: remove comment
hominlee-wemade Nov 11, 2025
cac1120
feat: update msg.GasTipCap handling in TransactionToMessage for autho…
hominlee-wemade Nov 12, 2025
04121e5
feat: pass stateDB as input parameter to TransactionToMessag
hominlee-wemade Nov 12, 2025
31485b7
feat: move effectiveGasPrice calculation for authorized accounts to a…
hominlee-wemade Nov 12, 2025
86ae900
test: add gas fee calculation tests for authorized and normal accounts
hominlee-wemade Nov 12, 2025
b6534ed
chore: change comment
hominlee-wemade Nov 12, 2025
d4cff59
chore: remove comment
hominlee-wemade Nov 12, 2025
8116c28
fix: adjust tip calculation logic
hominlee-wemade Nov 13, 2025
f211825
fix: check EffectiveGasPrice
hominlee-wemade Nov 13, 2025
b0bb2ce
test: add receipt derivation test for authorized account
hominlee-wemade Nov 13, 2025
845d9d4
refactor: use stateDB to determine authorized accounts instead of tem…
hominlee-wemade Nov 13, 2025
54deb6d
fix: handle nil minerFee when EffectiveGasPrice is missing
hominlee-wemade Nov 13, 2025
d3fff73
Add StateReader interface for IsAuthorized checks in receipts
hominlee-wemade Nov 14, 2025
a501177
fix: test failure
hominlee-wemade Nov 14, 2025
038e1e7
test: add tx ordering benchmarks
hominlee-wemade Nov 14, 2025
55a4ba8
refactor: remove unused baseFee argument from applyTransaction
hominlee-wemade Nov 17, 2025
cb18cc8
feat: implement Anzeon fee policy in priceHeap
hominlee-wemade Nov 18, 2025
0d52507
chore: change comment
hominlee-wemade Nov 18, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion cmd/evm/internal/t8ntool/execution.go
Original file line number Diff line number Diff line change
Expand Up @@ -206,7 +206,7 @@ func (pre *Prestate) Apply(vmConfig vm.Config, chainConfig *params.ChainConfig,
rejectedTxs = append(rejectedTxs, &rejectedTx{i, errMsg})
continue
}
msg, err := core.TransactionToMessage(tx, signer, pre.Env.BaseFee, nil)
msg, err := core.TransactionToMessage(tx, signer, pre.Env.BaseFee, nil, statedb)
if err != nil {
log.Warn("rejected tx", "index", i, "hash", tx.Hash(), "error", err)
rejectedTxs = append(rejectedTxs, &rejectedTx{i, err.Error()})
Expand Down
2 changes: 1 addition & 1 deletion core/bench_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -322,7 +322,7 @@ func benchReadChain(b *testing.B, full bool, count uint64) {
if full {
hash := header.Hash()
rawdb.ReadBody(db, hash, n)
rawdb.ReadReceipts(db, hash, n, header.Time, chain.Config())
rawdb.ReadReceipts(db, hash, n, header.Time, chain.Config(), nil)
}
}
chain.Stop()
Expand Down
7 changes: 6 additions & 1 deletion core/blockchain.go
Original file line number Diff line number Diff line change
Expand Up @@ -2120,7 +2120,12 @@ func (bc *BlockChain) collectLogs(b *types.Block, removed bool) []*types.Log {
headerGasTip = b.Header().GasTip()
}

if err := receipts.DeriveFields(bc.chainConfig, b.Hash(), b.NumberU64(), b.Time(), b.BaseFee(), headerGasTip, blobGasPrice, b.Transactions()); err != nil {
var stateReader rawdb.StateReader
if statedb, err := bc.StateAt(b.Root()); err == nil {
stateReader = statedb
}

if err := receipts.DeriveFields(bc.chainConfig, b.Hash(), b.NumberU64(), b.Time(), b.BaseFee(), headerGasTip, blobGasPrice, b.Transactions(), stateReader); err != nil {
log.Error("Failed to derive block receipts fields", "hash", b.Hash(), "number", b.NumberU64(), "err", err)
}
var logs []*types.Log
Expand Down
8 changes: 7 additions & 1 deletion core/blockchain_reader.go
Original file line number Diff line number Diff line change
Expand Up @@ -227,7 +227,13 @@ func (bc *BlockChain) GetReceiptsByHash(hash common.Hash) types.Receipts {
if header == nil {
return nil
}
receipts := rawdb.ReadReceipts(bc.db, hash, *number, header.Time, bc.chainConfig)

var stateReader rawdb.StateReader
if statedb, err := bc.StateAt(header.Root); err == nil {
stateReader = statedb
}

receipts := rawdb.ReadReceipts(bc.db, hash, *number, header.Time, bc.chainConfig, stateReader)
if receipts == nil {
return nil
}
Expand Down
12 changes: 6 additions & 6 deletions core/blockchain_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -927,9 +927,9 @@ func testFastVsFullChains(t *testing.T, scheme string) {
}

// Check receipts.
freceipts := rawdb.ReadReceipts(fastDb, hash, num, time, fast.Config())
anreceipts := rawdb.ReadReceipts(ancientDb, hash, num, time, fast.Config())
areceipts := rawdb.ReadReceipts(archiveDb, hash, num, time, fast.Config())
freceipts := rawdb.ReadReceipts(fastDb, hash, num, time, fast.Config(), nil)
anreceipts := rawdb.ReadReceipts(ancientDb, hash, num, time, fast.Config(), nil)
areceipts := rawdb.ReadReceipts(archiveDb, hash, num, time, fast.Config(), nil)
if types.DeriveSha(freceipts, trie.NewStackTrie(nil)) != types.DeriveSha(areceipts, trie.NewStackTrie(nil)) {
t.Errorf("block #%d [%x]: receipts mismatch: fastdb %v, ancientdb %v, archivedb %v", num, hash, freceipts, anreceipts, areceipts)
}
Expand Down Expand Up @@ -1171,7 +1171,7 @@ func testChainTxReorgs(t *testing.T, scheme string) {
if txn, _, _, _ := rawdb.ReadTransaction(db, tx.Hash()); txn != nil {
t.Errorf("drop %d: tx %v found while shouldn't have been", i, txn)
}
if rcpt, _, _, _ := rawdb.ReadReceipt(db, tx.Hash(), blockchain.Config()); rcpt != nil {
if rcpt, _, _, _ := rawdb.ReadReceipt(db, tx.Hash(), blockchain.Config(), nil); rcpt != nil {
t.Errorf("drop %d: receipt %v found while shouldn't have been", i, rcpt)
}
}
Expand All @@ -1180,7 +1180,7 @@ func testChainTxReorgs(t *testing.T, scheme string) {
if txn, _, _, _ := rawdb.ReadTransaction(db, tx.Hash()); txn == nil {
t.Errorf("add %d: expected tx to be found", i)
}
if rcpt, _, _, _ := rawdb.ReadReceipt(db, tx.Hash(), blockchain.Config()); rcpt == nil {
if rcpt, _, _, _ := rawdb.ReadReceipt(db, tx.Hash(), blockchain.Config(), nil); rcpt == nil {
t.Errorf("add %d: expected receipt to be found", i)
}
}
Expand All @@ -1189,7 +1189,7 @@ func testChainTxReorgs(t *testing.T, scheme string) {
if txn, _, _, _ := rawdb.ReadTransaction(db, tx.Hash()); txn == nil {
t.Errorf("share %d: expected tx to be found", i)
}
if rcpt, _, _, _ := rawdb.ReadReceipt(db, tx.Hash(), blockchain.Config()); rcpt == nil {
if rcpt, _, _, _ := rawdb.ReadReceipt(db, tx.Hash(), blockchain.Config(), nil); rcpt == nil {
t.Errorf("share %d: expected receipt to be found", i)
}
}
Expand Down
7 changes: 6 additions & 1 deletion core/chain_makers.go
Original file line number Diff line number Diff line change
Expand Up @@ -414,7 +414,12 @@ func GenerateChain(config *params.ChainConfig, parent *types.Block, engine conse
headerGasTip = block.Header().GasTip()
}

if err := receipts.DeriveFields(config, block.Hash(), block.NumberU64(), block.Time(), block.BaseFee(), headerGasTip, blobGasPrice, txs); err != nil {
var stateReader rawdb.StateReader
if statedb, err := cm.StateAt(block.Root()); err == nil {
stateReader = statedb
}

if err := receipts.DeriveFields(config, block.Hash(), block.NumberU64(), block.Time(), block.BaseFee(), headerGasTip, blobGasPrice, txs, stateReader); err != nil {
panic(err)
}

Expand Down
8 changes: 6 additions & 2 deletions core/rawdb/accessors_chain.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,10 @@ import (
"golang.org/x/exp/slices"
)

// StateReader is an alias for types.StateReader to maintain backward compatibility.
// The interface is defined in types package to avoid circular dependencies.
type StateReader = types.StateReader

// ReadCanonicalHash retrieves the hash assigned to a canonical block number.
func ReadCanonicalHash(db ethdb.Reader, number uint64) common.Hash {
var data []byte
Expand Down Expand Up @@ -623,7 +627,7 @@ func ReadRawReceipts(db ethdb.Reader, hash common.Hash, number uint64) types.Rec
// The current implementation populates these metadata fields by reading the receipts'
// corresponding block body, so if the block body is not found it will return nil even
// if the receipt itself is stored.
func ReadReceipts(db ethdb.Reader, hash common.Hash, number uint64, time uint64, config *params.ChainConfig) types.Receipts {
func ReadReceipts(db ethdb.Reader, hash common.Hash, number uint64, time uint64, config *params.ChainConfig, stateReader StateReader) types.Receipts {
// We're deriving many fields from the block body, retrieve beside the receipt
receipts := ReadRawReceipts(db, hash, number)
if receipts == nil {
Expand Down Expand Up @@ -654,7 +658,7 @@ func ReadReceipts(db ethdb.Reader, hash common.Hash, number uint64, time uint64,
headerGasTip = new(big.Int).Set(header.GasTip())
}

if err := receipts.DeriveFields(config, hash, number, time, baseFee, headerGasTip, blobGasPrice, body.Transactions); err != nil {
if err := receipts.DeriveFields(config, hash, number, time, baseFee, headerGasTip, blobGasPrice, body.Transactions, stateReader); err != nil {
log.Error("Failed to derive block receipts fields", "hash", hash, "number", number, "err", err)
return nil
}
Expand Down
10 changes: 5 additions & 5 deletions core/rawdb/accessors_chain_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -379,15 +379,15 @@ func TestBlockReceiptStorage(t *testing.T) {

// Check that no receipt entries are in a pristine database
hash := common.BytesToHash([]byte{0x03, 0x14})
if rs := ReadReceipts(db, hash, 0, 0, params.TestChainConfig); len(rs) != 0 {
if rs := ReadReceipts(db, hash, 0, 0, params.TestChainConfig, nil); len(rs) != 0 {
t.Fatalf("non existent receipts returned: %v", rs)
}
// Insert the body that corresponds to the receipts
WriteBody(db, hash, 0, body)

// Insert the receipt slice into the database and check presence
WriteReceipts(db, hash, 0, receipts)
if rs := ReadReceipts(db, hash, 0, 0, params.TestChainConfig); len(rs) == 0 {
if rs := ReadReceipts(db, hash, 0, 0, params.TestChainConfig, nil); len(rs) == 0 {
t.Fatalf("no receipts returned")
} else {
if err := checkReceiptsRLP(rs, receipts); err != nil {
Expand All @@ -396,7 +396,7 @@ func TestBlockReceiptStorage(t *testing.T) {
}
// Delete the body and ensure that the receipts are no longer returned (metadata can't be recomputed)
DeleteBody(db, hash, 0)
if rs := ReadReceipts(db, hash, 0, 0, params.TestChainConfig); rs != nil {
if rs := ReadReceipts(db, hash, 0, 0, params.TestChainConfig, nil); rs != nil {
t.Fatalf("receipts returned when body was deleted: %v", rs)
}
// Ensure that receipts without metadata can be returned without the block body too
Expand All @@ -407,7 +407,7 @@ func TestBlockReceiptStorage(t *testing.T) {
WriteBody(db, hash, 0, body)

DeleteReceipts(db, hash, 0)
if rs := ReadReceipts(db, hash, 0, 0, params.TestChainConfig); len(rs) != 0 {
if rs := ReadReceipts(db, hash, 0, 0, params.TestChainConfig, nil); len(rs) != 0 {
t.Fatalf("deleted receipts returned: %v", rs)
}
}
Expand Down Expand Up @@ -727,7 +727,7 @@ func TestReadLogs(t *testing.T) {

hash := common.BytesToHash([]byte{0x03, 0x14})
// Check that no receipt entries are in a pristine database
if rs := ReadReceipts(db, hash, 0, 0, params.TestChainConfig); len(rs) != 0 {
if rs := ReadReceipts(db, hash, 0, 0, params.TestChainConfig, nil); len(rs) != 0 {
t.Fatalf("non existent receipts returned: %v", rs)
}
// Insert the body that corresponds to the receipts
Expand Down
4 changes: 2 additions & 2 deletions core/rawdb/accessors_indexes.go
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,7 @@ func ReadTransaction(db ethdb.Reader, hash common.Hash) (*types.Transaction, com

// ReadReceipt retrieves a specific transaction receipt from the database, along with
// its added positional metadata.
func ReadReceipt(db ethdb.Reader, hash common.Hash, config *params.ChainConfig) (*types.Receipt, common.Hash, uint64, uint64) {
func ReadReceipt(db ethdb.Reader, hash common.Hash, config *params.ChainConfig, stateReader StateReader) (*types.Receipt, common.Hash, uint64, uint64) {
// Retrieve the context of the receipt based on the transaction hash
blockNumber := ReadTxLookupEntry(db, hash)
if blockNumber == nil {
Expand All @@ -135,7 +135,7 @@ func ReadReceipt(db ethdb.Reader, hash common.Hash, config *params.ChainConfig)
return nil, common.Hash{}, 0, 0
}
// Read all the receipts from the block and return the one with the matching hash
receipts := ReadReceipts(db, blockHash, *blockNumber, blockHeader.Time, config)
receipts := ReadReceipts(db, blockHash, *blockNumber, blockHeader.Time, config, stateReader)
for receiptIndex, receipt := range receipts {
if receipt.TxHash == hash {
return receipt, blockHash, *blockNumber, uint64(receiptIndex)
Expand Down
2 changes: 1 addition & 1 deletion core/state_prefetcher.go
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ func (p *statePrefetcher) Prefetch(block *types.Block, statedb *state.StateDB, c
}

// Convert the transaction into an executable message and pre-cache its sender
msg, err := TransactionToMessage(tx, signer, header.BaseFee, header.GasTip())
msg, err := TransactionToMessage(tx, signer, header.BaseFee, header.GasTip(), statedb)
if err != nil {
return // Also invalid block, bail out
}
Expand Down
4 changes: 2 additions & 2 deletions core/state_processor.go
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ func (p *StateProcessor) Process(block *types.Block, statedb *state.StateDB, cfg
}
// Iterate over and process the individual transactions
for i, tx := range block.Transactions() {
msg, err := TransactionToMessage(tx, signer, header.BaseFee, header.GasTip())
msg, err := TransactionToMessage(tx, signer, header.BaseFee, header.GasTip(), statedb)
if err != nil {
return nil, nil, 0, fmt.Errorf("could not apply tx %d [%v]: %w", i, tx.Hash().Hex(), err)
}
Expand Down Expand Up @@ -161,7 +161,7 @@ func applyTransaction(msg *Message, config *params.ChainConfig, gp *GasPool, sta
// for the transaction, gas used and an error if the transaction failed,
// indicating the block was invalid.
func ApplyTransaction(config *params.ChainConfig, bc ChainContext, author *common.Address, gp *GasPool, statedb *state.StateDB, header *types.Header, tx *types.Transaction, usedGas *uint64, cfg vm.Config) (*types.Receipt, error) {
msg, err := TransactionToMessage(tx, types.MakeSigner(config, header.Number, header.Time), header.BaseFee, header.GasTip())
msg, err := TransactionToMessage(tx, types.MakeSigner(config, header.Number, header.Time), header.BaseFee, header.GasTip(), statedb)
if err != nil {
return nil, err
}
Expand Down
Loading