e3: use deserializeV3 for history (#7691)

This commit is contained in:
Alex Sharov 2023-06-09 10:53:04 +07:00 committed by GitHub
parent 7671f419f8
commit afa4f53ae2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 48 additions and 74 deletions

View File

@ -32,7 +32,6 @@ import (
"github.com/ledgerwatch/erigon-lib/kv"
state2 "github.com/ledgerwatch/erigon-lib/state"
types2 "github.com/ledgerwatch/erigon-lib/types"
"github.com/ledgerwatch/erigon/eth/ethconfig"
"github.com/ledgerwatch/erigon/turbo/services"
"github.com/ledgerwatch/log/v3"
@ -184,13 +183,7 @@ func (b *SimulatedBackend) emptyPendingBlock() {
panic(err)
}
b.pendingReaderTx = tx
if ethconfig.EnableHistoryV4InTest {
panic("implement me")
//b.pendingReader = state.NewReaderV4(b.pendingReaderTx.(kv.TemporalTx))
} else {
b.pendingReader = state.NewPlainStateReader(b.pendingReaderTx)
}
b.pendingReader = b.m.NewStateReader(b.pendingReaderTx)
b.pendingState = state.New(b.pendingReader)
}

View File

@ -24,11 +24,13 @@ import (
"github.com/ledgerwatch/erigon-lib/chain"
libcommon "github.com/ledgerwatch/erigon-lib/common"
"github.com/ledgerwatch/erigon-lib/kv"
"github.com/ledgerwatch/erigon/common"
"github.com/ledgerwatch/erigon/common/math"
"github.com/ledgerwatch/erigon/consensus/ethash"
"github.com/ledgerwatch/erigon/core/state"
"github.com/ledgerwatch/erigon/core/types"
"github.com/ledgerwatch/erigon/turbo/rpchelper"
)
type Prestate struct {
@ -73,9 +75,9 @@ type stEnvMarshaling struct {
BaseFee *math.HexOrDecimal256
}
func MakePreState(chainRules *chain.Rules, tx kv.RwTx, accounts types.GenesisAlloc) (*state.PlainStateReader, *state.PlainStateWriter) {
func MakePreState(chainRules *chain.Rules, tx kv.RwTx, accounts types.GenesisAlloc) (state.StateReader, *state.PlainStateWriter) {
var blockNr uint64 = 0
stateReader, stateWriter := state.NewPlainStateReader(tx), state.NewPlainStateWriter(tx, tx, blockNr)
stateReader, stateWriter := rpchelper.NewLatestStateReader(tx), state.NewPlainStateWriter(tx, tx, blockNr)
statedb := state.New(stateReader) //ibs
for addr, a := range accounts {
statedb.SetCode(addr, a.Code)

View File

@ -13,12 +13,11 @@ import (
"github.com/ledgerwatch/erigon-lib/kv/order"
"github.com/ledgerwatch/erigon-lib/kv/rawdbv3"
"github.com/ledgerwatch/erigon-lib/kv/temporal/historyv2"
"github.com/ledgerwatch/erigon/core/state/temporal"
"github.com/ledgerwatch/erigon/eth/stagedsync/stages"
"github.com/ledgerwatch/log/v3"
"github.com/ledgerwatch/erigon/core/state"
"github.com/ledgerwatch/erigon/core/state/temporal"
"github.com/ledgerwatch/erigon/core/types/accounts"
"github.com/ledgerwatch/erigon/turbo/rpchelper"
)
type ContractCreatorData struct {
@ -33,8 +32,8 @@ func (api *OtterscanAPIImpl) GetContractCreator(ctx context.Context, addr common
}
defer tx.Rollback()
reader := state.NewPlainStateReader(tx)
plainStateAcc, err := reader.ReadAccountData(addr)
latestState := rpchelper.NewLatestStateReader(tx)
plainStateAcc, err := latestState.ReadAccountData(addr)
if err != nil {
return nil, err
}
@ -57,14 +56,6 @@ func (api *OtterscanAPIImpl) GetContractCreator(ctx context.Context, addr common
var acc accounts.Account
if api.historyV3(tx) {
ttx := tx.(kv.TemporalTx)
headNumber, err := stages.GetStageProgress(tx, stages.Execution)
if err != nil {
return nil, err
}
lastTxNum, err := rawdbv3.TxNums.Max(tx, headNumber)
if err != nil {
return nil, err
}
// Contract; search for creation tx; navigate forward on AccountsHistory/ChangeSets
//
@ -75,7 +66,7 @@ func (api *OtterscanAPIImpl) GetContractCreator(ctx context.Context, addr common
// so it is optimal to search from the beginning even if the contract has multiple
// incarnations.
var prevTxnID, nextTxnID uint64
it, err := ttx.IndexRange(temporal.AccountsHistoryIdx, addr[:], 0, int(lastTxNum+1), order.Asc, kv.Unlim)
it, err := ttx.IndexRange(temporal.AccountsHistoryIdx, addr[:], 0, -1, order.Asc, kv.Unlim)
if err != nil {
return nil, err
}
@ -92,10 +83,9 @@ func (api *OtterscanAPIImpl) GetContractCreator(ctx context.Context, addr common
v, ok, err := ttx.HistoryGet(temporal.AccountsHistory, addr[:], txnID)
if err != nil {
log.Error("Unexpected error, couldn't find changeset", "txNum", i, "addr", addr)
log.Error("Unexpected error, couldn't find changeset", "txNum", txnID, "addr", addr)
return nil, err
}
fmt.Printf("i: %d, %t, %x\n", i, ok, v)
if !ok {
err = fmt.Errorf("couldn't find history txnID=%v addr=%v", txnID, addr)
@ -107,7 +97,7 @@ func (api *OtterscanAPIImpl) GetContractCreator(ctx context.Context, addr common
continue
}
if err := acc.DecodeForStorage(v); err != nil {
if err := accounts.DeserialiseV3(&acc, v); err != nil {
return nil, err
}
// Found the shard where the incarnation change happens; ignore all next index values
@ -145,7 +135,7 @@ func (api *OtterscanAPIImpl) GetContractCreator(ctx context.Context, addr common
return false
}
if err := acc.DecodeForStorage(v); err != nil {
if err := accounts.DeserialiseV3(&acc, v); err != nil {
searchErr = err
return false
}

View File

@ -62,7 +62,7 @@ func (api *OtterscanAPIImpl) GetTransactionBySenderAndNonce(ctx context.Context,
continue
}
if err := acc.DecodeForStorage(v); err != nil {
if err := accounts.DeserialiseV3(&acc, v); err != nil {
return nil, err
}
// Desired nonce was found in this chunk
@ -99,10 +99,11 @@ func (api *OtterscanAPIImpl) GetTransactionBySenderAndNonce(ctx context.Context,
return false
}
if err := acc.DecodeForStorage(v); err != nil {
if err := accounts.DeserialiseV3(&acc, v); err != nil {
searchErr = err
return false
}
// Since the state contains the nonce BEFORE the block changes, we look for
// the block when the nonce changed to be > the desired once, which means the
// previous history block contains the actual change; it may contain multiple

View File

@ -9,8 +9,8 @@ import (
"github.com/ledgerwatch/erigon-lib/common/hexutility"
"github.com/ledgerwatch/erigon-lib/common/length"
"github.com/ledgerwatch/erigon-lib/kv"
"github.com/ledgerwatch/erigon/turbo/rpchelper"
"github.com/ledgerwatch/erigon/core/state"
"github.com/ledgerwatch/erigon/rpc"
)
@ -46,7 +46,7 @@ func (api *ParityAPIImpl) ListStorageKeys(ctx context.Context, account libcommon
return nil, fmt.Errorf("listStorageKeys cannot open tx: %w", err)
}
defer tx.Rollback()
a, err := state.NewPlainStateReader(tx).ReadAccountData(account)
a, err := rpchelper.NewLatestStateReader(tx).ReadAccountData(account)
if err != nil {
return nil, err
} else if a == nil {

View File

@ -117,7 +117,6 @@ func ExecuteBlockEphemerally(
vmConfig.Tracer = tracer
writeTrace = true
}
receipt, _, err := ApplyTransaction(chainConfig, blockHashFunc, engine, nil, gp, ibs, noop, header, tx, usedGas, *vmConfig)
if writeTrace {
if ftracer, ok := vmConfig.Tracer.(vm.FlushableTracer); ok {

View File

@ -25,8 +25,6 @@ import (
libcommon "github.com/ledgerwatch/erigon-lib/common"
"github.com/ledgerwatch/erigon-lib/common/length"
"github.com/ledgerwatch/erigon-lib/kv"
"github.com/ledgerwatch/erigon/core/systemcontracts"
"github.com/ledgerwatch/erigon/eth/ethconfig"
"github.com/ledgerwatch/log/v3"
"github.com/ledgerwatch/erigon/common"
@ -34,9 +32,12 @@ import (
"github.com/ledgerwatch/erigon/consensus/merge"
"github.com/ledgerwatch/erigon/consensus/misc"
"github.com/ledgerwatch/erigon/core/state"
"github.com/ledgerwatch/erigon/core/systemcontracts"
"github.com/ledgerwatch/erigon/core/types"
"github.com/ledgerwatch/erigon/core/vm"
"github.com/ledgerwatch/erigon/eth/ethconfig"
"github.com/ledgerwatch/erigon/params"
"github.com/ledgerwatch/erigon/turbo/rpchelper"
"github.com/ledgerwatch/erigon/turbo/trie"
)
@ -355,13 +356,11 @@ func GenerateChain(config *chain.Config, parent *types.Block, engine consensus.E
var txNum uint64
for i := 0; i < n; i++ {
var stateReader state.StateReader
stateReader := rpchelper.NewLatestStateReader(tx)
var stateWriter state.StateWriter
if ethconfig.EnableHistoryV4InTest {
panic("implement me on v4")
} else {
stateReader = state.NewPlainStateReader(tx)
stateWriter = state.NewPlainStateWriter(tx, nil, parent.NumberU64()+uint64(i)+1)
}
ibs := state.New(stateReader)

View File

@ -384,10 +384,16 @@ func ReadStorageBody(db kv.Getter, hash libcommon.Hash, number uint64) (types.Bo
return *bodyForStorage, nil
}
func CanonicalTxnByID(db kv.Getter, id uint64) (types.Transaction, error) {
txIdKey := make([]byte, 8)
binary.BigEndian.PutUint64(txIdKey, id)
v, err := db.GetOne(kv.EthTx, txIdKey)
func TxnByIdxInBlock(db kv.Getter, blockHash libcommon.Hash, blockNum uint64, txIdxInBlock int) (types.Transaction, error) {
b, err := ReadBodyForStorageByKey(db, dbutils.BlockBodyKey(blockNum, blockHash))
if err != nil {
return nil, err
}
if b == nil {
return nil, nil
}
v, err := db.GetOne(kv.EthTx, hexutility.EncodeTs(b.BaseTxId+1+uint64(txIdxInBlock)))
if err != nil {
return nil, err
}

View File

@ -45,6 +45,7 @@ import (
"github.com/ledgerwatch/erigon/crypto"
"github.com/ledgerwatch/erigon/params"
"github.com/ledgerwatch/erigon/rlp"
"github.com/ledgerwatch/erigon/turbo/rpchelper"
"github.com/ledgerwatch/erigon/turbo/trie"
)
@ -194,12 +195,7 @@ func (t *StateTest) RunNoVerify(tx kv.RwTx, subtest StateSubtest, vmconfig vm.Co
return nil, libcommon.Hash{}, UnsupportedForkError{subtest.Fork}
}
var r state.StateReader
if ethconfig.EnableHistoryV4InTest {
panic("implement me")
} else {
r = state.NewPlainStateReader(tx)
}
r := rpchelper.NewLatestStateReader(tx)
statedb := state.New(r)
var w state.StateWriter
@ -311,12 +307,7 @@ func (t *StateTest) RunNoVerify(tx kv.RwTx, subtest StateSubtest, vmconfig vm.Co
}
func MakePreState(rules *chain.Rules, tx kv.RwTx, accounts types.GenesisAlloc, blockNr uint64) (*state.IntraBlockState, error) {
var r state.StateReader
if ethconfig.EnableHistoryV4InTest {
panic("implement me")
} else {
r = state.NewPlainStateReader(tx)
}
r := rpchelper.NewLatestStateReader(tx)
statedb := state.New(r)
for addr, a := range accounts {
statedb.SetCode(addr, a.Code)

View File

@ -11,6 +11,7 @@ import (
"github.com/ledgerwatch/erigon/core/rawdb"
"github.com/ledgerwatch/erigon/core/state"
"github.com/ledgerwatch/erigon/core/systemcontracts"
"github.com/ledgerwatch/erigon/eth/ethconfig"
"github.com/ledgerwatch/erigon/eth/stagedsync/stages"
"github.com/ledgerwatch/erigon/rpc"
)
@ -129,3 +130,11 @@ func CreateHistoryStateReader(tx kv.Tx, blockNumber uint64, txnIndex int, histor
r.SetTxNum(uint64(int(minTxNum) + txnIndex + 1))
return r, nil
}
func NewLatestStateReader(tx kv.Getter) state.StateReader {
if ethconfig.EnableHistoryV4InTest {
panic("implement me")
//b.pendingReader = state.NewReaderV4(b.pendingReaderTx.(kv.TemporalTx))
}
return state.NewPlainStateReader(tx)
}

View File

@ -3,7 +3,6 @@ package snapshotsync
import (
"bytes"
"context"
"encoding/binary"
"fmt"
"github.com/ledgerwatch/erigon-lib/common"
@ -685,29 +684,14 @@ func (r *BlockReader) txnByHash(txnHash common.Hash, segments []*TxnSegment, buf
// TxnByIdxInBlock - doesn't include system-transactions in the begin/end of block
// return nil if 0 < i < body.TxAmount
func (r *BlockReader) TxnByIdxInBlock(ctx context.Context, tx kv.Getter, blockNum uint64, i int) (txn types.Transaction, err error) {
func (r *BlockReader) TxnByIdxInBlock(ctx context.Context, tx kv.Getter, blockNum uint64, txIdxInBlock int) (txn types.Transaction, err error) {
blocksAvailable := r.sn.BlocksAvailable()
if blocksAvailable == 0 || blockNum > blocksAvailable {
canonicalHash, err := rawdb.ReadCanonicalHash(tx, blockNum)
if err != nil {
return nil, err
}
var k [8 + 32]byte
binary.BigEndian.PutUint64(k[:], blockNum)
copy(k[8:], canonicalHash[:])
b, err := rawdb.ReadBodyForStorageByKey(tx, k[:])
if err != nil {
return nil, err
}
if b == nil {
return nil, nil
}
txn, err = rawdb.CanonicalTxnByID(tx, b.BaseTxId+1+uint64(i))
if err != nil {
return nil, err
}
return txn, nil
return rawdb.TxnByIdxInBlock(tx, canonicalHash, blockNum, txIdxInBlock)
}
view := r.sn.View()
@ -727,7 +711,7 @@ func (r *BlockReader) TxnByIdxInBlock(ctx context.Context, tx kv.Getter, blockNu
}
// if block has no transactions, or requested txNum out of non-system transactions length
if b.TxAmount == 2 || i == -1 || i >= int(b.TxAmount-2) {
if b.TxAmount == 2 || txIdxInBlock == -1 || txIdxInBlock >= int(b.TxAmount-2) {
return nil, nil
}
@ -736,7 +720,7 @@ func (r *BlockReader) TxnByIdxInBlock(ctx context.Context, tx kv.Getter, blockNu
return
}
// +1 because block has system-txn in the beginning of block
return r.txnByID(b.BaseTxId+1+uint64(i), txnSeg, nil)
return r.txnByID(b.BaseTxId+1+uint64(txIdxInBlock), txnSeg, nil)
}
// TxnLookup - find blockNumber and txnID by txnHash