Skip to content

Commit

Permalink
ibs: remove txnHash (#11657)
Browse files Browse the repository at this point in the history
- remove txnHash field
- simplified field `logs`: from `map[common.Hash][]*types.Log` to
`map[int][]*types.Log` (maybe in future can turn into array)
- `txnHash` left only in `GetLogs` method - where it used to fill 
- added method `GetRawLogs` which doesn't require calculated
`txn.Hash()`.
Example: if need filter logs and only then set `txn.Hash()` for filtered
logs - then no reason to calc for all transactions. (like in
`eth_getLogs`)

depends on #11656
  • Loading branch information
AskAlexSharov authored Sep 12, 2024
1 parent 60675ae commit 54dcd76
Show file tree
Hide file tree
Showing 26 changed files with 79 additions and 63 deletions.
4 changes: 2 additions & 2 deletions accounts/abi/bind/backends/simulated.go
Original file line number Diff line number Diff line change
Expand Up @@ -647,7 +647,7 @@ func (b *SimulatedBackend) EstimateGas(ctx context.Context, call ethereum.CallMs
}
}
gasCap = hi
b.pendingState.SetTxContext(libcommon.Hash{}, len(b.pendingBlock.Transactions()))
b.pendingState.SetTxContext(len(b.pendingBlock.Transactions()))

