update code
fix state processing read only db
This commit is contained in:
parent
9593c7bde0
commit
6b65a54d1c
@ -25,120 +25,19 @@ import (
|
|||||||
var errNotSupported = errors.New("this operation is not supported")
|
var errNotSupported = errors.New("this operation is not supported")
|
||||||
|
|
||||||
type database struct {
|
type database struct {
|
||||||
ethDB ethdb.Database
|
ethdb.Database
|
||||||
}
|
}
|
||||||
|
|
||||||
func newDatabase(db ethdb.Database) *database {
|
func newDatabase(db ethdb.Database) *database {
|
||||||
return &database{
|
return &database{
|
||||||
ethDB: db,
|
Database: db,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *database) NewIterator(prefix []byte, start []byte) ethdb.Iterator {
|
|
||||||
return d.ethDB.NewIterator(prefix, start)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (d *database) Has(key []byte) (bool, error) {
|
|
||||||
return d.ethDB.Has(key)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (d *database) Get(key []byte) ([]byte, error) {
|
|
||||||
return d.ethDB.Get(key)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (d *database) Put(key []byte, value []byte) error {
|
func (d *database) Put(key []byte, value []byte) error {
|
||||||
return nil
|
return errNotSupported
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *database) Delete(key []byte) error {
|
func (d *database) Delete(key []byte) error {
|
||||||
return nil
|
return errNotSupported
|
||||||
}
|
|
||||||
|
|
||||||
func (d *database) Stat(property string) (string, error) {
|
|
||||||
return d.ethDB.Stat(property)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (d *database) Compact(start []byte, limit []byte) error {
|
|
||||||
return d.ethDB.Compact(start, limit)
|
|
||||||
}
|
|
||||||
|
|
||||||
// HasAncient returns an error as we don't have a backing chain freezer.
|
|
||||||
func (d *database) HasAncient(kind string, number uint64) (bool, error) {
|
|
||||||
return d.ethDB.HasAncient(kind, number)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Ancient returns an error as we don't have a backing chain freezer.
|
|
||||||
func (d *database) Ancient(kind string, number uint64) ([]byte, error) {
|
|
||||||
return d.ethDB.Ancient(kind, number)
|
|
||||||
}
|
|
||||||
|
|
||||||
// AncientRange returns an error as we don't have a backing chain freezer.
|
|
||||||
func (d *database) AncientRange(kind string, start, max, maxByteSize uint64) ([][]byte, error) {
|
|
||||||
return d.ethDB.AncientRange(kind, start, max, maxByteSize)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Ancients returns an error as we don't have a backing chain freezer.
|
|
||||||
func (d *database) Ancients() (uint64, error) {
|
|
||||||
return d.ethDB.Ancients()
|
|
||||||
}
|
|
||||||
|
|
||||||
// AncientSize returns an error as we don't have a backing chain freezer.
|
|
||||||
func (d *database) AncientSize(kind string) (uint64, error) {
|
|
||||||
return d.ethDB.AncientSize(kind)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Tail returns the number of first stored item in the freezer.
|
|
||||||
func (d *database) Tail() (uint64, error) {
|
|
||||||
return d.Tail()
|
|
||||||
}
|
|
||||||
|
|
||||||
// ModifyAncients is not supported.
|
|
||||||
func (d *database) ModifyAncients(fn func(ethdb.AncientWriteOp) error) (int64, error) {
|
|
||||||
return 0, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// TruncateHead discards all but the first n ancient data from the ancient store.
|
|
||||||
func (d *database) TruncateHead(n uint64) error {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// TruncateTail discards the first n ancient data from the ancient store.
|
|
||||||
func (d *database) TruncateTail(n uint64) error {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (d *database) Sync() error {
|
|
||||||
return d.ethDB.Sync()
|
|
||||||
}
|
|
||||||
|
|
||||||
// MigrateTable processes and migrates entries of a given table to a new format.
|
|
||||||
func (d *database) MigrateTable(string, func([]byte) ([]byte, error)) error {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (d *database) NewBatch() ethdb.Batch {
|
|
||||||
return d.ethDB.NewBatch()
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewBatchWithSize creates a write-only database batch with pre-allocated buffer.
|
|
||||||
func (d *database) NewBatchWithSize(size int) ethdb.Batch {
|
|
||||||
return d.ethDB.NewBatchWithSize(size)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (d *database) ReadAncients(fn func(ethdb.AncientReaderOp) error) (err error) {
|
|
||||||
return d.ethDB.ReadAncients(fn)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (d *database) Close() error {
|
|
||||||
return d.ethDB.Close()
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewSnapshot creates a database snapshot based on the current state.
|
|
||||||
func (d *database) NewSnapshot() (ethdb.Snapshot, error) {
|
|
||||||
return d.NewSnapshot()
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewSnapshot creates a database snapshot based on the current state.
|
|
||||||
func (d *database) AncientDatadir() (string, error) {
|
|
||||||
return "", errNotSupported
|
|
||||||
}
|
}
|
||||||
|
@ -25,7 +25,7 @@ import (
|
|||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/cerc-io/plugeth-statediff"
|
statediff "github.com/cerc-io/plugeth-statediff"
|
||||||
"github.com/cerc-io/plugeth-statediff/indexer/database/sql/postgres"
|
"github.com/cerc-io/plugeth-statediff/indexer/database/sql/postgres"
|
||||||
"github.com/ethereum/go-ethereum/common"
|
"github.com/ethereum/go-ethereum/common"
|
||||||
"github.com/ethereum/go-ethereum/consensus"
|
"github.com/ethereum/go-ethereum/consensus"
|
||||||
@ -36,6 +36,7 @@ import (
|
|||||||
"github.com/ethereum/go-ethereum/core/vm"
|
"github.com/ethereum/go-ethereum/core/vm"
|
||||||
"github.com/ethereum/go-ethereum/params"
|
"github.com/ethereum/go-ethereum/params"
|
||||||
"github.com/ethereum/go-ethereum/rpc"
|
"github.com/ethereum/go-ethereum/rpc"
|
||||||
|
"github.com/holiman/uint256"
|
||||||
"github.com/jmoiron/sqlx"
|
"github.com/jmoiron/sqlx"
|
||||||
log "github.com/sirupsen/logrus"
|
log "github.com/sirupsen/logrus"
|
||||||
|
|
||||||
@ -246,13 +247,13 @@ func ethBackend(db *sqlx.DB, c *ipldeth.Config) (*ipldeth.Backend, error) {
|
|||||||
ExpiryDuration: time.Minute * time.Duration(gcc.StateDB.CacheExpiryInMins),
|
ExpiryDuration: time.Minute * time.Duration(gcc.StateDB.CacheExpiryInMins),
|
||||||
})
|
})
|
||||||
// Read only wrapper around ipfs-ethdb eth.Database implementation
|
// Read only wrapper around ipfs-ethdb eth.Database implementation
|
||||||
customEthDB := newDatabase(ethDB)
|
ethDB = newDatabase(ethDB)
|
||||||
|
|
||||||
return &ipldeth.Backend{
|
return &ipldeth.Backend{
|
||||||
DB: db,
|
DB: db,
|
||||||
Retriever: r,
|
Retriever: r,
|
||||||
EthDB: customEthDB,
|
EthDB: ethDB,
|
||||||
IpldTrieStateDatabase: ipldstate.NewDatabase(customEthDB),
|
IpldTrieStateDatabase: ipldstate.NewDatabase(ethDB),
|
||||||
Config: c,
|
Config: c,
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
@ -294,10 +295,13 @@ func (s *Service) writeStateDiffAt(height uint64) error {
|
|||||||
|
|
||||||
// applyTransaction attempts to apply block transactions to the given state database
|
// applyTransaction attempts to apply block transactions to the given state database
|
||||||
// and uses the input parameters for its environment. It returns the stateDB of parent with applied txs.
|
// and uses the input parameters for its environment. It returns the stateDB of parent with applied txs.
|
||||||
|
//
|
||||||
|
// Note: this skips the DAO hard fork refund
|
||||||
func applyTransactions(block *types.Block, backend *ipldeth.Backend) (*ipldstate.StateDB, error) {
|
func applyTransactions(block *types.Block, backend *ipldeth.Backend) (*ipldstate.StateDB, error) {
|
||||||
if block.NumberU64() == 0 {
|
if block.NumberU64() == 0 {
|
||||||
return nil, errors.New("no transaction in genesis")
|
return nil, errors.New("no transaction in genesis")
|
||||||
}
|
}
|
||||||
|
config := backend.Config.ChainConfig
|
||||||
|
|
||||||
// Create the parent state database
|
// Create the parent state database
|
||||||
parentHash := block.ParentHash()
|
parentHash := block.ParentHash()
|
||||||
@ -310,10 +314,13 @@ func applyTransactions(block *types.Block, backend *ipldeth.Backend) (*ipldstate
|
|||||||
var gp core.GasPool
|
var gp core.GasPool
|
||||||
gp.AddGas(block.GasLimit())
|
gp.AddGas(block.GasLimit())
|
||||||
|
|
||||||
signer := types.MakeSigner(backend.Config.ChainConfig, block.Number())
|
|
||||||
blockContext := core.NewEVMBlockContext(block.Header(), backend, getAuthor(backend, block.Header()))
|
blockContext := core.NewEVMBlockContext(block.Header(), backend, getAuthor(backend, block.Header()))
|
||||||
evm := vm.NewEVM(blockContext, vm.TxContext{}, statedb, backend.Config.ChainConfig, vm.Config{})
|
evm := vm.NewEVM(blockContext, vm.TxContext{}, statedb, config, vm.Config{})
|
||||||
rules := backend.Config.ChainConfig.Rules(block.Number(), true, block.Time())
|
signer := types.MakeSigner(config, block.Number(), block.Time())
|
||||||
|
|
||||||
|
if beaconRoot := block.BeaconRoot(); beaconRoot != nil {
|
||||||
|
ProcessBeaconBlockRoot(*beaconRoot, evm, statedb)
|
||||||
|
}
|
||||||
|
|
||||||
// Iterate over and process the individual transactions
|
// Iterate over and process the individual transactions
|
||||||
for i, tx := range block.Transactions() {
|
for i, tx := range block.Transactions() {
|
||||||
@ -322,7 +329,6 @@ func applyTransactions(block *types.Block, backend *ipldeth.Backend) (*ipldstate
|
|||||||
return nil, fmt.Errorf("error converting transaction to message: %w", err)
|
return nil, fmt.Errorf("error converting transaction to message: %w", err)
|
||||||
}
|
}
|
||||||
statedb.SetTxContext(tx.Hash(), i)
|
statedb.SetTxContext(tx.Hash(), i)
|
||||||
statedb.Prepare(rules, msg.From, block.Coinbase(), msg.To, nil, nil)
|
|
||||||
|
|
||||||
// Create a new context to be used in the EVM environment.
|
// Create a new context to be used in the EVM environment.
|
||||||
evm.Reset(core.NewEVMTxContext(msg), statedb)
|
evm.Reset(core.NewEVMTxContext(msg), statedb)
|
||||||
@ -330,10 +336,16 @@ func applyTransactions(block *types.Block, backend *ipldeth.Backend) (*ipldstate
|
|||||||
if _, err := core.ApplyMessage(evm, msg, &gp); err != nil {
|
if _, err := core.ApplyMessage(evm, msg, &gp); err != nil {
|
||||||
return nil, fmt.Errorf("transaction %#x failed: %w", tx.Hash(), err)
|
return nil, fmt.Errorf("transaction %#x failed: %w", tx.Hash(), err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if config.IsByzantium(block.Number()) {
|
||||||
|
statedb.Finalise(true)
|
||||||
|
} else {
|
||||||
|
statedb.IntermediateRoot(config.IsEIP158(block.Number())).Bytes()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if backend.Config.ChainConfig.Ethash != nil {
|
if config.Ethash != nil {
|
||||||
accumulateRewards(backend.Config.ChainConfig, statedb, block.Header(), block.Uncles())
|
accumulateRewards(config, statedb, block.Header(), block.Uncles())
|
||||||
}
|
}
|
||||||
|
|
||||||
return statedb, nil
|
return statedb, nil
|
||||||
@ -354,20 +366,40 @@ func accumulateRewards(config *params.ChainConfig, state *ipldstate.StateDB, hea
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Accumulate the rewards for the miner and any included uncles
|
// Accumulate the rewards for the miner and any included uncles
|
||||||
reward := new(big.Int).Set(blockReward)
|
reward := new(big.Int).Set(blockReward.ToBig())
|
||||||
r := new(big.Int)
|
r := new(big.Int)
|
||||||
for _, uncle := range uncles {
|
for _, uncle := range uncles {
|
||||||
r.Add(uncle.Number, big8)
|
r.Add(uncle.Number, big8)
|
||||||
r.Sub(r, header.Number)
|
r.Sub(r, header.Number)
|
||||||
r.Mul(r, blockReward)
|
r.Mul(r, blockReward.ToBig())
|
||||||
r.Div(r, big8)
|
r.Div(r, big8)
|
||||||
state.AddBalance(uncle.Coinbase, r)
|
state.AddBalance(uncle.Coinbase, uint256.MustFromBig(r))
|
||||||
|
|
||||||
r.Div(blockReward, big32)
|
r.Div(blockReward.ToBig(), big32)
|
||||||
reward.Add(reward, r)
|
reward.Add(reward, r)
|
||||||
}
|
}
|
||||||
|
|
||||||
state.AddBalance(header.Coinbase, reward)
|
state.AddBalance(header.Coinbase, uint256.MustFromBig(reward))
|
||||||
|
}
|
||||||
|
|
||||||
|
// ProcessBeaconBlockRoot applies the EIP-4788 system call to the beacon block root
|
||||||
|
// contract. This method is exported to be used in tests.
|
||||||
|
func ProcessBeaconBlockRoot(beaconRoot common.Hash, vmenv *vm.EVM, statedb *ipldstate.StateDB) {
|
||||||
|
// If EIP-4788 is enabled, we need to invoke the beaconroot storage contract with
|
||||||
|
// the new root
|
||||||
|
msg := &core.Message{
|
||||||
|
From: params.SystemAddress,
|
||||||
|
GasLimit: 30_000_000,
|
||||||
|
GasPrice: common.Big0,
|
||||||
|
GasFeeCap: common.Big0,
|
||||||
|
GasTipCap: common.Big0,
|
||||||
|
To: ¶ms.BeaconRootsStorageAddress,
|
||||||
|
Data: beaconRoot[:],
|
||||||
|
}
|
||||||
|
vmenv.Reset(core.NewEVMTxContext(msg), statedb)
|
||||||
|
statedb.AddAddressToAccessList(params.BeaconRootsStorageAddress)
|
||||||
|
_, _, _ = vmenv.Call(vm.AccountRef(msg.From), *msg.To, msg.Data, 30_000_000, common.U2560)
|
||||||
|
statedb.Finalise(true)
|
||||||
}
|
}
|
||||||
|
|
||||||
func setChainConfig(ghash common.Hash) *params.ChainConfig {
|
func setChainConfig(ghash common.Hash) *params.ChainConfig {
|
||||||
@ -376,8 +408,6 @@ func setChainConfig(ghash common.Hash) *params.ChainConfig {
|
|||||||
return params.MainnetChainConfig
|
return params.MainnetChainConfig
|
||||||
case ghash == params.SepoliaGenesisHash:
|
case ghash == params.SepoliaGenesisHash:
|
||||||
return params.SepoliaChainConfig
|
return params.SepoliaChainConfig
|
||||||
case ghash == params.RinkebyGenesisHash:
|
|
||||||
return params.RinkebyChainConfig
|
|
||||||
case ghash == params.GoerliGenesisHash:
|
case ghash == params.GoerliGenesisHash:
|
||||||
return params.GoerliChainConfig
|
return params.GoerliChainConfig
|
||||||
default:
|
default:
|
||||||
|
Loading…
Reference in New Issue
Block a user