feat: add sender+nonce index fro lookup

This commit is contained in:
jeevan-sid 2026-02-16 19:01:09 +05:30
parent 0cba803fba
commit e19e2e215f
3 changed files with 43 additions and 0 deletions

View file

@ -1281,6 +1281,11 @@ func (bc *BlockChain) writeHeadBlock(block *types.Block) {
rawdb.WriteHeadFastBlockHash(batch, block.Hash())
rawdb.WriteCanonicalHash(batch, block.Hash(), block.NumberU64())
rawdb.WriteTxLookupEntriesByBlock(batch, block)
signer := types.MakeSigner(bc.chainConfig, block.Number(), block.Time())
// Write sender+nonce index
rawdb.WriteTxSenderNonceEntryByBlock(batch, block, signer)
rawdb.WriteHeadBlockHash(batch, block.Hash())
// Flush the whole batch into the disk, exit the node if failed

View file

@ -134,6 +134,34 @@ func DeleteAllTxLookupEntries(db ethdb.KeyValueStore, condition func(common.Hash
}
}
// WriteTxSenderNonceIndex stores the mapping of sender+nonce to tx hash.
func WriteTxSenderNonceEntry(db ethdb.KeyValueWriter, sender common.Address, nonce uint64, hash common.Hash) {
if err := db.Put(txSenderNonceKey(sender, nonce), hash.Bytes()); err != nil {
log.Crit("Failed to store sender nonce index", "err", err)
}
}
// WriteTxSenderNonceIndexByBlock stores a sender+nonce to transaction hash mapping
// for every transaction in a block, enabling sender and nonce based transaction lookups.
func WriteTxSenderNonceEntryByBlock(db ethdb.KeyValueWriter, block *types.Block, signer types.Signer) {
for _, tx := range block.Transactions() {
if sender, err := types.Sender(signer, tx); err == nil {
WriteTxSenderNonceEntry(db, sender, tx.Nonce(), tx.Hash())
}
}
}
// ReadTxSenderNonceIndex retrieves the hash for a specific sender and nonce.
func ReadTxSenderNonceEntry(db ethdb.KeyValueReader, sender common.Address, nonce uint64) *common.Hash {
data, _ := db.Get(txSenderNonceKey(sender, nonce))
if len(data) == 0 {
return nil
}
hash := common.BytesToHash(data)
return &hash
}
// findTxInBlockBody traverses the given RLP-encoded block body, searching for
// the transaction specified by its hash.
func findTxInBlockBody(blockbody rlp.RawValue, target common.Hash) (*types.Transaction, uint64, error) {

View file

@ -114,6 +114,7 @@ var (
blockReceiptsPrefix = []byte("r") // blockReceiptsPrefix + num (uint64 big endian) + hash -> block receipts
txLookupPrefix = []byte("l") // txLookupPrefix + hash -> transaction/receipt lookup metadata
txSenderNoncePrefix = []byte("x") // txSenderNoncePrefix + sender + nonce -> transaction hash
bloomBitsPrefix = []byte("B") // bloomBitsPrefix + bit (uint16 big endian) + section (uint64 big endian) + hash -> bloom bits
SnapshotAccountPrefix = []byte("a") // SnapshotAccountPrefix + account hash -> account trie value
SnapshotStoragePrefix = []byte("o") // SnapshotStoragePrefix + account hash + storage hash -> storage trie value
@ -219,6 +220,15 @@ func txLookupKey(hash common.Hash) []byte {
return append(txLookupPrefix, hash.Bytes()...)
}
// txSenderNonceKey = txSenderNoncePrefix + sender + nonce -> transaction hash
func txSenderNonceKey(sender common.Address, nonce uint64) []byte {
buf := make([]byte, len(txSenderNoncePrefix)+common.AddressLength+8)
n := copy(buf, txSenderNoncePrefix)
n += copy(buf[n:], sender.Bytes())
binary.BigEndian.PutUint64(buf[n:], nonce)
return buf
}
// accountSnapshotKey = SnapshotAccountPrefix + hash
func accountSnapshotKey(hash common.Hash) []byte {
return append(SnapshotAccountPrefix, hash.Bytes()...)