// Create a helper to check if a gas allowance results in an executable transaction
executable := func(gas uint64) (bool, *evmtypes.ExecutionResult, error) {
Expand Down Expand Up @@ -756,7 +756,7 @@ func (b *SimulatedBackend) SendTransaction(ctx context.Context, txn types.Transa
return fmt.Errorf("invalid transaction nonce: got %d, want %d", txn.GetNonce(), nonce)
}

b.pendingState.SetTxContext(txn.Hash(), len(b.pendingBlock.Transactions()))
b.pendingState.SetTxContext(len(b.pendingBlock.Transactions()))
//fmt.Printf("==== Start producing block %d, header: %d\n", b.pendingBlock.NumberU64(), b.pendingHeader.Number.Uint64())
if _, _, err := core.ApplyTransaction(
b.m.ChainConfig, core.GetHashFn(b.pendingHeader, b.getHeader), b.m.Engine,
Expand Down
2 changes: 1 addition & 1 deletion cmd/devnet/services/polygon/proofgenerator_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -179,7 +179,7 @@ func (rg *requestGenerator) GetTransactionReceipt(ctx context.Context, hash libc

for i, txn := range block.Transactions() {

ibs.SetTxContext(txn.Hash(), i)
ibs.SetTxContext(i)

receipt, _, err := core.ApplyTransaction(chainConfig, core.GetHashFn(header, getHeader), engine, nil, gp, ibs, noopWriter, header, txn, &usedGas, &usedBlobGas, vm.Config{})

Expand Down
2 changes: 1 addition & 1 deletion cmd/state/commands/opcode_tracer.go
Original file line number Diff line number Diff line change
Expand Up @@ -726,7 +726,7 @@ func runBlock(engine consensus.Engine, ibs *state.IntraBlockState, txnWriter sta
core.InitializeBlockExecution(engine, nil, header, chainConfig, ibs, logger, nil)
rules := chainConfig.Rules(block.NumberU64(), block.Time())
for i, txn := range block.Transactions() {
ibs.SetTxContext(txn.Hash(), i)
ibs.SetTxContext(i)
receipt, _, err := core.ApplyTransaction(chainConfig, core.GetHashFn(header, getHeader), engine, nil, gp, ibs, txnWriter, header, txn, usedGas, usedBlobGas, vmConfig)
if err != nil {
return nil, fmt.Errorf("could not apply txn %d [%x] failed: %w", i, txn.Hash(), err)
Expand Down
5 changes: 2 additions & 3 deletions cmd/state/exec3/historical_trace_worker.go
Original file line number Diff line number Diff line change
Expand Up @@ -179,14 +179,13 @@ func (rw *HistoricalTraceWorker) RunTxTask(txTask *state.TxTask) {
txTask.Error = err
}
default:
txHash := txTask.Tx.Hash()
rw.taskGasPool.Reset(txTask.Tx.GetGas(), rw.execArgs.ChainConfig.GetMaxBlobGasPerBlock())
if tracer := rw.consumer.NewTracer(); tracer != nil {
rw.vmConfig.Debug = true
rw.vmConfig.Tracer = tracer
}
rw.vmConfig.SkipAnalysis = txTask.SkipAnalysis
ibs.SetTxContext(txHash, txTask.TxIndex)
ibs.SetTxContext(txTask.TxIndex)
msg := txTask.TxAsMessage

rw.evm.ResetBetweenBlocks(txTask.EvmBlockContext, core.NewEVMTxContext(msg), ibs, *rw.vmConfig, rules)
Expand All @@ -208,7 +207,7 @@ func (rw *HistoricalTraceWorker) RunTxTask(txTask *state.TxTask) {
txTask.UsedGas = applyRes.UsedGas
// Update the state with pending changes
ibs.SoftFinalise()
txTask.Logs = ibs.GetLogs(txHash, rw.blockNum, rw.blockHash)
txTask.Logs = ibs.GetLogs(txTask.TxIndex, txTask.Tx.Hash(), txTask.BlockNum, txTask.BlockHash)
}
//txTask.Tracer = tracer
}
Expand Down
5 changes: 2 additions & 3 deletions cmd/state/exec3/state.go
Original file line number Diff line number Diff line change
Expand Up @@ -251,11 +251,10 @@ func (rw *Worker) RunTxTaskNoLock(txTask *state.TxTask, isMining bool) {
}
}
default:
txHash := txTask.Tx.Hash()
rw.taskGasPool.Reset(txTask.Tx.GetGas(), rw.chainConfig.GetMaxBlobGasPerBlock())
rw.callTracer.Reset()
rw.vmCfg.SkipAnalysis = txTask.SkipAnalysis
ibs.SetTxContext(txHash, txTask.TxIndex)
ibs.SetTxContext(txTask.TxIndex)
msg := txTask.TxAsMessage

rw.evm.ResetBetweenBlocks(txTask.EvmBlockContext, core.NewEVMTxContext(msg), ibs, rw.vmCfg, rules)
Expand All @@ -278,7 +277,7 @@ func (rw *Worker) RunTxTaskNoLock(txTask *state.TxTask, isMining bool) {
// Update the state with pending changes
ibs.SoftFinalise()
//txTask.Error = ibs.FinalizeTx(rules, noop)
txTask.Logs = ibs.GetLogs(txHash, txTask.BlockNum, txTask.BlockHash)
txTask.Logs = ibs.GetLogs(txTask.TxIndex, txTask.Tx.Hash(), txTask.BlockNum, txTask.BlockHash)
txTask.TraceFroms = rw.callTracer.Froms()
txTask.TraceTos = rw.callTracer.Tos()
}
Expand Down
2 changes: 1 addition & 1 deletion cmd/state/exec3/state_recon.go
Original file line number Diff line number Diff line change
Expand Up @@ -353,7 +353,7 @@ func (rw *ReconWorker) runTxTask(txTask *state.TxTask) error {
} else {
gp := new(core.GasPool).AddGas(txTask.Tx.GetGas()).AddBlobGas(txTask.Tx.GetBlobGas())
vmConfig := vm.Config{NoReceipts: true, SkipAnalysis: txTask.SkipAnalysis}
ibs.SetTxContext(txTask.Tx.Hash(), txTask.TxIndex)
ibs.SetTxContext(txTask.TxIndex)
msg := txTask.TxAsMessage

rw.evm.ResetBetweenBlocks(txTask.EvmBlockContext, core.NewEVMTxContext(msg), ibs, vmConfig, txTask.Rules)
Expand Down
8 changes: 4 additions & 4 deletions cmd/state/exec3/trace_worker.go
Original file line number Diff line number Diff line change
Expand Up @@ -99,15 +99,15 @@ func (e *TraceWorker) ChangeBlock(header *types.Header) {
e.vmConfig.SkipAnalysis = core.SkipAnalysis(e.chainConfig, e.blockNum)
}

func (e *TraceWorker) GetLogs(txIdx int, txn types.Transaction) types.Logs {
return e.ibs.GetLogs(txn.Hash(), e.blockNum, e.header.Hash())
func (e *TraceWorker) GetRawLogs(txIdx int) types.Logs { return e.ibs.GetRawLogs(txIdx) }
func (e *TraceWorker) GetLogs(txIndex int, txnHash common.Hash, blockNumber uint64, blockHash common.Hash) []*types.Log {
return e.ibs.GetLogs(txIndex, txnHash, blockNumber, blockHash)
}

func (e *TraceWorker) ExecTxn(txNum uint64, txIndex int, txn types.Transaction) (*evmtypes.ExecutionResult, error) {
e.stateReader.SetTxNum(txNum)
txHash := txn.Hash()
e.ibs.Reset()
e.ibs.SetTxContext(txHash, txIndex)
e.ibs.SetTxContext(txIndex)
gp := new(core.GasPool).AddGas(txn.GetGas()).AddBlobGas(txn.GetBlobGas())
msg, err := txn.AsMessage(*e.signer, e.header.BaseFee, e.rules)
if err != nil {
Expand Down
2 changes: 1 addition & 1 deletion core/blockchain.go
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ func ExecuteBlockEphemerally(
receipts := make(types.Receipts, 0, block.Transactions().Len())
noop := state.NewNoopWriter()
for i, txn := range block.Transactions() {
ibs.SetTxContext(txn.Hash(), i)
ibs.SetTxContext(i)
writeTrace := false
if vmConfig.Debug && vmConfig.Tracer == nil {
tracer, err := getTracer(i, txn.Hash())
Expand Down
4 changes: 2 additions & 2 deletions core/chain_makers.go
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,7 @@ func (b *BlockGen) AddTxWithChain(getHeader func(hash libcommon.Hash, number uin
if b.gasPool == nil {
b.SetCoinbase(libcommon.Address{})
}
b.ibs.SetTxContext(txn.Hash(), len(b.txs))
b.ibs.SetTxContext(len(b.txs))
receipt, _, err := ApplyTransaction(b.config, GetHashFn(b.header, getHeader), engine, &b.header.Coinbase, b.gasPool, b.ibs, state.NewNoopWriter(), b.header, txn, &b.header.GasUsed, b.header.BlobGasUsed, vm.Config{})
if err != nil {
panic(err)
Expand All @@ -141,7 +141,7 @@ func (b *BlockGen) AddFailedTxWithChain(getHeader func(hash libcommon.Hash, numb
if b.gasPool == nil {
b.SetCoinbase(libcommon.Address{})
}
b.ibs.SetTxContext(txn.Hash(), len(b.txs))
b.ibs.SetTxContext(len(b.txs))
receipt, _, err := ApplyTransaction(b.config, GetHashFn(b.header, getHeader), engine, &b.header.Coinbase, b.gasPool, b.ibs, state.NewNoopWriter(), b.header, txn, &b.header.GasUsed, b.header.BlobGasUsed, vm.Config{})
_ = err // accept failed transactions
b.txs = append(b.txs, txn)
Expand Down
42 changes: 27 additions & 15 deletions core/state/intra_block_state.go
Original file line number Diff line number Diff line change
Expand Up @@ -80,9 +80,8 @@ type IntraBlockState struct {
// The refund counter, also used by state transitioning.
refund uint64

thash libcommon.Hash
txIndex int
logs map[libcommon.Hash][]*types.Log
logs map[int][]*types.Log
logSize uint

// Per-transaction access list
Expand All @@ -107,11 +106,12 @@ func New(stateReader StateReader) *IntraBlockState {
stateObjects: map[libcommon.Address]*stateObject{},
stateObjectsDirty: map[libcommon.Address]struct{}{},
nilAccounts: map[libcommon.Address]struct{}{},
logs: map[libcommon.Hash][]*types.Log{},
logs: map[int][]*types.Log{},
journal: newJournal(),
accessList: newAccessList(),
transientStorage: newTransientStorage(),
balanceInc: map[libcommon.Address]*BalanceIncrease{},
txIndex: -1,
//trace: true,
}
}
Expand Down Expand Up @@ -155,32 +155,37 @@ func (sdb *IntraBlockState) Reset() {
//clear(sdb.stateObjects)
sdb.stateObjectsDirty = make(map[libcommon.Address]struct{})
//clear(sdb.stateObjectsDirty)
sdb.logs = make(map[libcommon.Hash][]*types.Log)
sdb.logs = make(map[int][]*types.Log)
sdb.balanceInc = make(map[libcommon.Address]*BalanceIncrease)
//clear(sdb.balanceInc)
sdb.thash = libcommon.Hash{}
sdb.txIndex = 0
sdb.txIndex = -1
sdb.logSize = 0
}

func (sdb *IntraBlockState) AddLog(log2 *types.Log) {
sdb.journal.append(addLogChange{txhash: sdb.thash})
log2.TxHash = sdb.thash
sdb.journal.append(addLogChange{txIndex: sdb.txIndex})
log2.TxIndex = uint(sdb.txIndex)
log2.Index = sdb.logSize
sdb.logs[sdb.thash] = append(sdb.logs[sdb.thash], log2)
sdb.logs[sdb.txIndex] = append(sdb.logs[sdb.txIndex], log2)
sdb.logSize++
}

func (sdb *IntraBlockState) GetLogs(hash libcommon.Hash, blockNumber uint64, blockHash libcommon.Hash) []*types.Log {
logs := sdb.logs[hash]
func (sdb *IntraBlockState) GetLogs(txIndex int, txnHash libcommon.Hash, blockNumber uint64, blockHash libcommon.Hash) []*types.Log {
logs := sdb.logs[txIndex]
for _, l := range logs {
l.TxHash = txnHash
l.BlockNumber = blockNumber
l.BlockHash = blockHash
}
return logs
}

// GetRawLogs - is like GetLogs, but allow postpone calculation of `txn.Hash()`.
// Example: if you need filter logs and only then set `txn.Hash()` for filtered logs - then no reason to calc for all transactions.
func (sdb *IntraBlockState) GetRawLogs(txIndex int) []*types.Log {
return sdb.logs[txIndex]
}

func (sdb *IntraBlockState) Logs() []*types.Log {
var logs []*types.Log
for _, lgs := range sdb.logs {
Expand Down Expand Up @@ -240,7 +245,7 @@ func (sdb *IntraBlockState) GetNonce(addr libcommon.Address) uint64 {
}

// TxIndex returns the current transaction index set by Prepare.
func (sdb *IntraBlockState) TxIndex() int {
func (sdb *IntraBlockState) TxnIndex() int {
return sdb.txIndex
}

Expand Down Expand Up @@ -817,11 +822,18 @@ func (sdb *IntraBlockState) Print(chainRules chain.Rules) {
}
}

// SetTxContext sets the current transaction hash and index and block hash which are
// SetTxContext sets the current transaction index which
// used when the EVM emits new state logs. It should be invoked before
// transaction execution.
func (sdb *IntraBlockState) SetTxContext(thash libcommon.Hash, ti int) {
sdb.thash = thash
func (sdb *IntraBlockState) SetTxContext(ti int) {
if len(sdb.logs) > 0 && ti == 0 {
err := fmt.Errorf("seems you forgot `ibs.Reset` or `ibs.TxIndex()`. len(sdb.logs)=%d, ti=%d", len(sdb.logs), ti)
panic(err)
}
if sdb.txIndex >= 0 && sdb.txIndex > ti {
err := fmt.Errorf("seems you forgot `ibs.Reset` or `ibs.TxIndex()`. sdb.txIndex=%d, ti=%d", sdb.txIndex, ti)
panic(err)
}
sdb.txIndex = ti
}

Expand Down
6 changes: 3 additions & 3 deletions core/state/intra_block_state_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -359,9 +359,9 @@ func (test *snapshotTest) checkEqual(state, checkstate *IntraBlockState) error {
return fmt.Errorf("got GetRefund() == %d, want GetRefund() == %d",
state.GetRefund(), checkstate.GetRefund())
}
if !reflect.DeepEqual(state.GetLogs(libcommon.Hash{}, 0, libcommon.Hash{}), checkstate.GetLogs(libcommon.Hash{}, 0, libcommon.Hash{})) {
return fmt.Errorf("got GetLogs(libcommon.Hash{}) == %v, want GetLogs(libcommon.Hash{}) == %v",
state.GetLogs(libcommon.Hash{}, 0, libcommon.Hash{}), checkstate.GetLogs(libcommon.Hash{}, 0, libcommon.Hash{}))
if !reflect.DeepEqual(state.GetRawLogs(0), checkstate.GetRawLogs(0)) {
return fmt.Errorf("got GetRawLogs(libcommon.Hash{}) == %v, want GetRawLogs(libcommon.Hash{}) == %v",
state.GetRawLogs(0), checkstate.GetRawLogs(0))
}
return nil
}
Expand Down
8 changes: 4 additions & 4 deletions core/state/journal.go
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,7 @@ type (
prev uint64
}
addLogChange struct {
txhash libcommon.Hash
txIndex int
}
touchChange struct {
account *libcommon.Address
Expand Down Expand Up @@ -288,11 +288,11 @@ func (ch refundChange) dirtied() *libcommon.Address {
}

func (ch addLogChange) revert(s *IntraBlockState) {
logs := s.logs[ch.txhash]
logs := s.logs[ch.txIndex]
if len(logs) == 1 {
delete(s.logs, ch.txhash)
delete(s.logs, ch.txIndex)
} else {
s.logs[ch.txhash] = logs[:len(logs)-1]
s.logs[ch.txIndex] = logs[:len(logs)-1]
}
s.logSize--
}
Expand Down
6 changes: 6 additions & 0 deletions core/state/txtask.go
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,12 @@ func (t *TxTask) CreateReceipt(cumulativeGasUsed uint64) *types.Receipt {
TxHash: t.Tx.Hash(),
Logs: t.Logs,
}
blockNum := t.Header.Number.Uint64()
for _, l := range receipt.Logs {
l.TxHash = receipt.TxHash
l.BlockNumber = blockNum
l.BlockHash = receipt.BlockHash
}
if t.Failed {
receipt.Status = types.ReceiptStatusFailed
} else {
Expand Down
4 changes: 2 additions & 2 deletions core/state_processor.go
Original file line number Diff line number Diff line change
Expand Up @@ -92,10 +92,10 @@ func applyTransaction(config *chain.Config, engine consensus.EngineReader, gp *G
receipt.ContractAddress = crypto.CreateAddress(evm.Origin, txn.GetNonce())
}
// Set the receipt logs and create a bloom for filtering
receipt.Logs = ibs.GetLogs(txn.Hash(), blockNum, header.Hash())
receipt.Logs = ibs.GetLogs(ibs.TxnIndex(), txn.Hash(), blockNum, header.Hash())
receipt.Bloom = types.CreateBloom(types.Receipts{receipt})
receipt.BlockNumber = header.Number
receipt.TransactionIndex = uint(ibs.TxIndex())
receipt.TransactionIndex = uint(ibs.TxnIndex())
}

return receipt, result.ReturnData, err
Expand Down
6 changes: 3 additions & 3 deletions eth/stagedsync/stage_mining_exec.go
Original file line number Diff line number Diff line change
Expand Up @@ -450,7 +450,7 @@ func addTransactionsToMiningBlock(logPrefix string, current *MiningBlock, chainC
engine consensus.Engine, txs types.TransactionsStream, coinbase libcommon.Address, ibs *state.IntraBlockState, ctx context.Context,
interrupt *int32, payloadId uint64, logger log.Logger) (types.Logs, bool, error) {
header := current.Header
tcount := 0
txnIdx := ibs.TxnIndex() + 1
gasPool := new(core.GasPool).AddGas(header.GasLimit - header.GasUsed)
if header.BlobGasUsed != nil {
gasPool.AddBlobGas(chainConfig.GetMaxBlobGasPerBlock() - *header.BlobGasUsed)
Expand All @@ -461,7 +461,7 @@ func addTransactionsToMiningBlock(logPrefix string, current *MiningBlock, chainC
noop := state.NewNoopWriter()

var miningCommitTx = func(txn types.Transaction, coinbase libcommon.Address, vmConfig *vm.Config, chainConfig chain.Config, ibs *state.IntraBlockState, current *MiningBlock) ([]*types.Log, error) {
ibs.SetTxContext(txn.Hash(), tcount)
ibs.SetTxContext(txnIdx)
gasSnap := gasPool.Gas()
blobGasSnap := gasPool.BlobGas()
snap := ibs.Snapshot()
Expand Down Expand Up @@ -555,7 +555,7 @@ LOOP:
// Everything ok, collect the logs and shift in the next transaction from the same account
logger.Trace(fmt.Sprintf("[%s] Added transaction", logPrefix), "hash", txn.Hash(), "sender", from, "nonce", txn.GetNonce(), "payload", payloadId)
coalescedLogs = append(coalescedLogs, logs...)
tcount++
txnIdx++
txs.Shift()
} else {
// Strange error, discard the transaction and get the next in line (note, the
Expand Down
2 changes: 1 addition & 1 deletion turbo/jsonrpc/erigon_receipts.go
Original file line number Diff line number Diff line change
Expand Up @@ -261,7 +261,7 @@ func (api *ErigonImpl) GetLatestLogs(ctx context.Context, crit filters.FilterCri
if err != nil {
return nil, err
}
blockLogs = exec.GetLogs(txIndex, txn)
blockLogs = exec.GetRawLogs(txIndex)
for _, log := range blockLogs {
log.Index = logIndex
logIndex++
Expand Down
2 changes: 1 addition & 1 deletion turbo/jsonrpc/eth_callMany.go
Original file line number Diff line number Diff line change
Expand Up @@ -210,7 +210,7 @@ func (api *APIImpl) CallMany(ctx context.Context, bundles []Bundle, simulateCont
// and apply the message.
gp := new(core.GasPool).AddGas(math.MaxUint64).AddBlobGas(math.MaxUint64)
for idx, txn := range replayTransactions {
st.SetTxContext(txn.Hash(), idx)
st.SetTxContext(idx)
msg, err := txn.AsMessage(*signer, block.BaseFee(), rules)
if err != nil {
return nil, err
Expand Down
2 changes: 1 addition & 1 deletion turbo/jsonrpc/eth_receipts.go
Original file line number Diff line number Diff line change
Expand Up @@ -331,7 +331,7 @@ func (api *BaseAPI) getLogsV3(ctx context.Context, tx kv.TemporalTx, begin, end
if err != nil {
return nil, err
}
rawLogs := exec.GetLogs(txIndex, txn)
rawLogs := exec.GetRawLogs(txIndex)
//TODO: logIndex within the block! no way to calc it now
//logIndex := uint(0)
//for _, log := range rawLogs {
Expand Down
2 changes: 1 addition & 1 deletion turbo/jsonrpc/otterscan_search_trace.go
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ func (api *OtterscanAPIImpl) traceBlock(dbtx kv.Tx, ctx context.Context, blockNu
return false, nil, ctx.Err()
default:
}
ibs.SetTxContext(txn.Hash(), idx)
ibs.SetTxContext(idx)

msg, _ := txn.AsMessage(*signer, header.BaseFee, rules)

Expand Down
2 changes: 1 addition & 1 deletion turbo/jsonrpc/otterscan_search_v3.go
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ func (api *OtterscanAPIImpl) buildSearchResults(ctx context.Context, tx kv.Tempo
if err != nil {
return nil, nil, false, err
}
rawLogs := exec.GetLogs(txIndex, txn)
rawLogs := exec.GetLogs(txIndex, txn.Hash(), blockNum, blockHash)
rpcTx := NewRPCTransaction(txn, blockHash, blockNum, uint64(txIndex), header.BaseFee)
txs = append(txs, rpcTx)
receipt := &types.Receipt{
Expand Down
Loading

0 comments on commit 54dcd76

Please sign in to comment.