evm: benchmark state DB (#514)
* evm: benchmark state DB * add more bech funcs * rm func from interface
This commit is contained in:
parent
9a8827e790
commit
87c4ea2dc2
@ -26,7 +26,6 @@ type EVMKeeper interface {
|
|||||||
GetParams(ctx sdk.Context) evmtypes.Params
|
GetParams(ctx sdk.Context) evmtypes.Params
|
||||||
WithContext(ctx sdk.Context)
|
WithContext(ctx sdk.Context)
|
||||||
ResetRefundTransient(ctx sdk.Context)
|
ResetRefundTransient(ctx sdk.Context)
|
||||||
GetCoinbaseAddress() (common.Address, error)
|
|
||||||
NewEVM(msg core.Message, config *params.ChainConfig, params evmtypes.Params, coinbase common.Address, tracer vm.Tracer) *vm.EVM
|
NewEVM(msg core.Message, config *params.ChainConfig, params evmtypes.Params, coinbase common.Address, tracer vm.Tracer) *vm.EVM
|
||||||
GetCodeHash(addr common.Address) common.Hash
|
GetCodeHash(addr common.Address) common.Hash
|
||||||
}
|
}
|
||||||
|
@ -330,7 +330,7 @@ func (k Keeper) EthCall(c context.Context, req *types.EthCallRequest) (*types.Ms
|
|||||||
params := k.GetParams(ctx)
|
params := k.GetParams(ctx)
|
||||||
ethCfg := params.ChainConfig.EthereumConfig(k.eip155ChainID)
|
ethCfg := params.ChainConfig.EthereumConfig(k.eip155ChainID)
|
||||||
|
|
||||||
coinbase, err := k.GetCoinbaseAddress()
|
coinbase, err := k.GetCoinbaseAddress(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, status.Error(codes.Internal, err.Error())
|
return nil, status.Error(codes.Internal, err.Error())
|
||||||
}
|
}
|
||||||
@ -394,7 +394,7 @@ func (k Keeper) EstimateGas(c context.Context, req *types.EthCallRequest) (*type
|
|||||||
params := k.GetParams(ctx)
|
params := k.GetParams(ctx)
|
||||||
ethCfg := params.ChainConfig.EthereumConfig(k.eip155ChainID)
|
ethCfg := params.ChainConfig.EthereumConfig(k.eip155ChainID)
|
||||||
|
|
||||||
coinbase, err := k.GetCoinbaseAddress()
|
coinbase, err := k.GetCoinbaseAddress(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, status.Error(codes.Internal, err.Error())
|
return nil, status.Error(codes.Internal, err.Error())
|
||||||
}
|
}
|
||||||
|
@ -69,39 +69,40 @@ func (k Keeper) VMConfig(msg core.Message, params types.Params, tracer vm.Tracer
|
|||||||
func (k Keeper) GetHashFn() vm.GetHashFunc {
|
func (k Keeper) GetHashFn() vm.GetHashFunc {
|
||||||
return func(height uint64) common.Hash {
|
return func(height uint64) common.Hash {
|
||||||
h := int64(height)
|
h := int64(height)
|
||||||
|
ctx := k.Ctx()
|
||||||
switch {
|
switch {
|
||||||
case k.Ctx().BlockHeight() == h:
|
case ctx.BlockHeight() == h:
|
||||||
// Case 1: The requested height matches the one from the context so we can retrieve the header
|
// Case 1: The requested height matches the one from the context so we can retrieve the header
|
||||||
// hash directly from the context.
|
// hash directly from the context.
|
||||||
// Note: The headerHash is only set at begin block, it will be nil in case of a query context
|
// Note: The headerHash is only set at begin block, it will be nil in case of a query context
|
||||||
headerHash := k.Ctx().HeaderHash()
|
headerHash := ctx.HeaderHash()
|
||||||
if len(headerHash) != 0 {
|
if len(headerHash) != 0 {
|
||||||
return common.BytesToHash(headerHash)
|
return common.BytesToHash(headerHash)
|
||||||
}
|
}
|
||||||
|
|
||||||
// only recompute the hash if not set (eg: checkTxState)
|
// only recompute the hash if not set (eg: checkTxState)
|
||||||
contextBlockHeader := k.Ctx().BlockHeader()
|
contextBlockHeader := ctx.BlockHeader()
|
||||||
header, err := tmtypes.HeaderFromProto(&contextBlockHeader)
|
header, err := tmtypes.HeaderFromProto(&contextBlockHeader)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
k.Logger(k.Ctx()).Error("failed to cast tendermint header from proto", "error", err)
|
k.Logger(ctx).Error("failed to cast tendermint header from proto", "error", err)
|
||||||
return common.Hash{}
|
return common.Hash{}
|
||||||
}
|
}
|
||||||
|
|
||||||
headerHash = header.Hash()
|
headerHash = header.Hash()
|
||||||
return common.BytesToHash(headerHash)
|
return common.BytesToHash(headerHash)
|
||||||
|
|
||||||
case k.Ctx().BlockHeight() > h:
|
case ctx.BlockHeight() > h:
|
||||||
// Case 2: if the chain is not the current height we need to retrieve the hash from the store for the
|
// Case 2: if the chain is not the current height we need to retrieve the hash from the store for the
|
||||||
// current chain epoch. This only applies if the current height is greater than the requested height.
|
// current chain epoch. This only applies if the current height is greater than the requested height.
|
||||||
histInfo, found := k.stakingKeeper.GetHistoricalInfo(k.Ctx(), h)
|
histInfo, found := k.stakingKeeper.GetHistoricalInfo(ctx, h)
|
||||||
if !found {
|
if !found {
|
||||||
k.Logger(k.Ctx()).Debug("historical info not found", "height", h)
|
k.Logger(ctx).Debug("historical info not found", "height", h)
|
||||||
return common.Hash{}
|
return common.Hash{}
|
||||||
}
|
}
|
||||||
|
|
||||||
header, err := tmtypes.HeaderFromProto(&histInfo.Header)
|
header, err := tmtypes.HeaderFromProto(&histInfo.Header)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
k.Logger(k.Ctx()).Error("failed to cast tendermint header from proto", "error", err)
|
k.Logger(ctx).Error("failed to cast tendermint header from proto", "error", err)
|
||||||
return common.Hash{}
|
return common.Hash{}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -133,7 +134,8 @@ func (k Keeper) GetHashFn() vm.GetHashFunc {
|
|||||||
func (k *Keeper) ApplyTransaction(tx *ethtypes.Transaction) (*types.MsgEthereumTxResponse, error) {
|
func (k *Keeper) ApplyTransaction(tx *ethtypes.Transaction) (*types.MsgEthereumTxResponse, error) {
|
||||||
defer telemetry.ModuleMeasureSince(types.ModuleName, time.Now(), types.MetricKeyTransitionDB)
|
defer telemetry.ModuleMeasureSince(types.ModuleName, time.Now(), types.MetricKeyTransitionDB)
|
||||||
|
|
||||||
params := k.GetParams(k.Ctx())
|
ctx := k.Ctx()
|
||||||
|
params := k.GetParams(ctx)
|
||||||
|
|
||||||
// return error if contract creation or call are disabled through governance
|
// return error if contract creation or call are disabled through governance
|
||||||
if !params.EnableCreate && tx.To() == nil {
|
if !params.EnableCreate && tx.To() == nil {
|
||||||
@ -145,7 +147,7 @@ func (k *Keeper) ApplyTransaction(tx *ethtypes.Transaction) (*types.MsgEthereumT
|
|||||||
ethCfg := params.ChainConfig.EthereumConfig(k.eip155ChainID)
|
ethCfg := params.ChainConfig.EthereumConfig(k.eip155ChainID)
|
||||||
|
|
||||||
// get the latest signer according to the chain rules from the config
|
// get the latest signer according to the chain rules from the config
|
||||||
signer := ethtypes.MakeSigner(ethCfg, big.NewInt(k.Ctx().BlockHeight()))
|
signer := ethtypes.MakeSigner(ethCfg, big.NewInt(ctx.BlockHeight()))
|
||||||
|
|
||||||
msg, err := tx.AsMessage(signer)
|
msg, err := tx.AsMessage(signer)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -153,13 +155,13 @@ func (k *Keeper) ApplyTransaction(tx *ethtypes.Transaction) (*types.MsgEthereumT
|
|||||||
}
|
}
|
||||||
|
|
||||||
// get the coinbase address from the block proposer
|
// get the coinbase address from the block proposer
|
||||||
coinbase, err := k.GetCoinbaseAddress()
|
coinbase, err := k.GetCoinbaseAddress(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, stacktrace.Propagate(err, "failed to obtain coinbase address")
|
return nil, stacktrace.Propagate(err, "failed to obtain coinbase address")
|
||||||
}
|
}
|
||||||
|
|
||||||
// create an ethereum EVM instance and run the message
|
// create an ethereum EVM instance and run the message
|
||||||
tracer := types.NewTracer(k.tracer, msg, ethCfg, k.Ctx().BlockHeight(), k.debug)
|
tracer := types.NewTracer(k.tracer, msg, ethCfg, ctx.BlockHeight(), k.debug)
|
||||||
evm := k.NewEVM(msg, ethCfg, params, coinbase, tracer)
|
evm := k.NewEVM(msg, ethCfg, params, coinbase, tracer)
|
||||||
|
|
||||||
txHash := tx.Hash()
|
txHash := tx.Hash()
|
||||||
@ -368,14 +370,15 @@ func (k *Keeper) RefundGas(msg core.Message, leftoverGas, refundQuotient uint64)
|
|||||||
// 'gasUsed'
|
// 'gasUsed'
|
||||||
func (k *Keeper) resetGasMeterAndConsumeGas(gasUsed uint64) {
|
func (k *Keeper) resetGasMeterAndConsumeGas(gasUsed uint64) {
|
||||||
// reset the gas count
|
// reset the gas count
|
||||||
k.Ctx().GasMeter().RefundGas(k.Ctx().GasMeter().GasConsumed(), "reset the gas count")
|
ctx := k.Ctx()
|
||||||
k.Ctx().GasMeter().ConsumeGas(gasUsed, "apply evm transaction")
|
ctx.GasMeter().RefundGas(ctx.GasMeter().GasConsumed(), "reset the gas count")
|
||||||
|
ctx.GasMeter().ConsumeGas(gasUsed, "apply evm transaction")
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetCoinbaseAddress returns the block proposer's validator operator address.
|
// GetCoinbaseAddress returns the block proposer's validator operator address.
|
||||||
func (k Keeper) GetCoinbaseAddress() (common.Address, error) {
|
func (k Keeper) GetCoinbaseAddress(ctx sdk.Context) (common.Address, error) {
|
||||||
consAddr := sdk.ConsAddress(k.Ctx().BlockHeader().ProposerAddress)
|
consAddr := sdk.ConsAddress(ctx.BlockHeader().ProposerAddress)
|
||||||
validator, found := k.stakingKeeper.GetValidatorByConsAddr(k.Ctx(), consAddr)
|
validator, found := k.stakingKeeper.GetValidatorByConsAddr(ctx, consAddr)
|
||||||
if !found {
|
if !found {
|
||||||
return common.Address{}, stacktrace.Propagate(
|
return common.Address{}, stacktrace.Propagate(
|
||||||
sdkerrors.Wrap(stakingtypes.ErrNoValidatorFound, consAddr.String()),
|
sdkerrors.Wrap(stakingtypes.ErrNoValidatorFound, consAddr.String()),
|
||||||
|
@ -65,7 +65,7 @@ func (suite *KeeperTestSuite) TestGetCoinbaseAddress() {
|
|||||||
|
|
||||||
tc.malleate()
|
tc.malleate()
|
||||||
|
|
||||||
coinbase, err := suite.app.EvmKeeper.GetCoinbaseAddress()
|
coinbase, err := suite.app.EvmKeeper.GetCoinbaseAddress(suite.ctx)
|
||||||
if tc.expPass {
|
if tc.expPass {
|
||||||
suite.Require().NoError(err)
|
suite.Require().NoError(err)
|
||||||
suite.Require().Equal(valOpAddr, coinbase)
|
suite.Require().Equal(valOpAddr, coinbase)
|
||||||
|
@ -29,8 +29,8 @@ var _ vm.StateDB = &Keeper{}
|
|||||||
// address.
|
// address.
|
||||||
func (k *Keeper) CreateAccount(addr common.Address) {
|
func (k *Keeper) CreateAccount(addr common.Address) {
|
||||||
cosmosAddr := sdk.AccAddress(addr.Bytes())
|
cosmosAddr := sdk.AccAddress(addr.Bytes())
|
||||||
|
ctx := k.Ctx()
|
||||||
account := k.accountKeeper.GetAccount(k.Ctx(), cosmosAddr)
|
account := k.accountKeeper.GetAccount(ctx, cosmosAddr)
|
||||||
log := ""
|
log := ""
|
||||||
if account == nil {
|
if account == nil {
|
||||||
log = "account created"
|
log = "account created"
|
||||||
@ -39,10 +39,10 @@ func (k *Keeper) CreateAccount(addr common.Address) {
|
|||||||
k.ResetAccount(addr)
|
k.ResetAccount(addr)
|
||||||
}
|
}
|
||||||
|
|
||||||
account = k.accountKeeper.NewAccountWithAddress(k.Ctx(), cosmosAddr)
|
account = k.accountKeeper.NewAccountWithAddress(ctx, cosmosAddr)
|
||||||
k.accountKeeper.SetAccount(k.Ctx(), account)
|
k.accountKeeper.SetAccount(ctx, account)
|
||||||
|
|
||||||
k.Logger(k.Ctx()).Debug(
|
k.Logger(ctx).Debug(
|
||||||
log,
|
log,
|
||||||
"ethereum-address", addr.Hex(),
|
"ethereum-address", addr.Hex(),
|
||||||
"cosmos-address", cosmosAddr.String(),
|
"cosmos-address", cosmosAddr.String(),
|
||||||
@ -57,8 +57,10 @@ func (k *Keeper) CreateAccount(addr common.Address) {
|
|||||||
// coins and transferring them to the address. The coin denomination is obtained
|
// coins and transferring them to the address. The coin denomination is obtained
|
||||||
// from the module parameters.
|
// from the module parameters.
|
||||||
func (k *Keeper) AddBalance(addr common.Address, amount *big.Int) {
|
func (k *Keeper) AddBalance(addr common.Address, amount *big.Int) {
|
||||||
|
ctx := k.Ctx()
|
||||||
|
|
||||||
if amount.Sign() != 1 {
|
if amount.Sign() != 1 {
|
||||||
k.Logger(k.Ctx()).Debug(
|
k.Logger(ctx).Debug(
|
||||||
"ignored non-positive amount addition",
|
"ignored non-positive amount addition",
|
||||||
"ethereum-address", addr.Hex(),
|
"ethereum-address", addr.Hex(),
|
||||||
"amount", amount.Int64(),
|
"amount", amount.Int64(),
|
||||||
@ -67,12 +69,18 @@ func (k *Keeper) AddBalance(addr common.Address, amount *big.Int) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
cosmosAddr := sdk.AccAddress(addr.Bytes())
|
cosmosAddr := sdk.AccAddress(addr.Bytes())
|
||||||
|
params := k.GetParams(ctx)
|
||||||
|
|
||||||
params := k.GetParams(k.Ctx())
|
// Coin denom and amount already validated
|
||||||
coins := sdk.Coins{sdk.NewCoin(params.EvmDenom, sdk.NewIntFromBigInt(amount))}
|
coins := sdk.Coins{
|
||||||
|
{
|
||||||
|
Denom: params.EvmDenom,
|
||||||
|
Amount: sdk.NewIntFromBigInt(amount),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
if err := k.bankKeeper.MintCoins(k.Ctx(), types.ModuleName, coins); err != nil {
|
if err := k.bankKeeper.MintCoins(ctx, types.ModuleName, coins); err != nil {
|
||||||
k.Logger(k.Ctx()).Error(
|
k.Logger(ctx).Error(
|
||||||
"failed to mint coins when adding balance",
|
"failed to mint coins when adding balance",
|
||||||
"ethereum-address", addr.Hex(),
|
"ethereum-address", addr.Hex(),
|
||||||
"cosmos-address", cosmosAddr.String(),
|
"cosmos-address", cosmosAddr.String(),
|
||||||
@ -81,8 +89,8 @@ func (k *Keeper) AddBalance(addr common.Address, amount *big.Int) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := k.bankKeeper.SendCoinsFromModuleToAccount(k.Ctx(), types.ModuleName, cosmosAddr, coins); err != nil {
|
if err := k.bankKeeper.SendCoinsFromModuleToAccount(ctx, types.ModuleName, cosmosAddr, coins); err != nil {
|
||||||
k.Logger(k.Ctx()).Error(
|
k.Logger(ctx).Error(
|
||||||
"failed to send from module to account when adding balance",
|
"failed to send from module to account when adding balance",
|
||||||
"ethereum-address", addr.Hex(),
|
"ethereum-address", addr.Hex(),
|
||||||
"cosmos-address", cosmosAddr.String(),
|
"cosmos-address", cosmosAddr.String(),
|
||||||
@ -91,7 +99,7 @@ func (k *Keeper) AddBalance(addr common.Address, amount *big.Int) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
k.Logger(k.Ctx()).Debug(
|
k.Logger(ctx).Debug(
|
||||||
"balance addition",
|
"balance addition",
|
||||||
"ethereum-address", addr.Hex(),
|
"ethereum-address", addr.Hex(),
|
||||||
"cosmos-address", cosmosAddr.String(),
|
"cosmos-address", cosmosAddr.String(),
|
||||||
@ -103,8 +111,10 @@ func (k *Keeper) AddBalance(addr common.Address, amount *big.Int) {
|
|||||||
// from the module parameters. This function performs a no-op if the amount is negative
|
// from the module parameters. This function performs a no-op if the amount is negative
|
||||||
// or the user doesn't have enough funds for the transfer.
|
// or the user doesn't have enough funds for the transfer.
|
||||||
func (k *Keeper) SubBalance(addr common.Address, amount *big.Int) {
|
func (k *Keeper) SubBalance(addr common.Address, amount *big.Int) {
|
||||||
|
ctx := k.Ctx()
|
||||||
|
|
||||||
if amount.Sign() != 1 {
|
if amount.Sign() != 1 {
|
||||||
k.Logger(k.Ctx()).Debug(
|
k.Logger(ctx).Debug(
|
||||||
"ignored non-positive amount addition",
|
"ignored non-positive amount addition",
|
||||||
"ethereum-address", addr.Hex(),
|
"ethereum-address", addr.Hex(),
|
||||||
"amount", amount.Int64(),
|
"amount", amount.Int64(),
|
||||||
@ -114,11 +124,18 @@ func (k *Keeper) SubBalance(addr common.Address, amount *big.Int) {
|
|||||||
|
|
||||||
cosmosAddr := sdk.AccAddress(addr.Bytes())
|
cosmosAddr := sdk.AccAddress(addr.Bytes())
|
||||||
|
|
||||||
params := k.GetParams(k.Ctx())
|
params := k.GetParams(ctx)
|
||||||
coins := sdk.Coins{sdk.NewCoin(params.EvmDenom, sdk.NewIntFromBigInt(amount))}
|
|
||||||
|
|
||||||
if err := k.bankKeeper.SendCoinsFromAccountToModule(k.Ctx(), cosmosAddr, types.ModuleName, coins); err != nil {
|
// Coin denom and amount already validated
|
||||||
k.Logger(k.Ctx()).Debug(
|
coins := sdk.Coins{
|
||||||
|
{
|
||||||
|
Denom: params.EvmDenom,
|
||||||
|
Amount: sdk.NewIntFromBigInt(amount),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := k.bankKeeper.SendCoinsFromAccountToModule(ctx, cosmosAddr, types.ModuleName, coins); err != nil {
|
||||||
|
k.Logger(ctx).Debug(
|
||||||
"failed to send from account to module when subtracting balance",
|
"failed to send from account to module when subtracting balance",
|
||||||
"ethereum-address", addr.Hex(),
|
"ethereum-address", addr.Hex(),
|
||||||
"cosmos-address", cosmosAddr.String(),
|
"cosmos-address", cosmosAddr.String(),
|
||||||
@ -128,8 +145,8 @@ func (k *Keeper) SubBalance(addr common.Address, amount *big.Int) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := k.bankKeeper.BurnCoins(k.Ctx(), types.ModuleName, coins); err != nil {
|
if err := k.bankKeeper.BurnCoins(ctx, types.ModuleName, coins); err != nil {
|
||||||
k.Logger(k.Ctx()).Error(
|
k.Logger(ctx).Error(
|
||||||
"failed to burn coins when subtracting balance",
|
"failed to burn coins when subtracting balance",
|
||||||
"ethereum-address", addr.Hex(),
|
"ethereum-address", addr.Hex(),
|
||||||
"cosmos-address", cosmosAddr.String(),
|
"cosmos-address", cosmosAddr.String(),
|
||||||
@ -138,7 +155,7 @@ func (k *Keeper) SubBalance(addr common.Address, amount *big.Int) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
k.Logger(k.Ctx()).Debug(
|
k.Logger(ctx).Debug(
|
||||||
"balance subtraction",
|
"balance subtraction",
|
||||||
"ethereum-address", addr.Hex(),
|
"ethereum-address", addr.Hex(),
|
||||||
"cosmos-address", cosmosAddr.String(),
|
"cosmos-address", cosmosAddr.String(),
|
||||||
@ -148,9 +165,11 @@ func (k *Keeper) SubBalance(addr common.Address, amount *big.Int) {
|
|||||||
// GetBalance returns the EVM denomination balance of the provided address. The
|
// GetBalance returns the EVM denomination balance of the provided address. The
|
||||||
// denomination is obtained from the module parameters.
|
// denomination is obtained from the module parameters.
|
||||||
func (k *Keeper) GetBalance(addr common.Address) *big.Int {
|
func (k *Keeper) GetBalance(addr common.Address) *big.Int {
|
||||||
|
ctx := k.Ctx()
|
||||||
|
|
||||||
cosmosAddr := sdk.AccAddress(addr.Bytes())
|
cosmosAddr := sdk.AccAddress(addr.Bytes())
|
||||||
params := k.GetParams(k.Ctx())
|
params := k.GetParams(ctx)
|
||||||
balance := k.bankKeeper.GetBalance(k.Ctx(), cosmosAddr, params.EvmDenom)
|
balance := k.bankKeeper.GetBalance(ctx, cosmosAddr, params.EvmDenom)
|
||||||
|
|
||||||
return balance.Amount.BigInt()
|
return balance.Amount.BigInt()
|
||||||
}
|
}
|
||||||
@ -162,10 +181,12 @@ func (k *Keeper) GetBalance(addr common.Address) *big.Int {
|
|||||||
// GetNonce retrieves the account with the given address and returns the tx
|
// GetNonce retrieves the account with the given address and returns the tx
|
||||||
// sequence (i.e nonce). The function performs a no-op if the account is not found.
|
// sequence (i.e nonce). The function performs a no-op if the account is not found.
|
||||||
func (k *Keeper) GetNonce(addr common.Address) uint64 {
|
func (k *Keeper) GetNonce(addr common.Address) uint64 {
|
||||||
|
ctx := k.Ctx()
|
||||||
|
|
||||||
cosmosAddr := sdk.AccAddress(addr.Bytes())
|
cosmosAddr := sdk.AccAddress(addr.Bytes())
|
||||||
nonce, err := k.accountKeeper.GetSequence(k.Ctx(), cosmosAddr)
|
nonce, err := k.accountKeeper.GetSequence(ctx, cosmosAddr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
k.Logger(k.Ctx()).Error(
|
k.Logger(ctx).Error(
|
||||||
"account not found",
|
"account not found",
|
||||||
"ethereum-address", addr.Hex(),
|
"ethereum-address", addr.Hex(),
|
||||||
"cosmos-address", cosmosAddr.String(),
|
"cosmos-address", cosmosAddr.String(),
|
||||||
@ -179,21 +200,23 @@ func (k *Keeper) GetNonce(addr common.Address) uint64 {
|
|||||||
// SetNonce sets the given nonce as the sequence of the address' account. If the
|
// SetNonce sets the given nonce as the sequence of the address' account. If the
|
||||||
// account doesn't exist, a new one will be created from the address.
|
// account doesn't exist, a new one will be created from the address.
|
||||||
func (k *Keeper) SetNonce(addr common.Address, nonce uint64) {
|
func (k *Keeper) SetNonce(addr common.Address, nonce uint64) {
|
||||||
|
ctx := k.Ctx()
|
||||||
|
|
||||||
cosmosAddr := sdk.AccAddress(addr.Bytes())
|
cosmosAddr := sdk.AccAddress(addr.Bytes())
|
||||||
account := k.accountKeeper.GetAccount(k.Ctx(), cosmosAddr)
|
account := k.accountKeeper.GetAccount(ctx, cosmosAddr)
|
||||||
if account == nil {
|
if account == nil {
|
||||||
k.Logger(k.Ctx()).Debug(
|
k.Logger(ctx).Debug(
|
||||||
"account not found",
|
"account not found",
|
||||||
"ethereum-address", addr.Hex(),
|
"ethereum-address", addr.Hex(),
|
||||||
"cosmos-address", cosmosAddr.String(),
|
"cosmos-address", cosmosAddr.String(),
|
||||||
)
|
)
|
||||||
|
|
||||||
// create address if it doesn't exist
|
// create address if it doesn't exist
|
||||||
account = k.accountKeeper.NewAccountWithAddress(k.Ctx(), cosmosAddr)
|
account = k.accountKeeper.NewAccountWithAddress(ctx, cosmosAddr)
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := account.SetSequence(nonce); err != nil {
|
if err := account.SetSequence(nonce); err != nil {
|
||||||
k.Logger(k.Ctx()).Error(
|
k.Logger(ctx).Error(
|
||||||
"failed to set nonce",
|
"failed to set nonce",
|
||||||
"ethereum-address", addr.Hex(),
|
"ethereum-address", addr.Hex(),
|
||||||
"cosmos-address", cosmosAddr.String(),
|
"cosmos-address", cosmosAddr.String(),
|
||||||
@ -204,9 +227,9 @@ func (k *Keeper) SetNonce(addr common.Address, nonce uint64) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
k.accountKeeper.SetAccount(k.Ctx(), account)
|
k.accountKeeper.SetAccount(ctx, account)
|
||||||
|
|
||||||
k.Logger(k.Ctx()).Debug(
|
k.Logger(ctx).Debug(
|
||||||
"nonce set",
|
"nonce set",
|
||||||
"ethereum-address", addr.Hex(),
|
"ethereum-address", addr.Hex(),
|
||||||
"cosmos-address", cosmosAddr.String(),
|
"cosmos-address", cosmosAddr.String(),
|
||||||
@ -221,8 +244,10 @@ func (k *Keeper) SetNonce(addr common.Address, nonce uint64) {
|
|||||||
// GetCodeHash fetches the account from the store and returns its code hash. If the account doesn't
|
// GetCodeHash fetches the account from the store and returns its code hash. If the account doesn't
|
||||||
// exist or is not an EthAccount type, GetCodeHash returns the empty code hash value.
|
// exist or is not an EthAccount type, GetCodeHash returns the empty code hash value.
|
||||||
func (k *Keeper) GetCodeHash(addr common.Address) common.Hash {
|
func (k *Keeper) GetCodeHash(addr common.Address) common.Hash {
|
||||||
|
ctx := k.Ctx()
|
||||||
cosmosAddr := sdk.AccAddress(addr.Bytes())
|
cosmosAddr := sdk.AccAddress(addr.Bytes())
|
||||||
account := k.accountKeeper.GetAccount(k.Ctx(), cosmosAddr)
|
|
||||||
|
account := k.accountKeeper.GetAccount(ctx, cosmosAddr)
|
||||||
if account == nil {
|
if account == nil {
|
||||||
return common.BytesToHash(types.EmptyCodeHash)
|
return common.BytesToHash(types.EmptyCodeHash)
|
||||||
}
|
}
|
||||||
@ -238,17 +263,18 @@ func (k *Keeper) GetCodeHash(addr common.Address) common.Hash {
|
|||||||
// GetCode returns the code byte array associated with the given address.
|
// GetCode returns the code byte array associated with the given address.
|
||||||
// If the code hash from the account is empty, this function returns nil.
|
// If the code hash from the account is empty, this function returns nil.
|
||||||
func (k *Keeper) GetCode(addr common.Address) []byte {
|
func (k *Keeper) GetCode(addr common.Address) []byte {
|
||||||
|
ctx := k.Ctx()
|
||||||
hash := k.GetCodeHash(addr)
|
hash := k.GetCodeHash(addr)
|
||||||
|
|
||||||
if bytes.Equal(hash.Bytes(), common.BytesToHash(types.EmptyCodeHash).Bytes()) {
|
if bytes.Equal(hash.Bytes(), common.BytesToHash(types.EmptyCodeHash).Bytes()) {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
store := prefix.NewStore(k.Ctx().KVStore(k.storeKey), types.KeyPrefixCode)
|
store := prefix.NewStore(ctx.KVStore(k.storeKey), types.KeyPrefixCode)
|
||||||
code := store.Get(hash.Bytes())
|
code := store.Get(hash.Bytes())
|
||||||
|
|
||||||
if len(code) == 0 {
|
if len(code) == 0 {
|
||||||
k.Logger(k.Ctx()).Debug(
|
k.Logger(ctx).Debug(
|
||||||
"code not found",
|
"code not found",
|
||||||
"ethereum-address", addr.Hex(),
|
"ethereum-address", addr.Hex(),
|
||||||
"code-hash", hash.Hex(),
|
"code-hash", hash.Hex(),
|
||||||
@ -261,21 +287,23 @@ func (k *Keeper) GetCode(addr common.Address) []byte {
|
|||||||
// SetCode stores the code byte array to the application KVStore and sets the
|
// SetCode stores the code byte array to the application KVStore and sets the
|
||||||
// code hash to the given account. The code is deleted from the store if it is empty.
|
// code hash to the given account. The code is deleted from the store if it is empty.
|
||||||
func (k *Keeper) SetCode(addr common.Address, code []byte) {
|
func (k *Keeper) SetCode(addr common.Address, code []byte) {
|
||||||
|
ctx := k.Ctx()
|
||||||
|
|
||||||
if bytes.Equal(code, types.EmptyCodeHash) {
|
if bytes.Equal(code, types.EmptyCodeHash) {
|
||||||
k.Logger(k.Ctx()).Debug("passed in EmptyCodeHash, but expected empty code")
|
k.Logger(ctx).Debug("passed in EmptyCodeHash, but expected empty code")
|
||||||
}
|
}
|
||||||
hash := crypto.Keccak256Hash(code)
|
hash := crypto.Keccak256Hash(code)
|
||||||
|
|
||||||
// update account code hash
|
// update account code hash
|
||||||
account := k.accountKeeper.GetAccount(k.Ctx(), addr.Bytes())
|
account := k.accountKeeper.GetAccount(ctx, addr.Bytes())
|
||||||
if account == nil {
|
if account == nil {
|
||||||
account = k.accountKeeper.NewAccountWithAddress(k.Ctx(), addr.Bytes())
|
account = k.accountKeeper.NewAccountWithAddress(ctx, addr.Bytes())
|
||||||
k.accountKeeper.SetAccount(k.Ctx(), account)
|
k.accountKeeper.SetAccount(ctx, account)
|
||||||
}
|
}
|
||||||
|
|
||||||
ethAccount, isEthAccount := account.(*ethermint.EthAccount)
|
ethAccount, isEthAccount := account.(*ethermint.EthAccount)
|
||||||
if !isEthAccount {
|
if !isEthAccount {
|
||||||
k.Logger(k.Ctx()).Error(
|
k.Logger(ctx).Error(
|
||||||
"invalid account type",
|
"invalid account type",
|
||||||
"ethereum-address", addr.Hex(),
|
"ethereum-address", addr.Hex(),
|
||||||
"code-hash", hash.Hex(),
|
"code-hash", hash.Hex(),
|
||||||
@ -284,9 +312,9 @@ func (k *Keeper) SetCode(addr common.Address, code []byte) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
ethAccount.CodeHash = hash.Hex()
|
ethAccount.CodeHash = hash.Hex()
|
||||||
k.accountKeeper.SetAccount(k.Ctx(), ethAccount)
|
k.accountKeeper.SetAccount(ctx, ethAccount)
|
||||||
|
|
||||||
store := prefix.NewStore(k.Ctx().KVStore(k.storeKey), types.KeyPrefixCode)
|
store := prefix.NewStore(ctx.KVStore(k.storeKey), types.KeyPrefixCode)
|
||||||
|
|
||||||
action := "updated"
|
action := "updated"
|
||||||
|
|
||||||
@ -298,7 +326,7 @@ func (k *Keeper) SetCode(addr common.Address, code []byte) {
|
|||||||
store.Set(hash.Bytes(), code)
|
store.Set(hash.Bytes(), code)
|
||||||
}
|
}
|
||||||
|
|
||||||
k.Logger(k.Ctx()).Debug(
|
k.Logger(ctx).Debug(
|
||||||
fmt.Sprintf("code %s", action),
|
fmt.Sprintf("code %s", action),
|
||||||
"ethereum-address", addr.Hex(),
|
"ethereum-address", addr.Hex(),
|
||||||
"code-hash", hash.Hex(),
|
"code-hash", hash.Hex(),
|
||||||
@ -323,17 +351,19 @@ func (k *Keeper) GetCodeSize(addr common.Address) int {
|
|||||||
|
|
||||||
// AddRefund adds the given amount of gas to the refund transient value.
|
// AddRefund adds the given amount of gas to the refund transient value.
|
||||||
func (k *Keeper) AddRefund(gas uint64) {
|
func (k *Keeper) AddRefund(gas uint64) {
|
||||||
|
ctx := k.Ctx()
|
||||||
refund := k.GetRefund()
|
refund := k.GetRefund()
|
||||||
|
|
||||||
refund += gas
|
refund += gas
|
||||||
|
|
||||||
store := k.Ctx().TransientStore(k.transientKey)
|
store := ctx.TransientStore(k.transientKey)
|
||||||
store.Set(types.KeyPrefixTransientRefund, sdk.Uint64ToBigEndian(refund))
|
store.Set(types.KeyPrefixTransientRefund, sdk.Uint64ToBigEndian(refund))
|
||||||
}
|
}
|
||||||
|
|
||||||
// SubRefund subtracts the given amount of gas from the transient refund value. This function
|
// SubRefund subtracts the given amount of gas from the transient refund value. This function
|
||||||
// will panic if gas amount is greater than the stored refund.
|
// will panic if gas amount is greater than the stored refund.
|
||||||
func (k *Keeper) SubRefund(gas uint64) {
|
func (k *Keeper) SubRefund(gas uint64) {
|
||||||
|
ctx := k.Ctx()
|
||||||
refund := k.GetRefund()
|
refund := k.GetRefund()
|
||||||
|
|
||||||
if gas > refund {
|
if gas > refund {
|
||||||
@ -343,14 +373,15 @@ func (k *Keeper) SubRefund(gas uint64) {
|
|||||||
|
|
||||||
refund -= gas
|
refund -= gas
|
||||||
|
|
||||||
store := k.Ctx().TransientStore(k.transientKey)
|
store := ctx.TransientStore(k.transientKey)
|
||||||
store.Set(types.KeyPrefixTransientRefund, sdk.Uint64ToBigEndian(refund))
|
store.Set(types.KeyPrefixTransientRefund, sdk.Uint64ToBigEndian(refund))
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetRefund returns the amount of gas available for return after the tx execution
|
// GetRefund returns the amount of gas available for return after the tx execution
|
||||||
// finalizes. This value is reset to 0 on every transaction.
|
// finalizes. This value is reset to 0 on every transaction.
|
||||||
func (k *Keeper) GetRefund() uint64 {
|
func (k *Keeper) GetRefund() uint64 {
|
||||||
store := k.Ctx().TransientStore(k.transientKey)
|
ctx := k.Ctx()
|
||||||
|
store := ctx.TransientStore(k.transientKey)
|
||||||
|
|
||||||
bz := store.Get(types.KeyPrefixTransientRefund)
|
bz := store.Get(types.KeyPrefixTransientRefund)
|
||||||
if len(bz) == 0 {
|
if len(bz) == 0 {
|
||||||
@ -385,13 +416,15 @@ func (k *Keeper) GetCommittedState(addr common.Address, hash common.Hash) common
|
|||||||
// GetState returns the committed state for the given key hash, as all changes are committed directly
|
// GetState returns the committed state for the given key hash, as all changes are committed directly
|
||||||
// to the KVStore.
|
// to the KVStore.
|
||||||
func (k *Keeper) GetState(addr common.Address, hash common.Hash) common.Hash {
|
func (k *Keeper) GetState(addr common.Address, hash common.Hash) common.Hash {
|
||||||
return doGetState(k.Ctx(), k.storeKey, addr, hash)
|
ctx := k.Ctx()
|
||||||
|
return doGetState(ctx, k.storeKey, addr, hash)
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetState sets the given hashes (key, value) to the KVStore. If the value hash is empty, this
|
// SetState sets the given hashes (key, value) to the KVStore. If the value hash is empty, this
|
||||||
// function deletes the key from the store.
|
// function deletes the key from the store.
|
||||||
func (k *Keeper) SetState(addr common.Address, key, value common.Hash) {
|
func (k *Keeper) SetState(addr common.Address, key, value common.Hash) {
|
||||||
store := prefix.NewStore(k.Ctx().KVStore(k.storeKey), types.AddressStoragePrefix(addr))
|
ctx := k.Ctx()
|
||||||
|
store := prefix.NewStore(ctx.KVStore(k.storeKey), types.AddressStoragePrefix(addr))
|
||||||
key = types.KeyAddressStorage(addr, key)
|
key = types.KeyAddressStorage(addr, key)
|
||||||
|
|
||||||
action := "updated"
|
action := "updated"
|
||||||
@ -402,7 +435,7 @@ func (k *Keeper) SetState(addr common.Address, key, value common.Hash) {
|
|||||||
store.Set(key.Bytes(), value.Bytes())
|
store.Set(key.Bytes(), value.Bytes())
|
||||||
}
|
}
|
||||||
|
|
||||||
k.Logger(k.Ctx()).Debug(
|
k.Logger(ctx).Debug(
|
||||||
fmt.Sprintf("state %s", action),
|
fmt.Sprintf("state %s", action),
|
||||||
"ethereum-address", addr.Hex(),
|
"ethereum-address", addr.Hex(),
|
||||||
"key", key.Hex(),
|
"key", key.Hex(),
|
||||||
@ -416,6 +449,8 @@ func (k *Keeper) SetState(addr common.Address, key, value common.Hash) {
|
|||||||
// Suicide marks the given account as suicided and clears the account balance of
|
// Suicide marks the given account as suicided and clears the account balance of
|
||||||
// the EVM tokens.
|
// the EVM tokens.
|
||||||
func (k *Keeper) Suicide(addr common.Address) bool {
|
func (k *Keeper) Suicide(addr common.Address) bool {
|
||||||
|
ctx := k.Ctx()
|
||||||
|
|
||||||
prev := k.HasSuicided(addr)
|
prev := k.HasSuicided(addr)
|
||||||
if prev {
|
if prev {
|
||||||
return true
|
return true
|
||||||
@ -425,7 +460,7 @@ func (k *Keeper) Suicide(addr common.Address) bool {
|
|||||||
|
|
||||||
_, err := k.ClearBalance(cosmosAddr)
|
_, err := k.ClearBalance(cosmosAddr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
k.Logger(k.Ctx()).Error(
|
k.Logger(ctx).Error(
|
||||||
"failed to subtract balance on suicide",
|
"failed to subtract balance on suicide",
|
||||||
"ethereum-address", addr.Hex(),
|
"ethereum-address", addr.Hex(),
|
||||||
"cosmos-address", cosmosAddr.String(),
|
"cosmos-address", cosmosAddr.String(),
|
||||||
@ -436,12 +471,9 @@ func (k *Keeper) Suicide(addr common.Address) bool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// TODO: (@fedekunze) do we also need to delete the storage state and the code?
|
// TODO: (@fedekunze) do we also need to delete the storage state and the code?
|
||||||
|
k.setSuicided(ctx, addr)
|
||||||
|
|
||||||
// Set a single byte to the transient store
|
k.Logger(ctx).Debug(
|
||||||
store := prefix.NewStore(k.Ctx().TransientStore(k.transientKey), types.KeyPrefixTransientSuicided)
|
|
||||||
store.Set(addr.Bytes(), []byte{1})
|
|
||||||
|
|
||||||
k.Logger(k.Ctx()).Debug(
|
|
||||||
"account suicided",
|
"account suicided",
|
||||||
"ethereum-address", addr.Hex(),
|
"ethereum-address", addr.Hex(),
|
||||||
"cosmos-address", cosmosAddr.String(),
|
"cosmos-address", cosmosAddr.String(),
|
||||||
@ -450,11 +482,19 @@ func (k *Keeper) Suicide(addr common.Address) bool {
|
|||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// setSuicided sets a single byte to the transient store and marks the address as suicided
|
||||||
|
func (k Keeper) setSuicided(ctx sdk.Context, addr common.Address) {
|
||||||
|
|
||||||
|
store := prefix.NewStore(ctx.TransientStore(k.transientKey), types.KeyPrefixTransientSuicided)
|
||||||
|
store.Set(addr.Bytes(), []byte{1})
|
||||||
|
}
|
||||||
|
|
||||||
// HasSuicided queries the transient store to check if the account has been marked as suicided in the
|
// HasSuicided queries the transient store to check if the account has been marked as suicided in the
|
||||||
// current block. Accounts that are suicided will be returned as non-nil during queries and "cleared"
|
// current block. Accounts that are suicided will be returned as non-nil during queries and "cleared"
|
||||||
// after the block has been committed.
|
// after the block has been committed.
|
||||||
func (k *Keeper) HasSuicided(addr common.Address) bool {
|
func (k *Keeper) HasSuicided(addr common.Address) bool {
|
||||||
store := prefix.NewStore(k.Ctx().TransientStore(k.transientKey), types.KeyPrefixTransientSuicided)
|
ctx := k.Ctx()
|
||||||
|
store := prefix.NewStore(ctx.TransientStore(k.transientKey), types.KeyPrefixTransientSuicided)
|
||||||
return store.Has(addr.Bytes())
|
return store.Has(addr.Bytes())
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -465,13 +505,14 @@ func (k *Keeper) HasSuicided(addr common.Address) bool {
|
|||||||
// Exist returns true if the given account exists in store or if it has been
|
// Exist returns true if the given account exists in store or if it has been
|
||||||
// marked as suicided in the transient store.
|
// marked as suicided in the transient store.
|
||||||
func (k *Keeper) Exist(addr common.Address) bool {
|
func (k *Keeper) Exist(addr common.Address) bool {
|
||||||
|
ctx := k.Ctx()
|
||||||
// return true if the account has suicided
|
// return true if the account has suicided
|
||||||
if k.HasSuicided(addr) {
|
if k.HasSuicided(addr) {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
cosmosAddr := sdk.AccAddress(addr.Bytes())
|
cosmosAddr := sdk.AccAddress(addr.Bytes())
|
||||||
account := k.accountKeeper.GetAccount(k.Ctx(), cosmosAddr)
|
account := k.accountKeeper.GetAccount(ctx, cosmosAddr)
|
||||||
return account != nil
|
return account != nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -482,11 +523,12 @@ func (k *Keeper) Exist(addr common.Address) bool {
|
|||||||
//
|
//
|
||||||
// Non-ethereum accounts are considered not empty
|
// Non-ethereum accounts are considered not empty
|
||||||
func (k *Keeper) Empty(addr common.Address) bool {
|
func (k *Keeper) Empty(addr common.Address) bool {
|
||||||
|
ctx := k.Ctx()
|
||||||
nonce := uint64(0)
|
nonce := uint64(0)
|
||||||
codeHash := types.EmptyCodeHash
|
codeHash := types.EmptyCodeHash
|
||||||
|
|
||||||
cosmosAddr := sdk.AccAddress(addr.Bytes())
|
cosmosAddr := sdk.AccAddress(addr.Bytes())
|
||||||
account := k.accountKeeper.GetAccount(k.Ctx(), cosmosAddr)
|
account := k.accountKeeper.GetAccount(ctx, cosmosAddr)
|
||||||
|
|
||||||
if account != nil {
|
if account != nil {
|
||||||
nonce = account.GetSequence()
|
nonce = account.GetSequence()
|
||||||
@ -537,7 +579,8 @@ func (k *Keeper) PrepareAccessList(sender common.Address, dest *common.Address,
|
|||||||
|
|
||||||
// AddressInAccessList returns true if the address is registered on the transient store.
|
// AddressInAccessList returns true if the address is registered on the transient store.
|
||||||
func (k *Keeper) AddressInAccessList(addr common.Address) bool {
|
func (k *Keeper) AddressInAccessList(addr common.Address) bool {
|
||||||
ts := prefix.NewStore(k.Ctx().TransientStore(k.transientKey), types.KeyPrefixTransientAccessListAddress)
|
ctx := k.Ctx()
|
||||||
|
ts := prefix.NewStore(ctx.TransientStore(k.transientKey), types.KeyPrefixTransientAccessListAddress)
|
||||||
return ts.Has(addr.Bytes())
|
return ts.Has(addr.Bytes())
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -550,7 +593,8 @@ func (k *Keeper) SlotInAccessList(addr common.Address, slot common.Hash) (addres
|
|||||||
|
|
||||||
// addressSlotInAccessList returns true if the address's slot is registered on the transient store.
|
// addressSlotInAccessList returns true if the address's slot is registered on the transient store.
|
||||||
func (k *Keeper) addressSlotInAccessList(addr common.Address, slot common.Hash) bool {
|
func (k *Keeper) addressSlotInAccessList(addr common.Address, slot common.Hash) bool {
|
||||||
ts := prefix.NewStore(k.Ctx().TransientStore(k.transientKey), types.KeyPrefixTransientAccessListSlot)
|
ctx := k.Ctx()
|
||||||
|
ts := prefix.NewStore(ctx.TransientStore(k.transientKey), types.KeyPrefixTransientAccessListSlot)
|
||||||
key := append(addr.Bytes(), slot.Bytes()...)
|
key := append(addr.Bytes(), slot.Bytes()...)
|
||||||
return ts.Has(key)
|
return ts.Has(key)
|
||||||
}
|
}
|
||||||
@ -562,7 +606,8 @@ func (k *Keeper) AddAddressToAccessList(addr common.Address) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
ts := prefix.NewStore(k.Ctx().TransientStore(k.transientKey), types.KeyPrefixTransientAccessListAddress)
|
ctx := k.Ctx()
|
||||||
|
ts := prefix.NewStore(ctx.TransientStore(k.transientKey), types.KeyPrefixTransientAccessListAddress)
|
||||||
ts.Set(addr.Bytes(), []byte{0x1})
|
ts.Set(addr.Bytes(), []byte{0x1})
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -574,7 +619,8 @@ func (k *Keeper) AddSlotToAccessList(addr common.Address, slot common.Hash) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
ts := prefix.NewStore(k.Ctx().TransientStore(k.transientKey), types.KeyPrefixTransientAccessListSlot)
|
ctx := k.Ctx()
|
||||||
|
ts := prefix.NewStore(ctx.TransientStore(k.transientKey), types.KeyPrefixTransientAccessListSlot)
|
||||||
key := append(addr.Bytes(), slot.Bytes()...)
|
key := append(addr.Bytes(), slot.Bytes()...)
|
||||||
ts.Set(key, []byte{0x1})
|
ts.Set(key, []byte{0x1})
|
||||||
}
|
}
|
||||||
@ -601,7 +647,9 @@ func (k *Keeper) RevertToSnapshot(target int) {
|
|||||||
// context. This function also fills in the tx hash, block hash, tx index and log index fields before setting the log
|
// context. This function also fills in the tx hash, block hash, tx index and log index fields before setting the log
|
||||||
// to store.
|
// to store.
|
||||||
func (k *Keeper) AddLog(log *ethtypes.Log) {
|
func (k *Keeper) AddLog(log *ethtypes.Log) {
|
||||||
log.BlockHash = common.BytesToHash(k.Ctx().HeaderHash())
|
ctx := k.Ctx()
|
||||||
|
|
||||||
|
log.BlockHash = common.BytesToHash(ctx.HeaderHash())
|
||||||
log.TxIndex = uint(k.GetTxIndexTransient())
|
log.TxIndex = uint(k.GetTxIndexTransient())
|
||||||
log.TxHash = k.GetTxHashTransient()
|
log.TxHash = k.GetTxHashTransient()
|
||||||
|
|
||||||
@ -609,7 +657,7 @@ func (k *Keeper) AddLog(log *ethtypes.Log) {
|
|||||||
k.IncreaseLogSizeTransient()
|
k.IncreaseLogSizeTransient()
|
||||||
k.SetLog(log)
|
k.SetLog(log)
|
||||||
|
|
||||||
k.Logger(k.Ctx()).Debug(
|
k.Logger(ctx).Debug(
|
||||||
"log added",
|
"log added",
|
||||||
"tx-hash-ethereum", log.TxHash.Hex(),
|
"tx-hash-ethereum", log.TxHash.Hex(),
|
||||||
"log-index", int(log.Index),
|
"log-index", int(log.Index),
|
||||||
@ -632,7 +680,8 @@ func (k *Keeper) AddPreimage(_ common.Hash, _ []byte) {}
|
|||||||
// ForEachStorage uses the store iterator to iterate over all the state keys and perform a callback
|
// ForEachStorage uses the store iterator to iterate over all the state keys and perform a callback
|
||||||
// function on each of them.
|
// function on each of them.
|
||||||
func (k *Keeper) ForEachStorage(addr common.Address, cb func(key, value common.Hash) bool) error {
|
func (k *Keeper) ForEachStorage(addr common.Address, cb func(key, value common.Hash) bool) error {
|
||||||
store := k.Ctx().KVStore(k.storeKey)
|
ctx := k.Ctx()
|
||||||
|
store := ctx.KVStore(k.storeKey)
|
||||||
prefix := types.AddressStoragePrefix(addr)
|
prefix := types.AddressStoragePrefix(addr)
|
||||||
|
|
||||||
iterator := sdk.KVStorePrefixIterator(store, prefix)
|
iterator := sdk.KVStorePrefixIterator(store, prefix)
|
||||||
|
128
x/evm/keeper/statedb_benchmark_test.go
Normal file
128
x/evm/keeper/statedb_benchmark_test.go
Normal file
@ -0,0 +1,128 @@
|
|||||||
|
package keeper_test
|
||||||
|
|
||||||
|
import (
|
||||||
|
"math/big"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/stretchr/testify/require"
|
||||||
|
|
||||||
|
"github.com/ethereum/go-ethereum/common"
|
||||||
|
ethtypes "github.com/ethereum/go-ethereum/core/types"
|
||||||
|
"github.com/ethereum/go-ethereum/crypto"
|
||||||
|
|
||||||
|
"github.com/tharsis/ethermint/tests"
|
||||||
|
)
|
||||||
|
|
||||||
|
func BenchmarkCreateAccountNew(b *testing.B) {
|
||||||
|
suite := KeeperTestSuite{}
|
||||||
|
suite.DoSetupTest(b)
|
||||||
|
|
||||||
|
b.ResetTimer()
|
||||||
|
b.ReportAllocs()
|
||||||
|
|
||||||
|
for i := 0; i < b.N; i++ {
|
||||||
|
b.StopTimer()
|
||||||
|
addr := tests.GenerateAddress()
|
||||||
|
b.StartTimer()
|
||||||
|
suite.app.EvmKeeper.CreateAccount(addr)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func BenchmarkCreateAccountExisting(b *testing.B) {
|
||||||
|
suite := KeeperTestSuite{}
|
||||||
|
suite.DoSetupTest(b)
|
||||||
|
|
||||||
|
b.ResetTimer()
|
||||||
|
b.ReportAllocs()
|
||||||
|
|
||||||
|
for i := 0; i < b.N; i++ {
|
||||||
|
suite.app.EvmKeeper.CreateAccount(suite.address)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func BenchmarkAddBalance(b *testing.B) {
|
||||||
|
suite := KeeperTestSuite{}
|
||||||
|
suite.DoSetupTest(b)
|
||||||
|
|
||||||
|
amt := big.NewInt(10)
|
||||||
|
|
||||||
|
b.ResetTimer()
|
||||||
|
b.ReportAllocs()
|
||||||
|
|
||||||
|
for i := 0; i < b.N; i++ {
|
||||||
|
suite.app.EvmKeeper.AddBalance(suite.address, amt)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func BenchmarkSetCode(b *testing.B) {
|
||||||
|
suite := KeeperTestSuite{}
|
||||||
|
suite.DoSetupTest(b)
|
||||||
|
|
||||||
|
hash := crypto.Keccak256Hash([]byte("code")).Bytes()
|
||||||
|
|
||||||
|
b.ResetTimer()
|
||||||
|
b.ReportAllocs()
|
||||||
|
|
||||||
|
for i := 0; i < b.N; i++ {
|
||||||
|
suite.app.EvmKeeper.SetCode(suite.address, hash)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func BenchmarkSetState(b *testing.B) {
|
||||||
|
suite := KeeperTestSuite{}
|
||||||
|
suite.DoSetupTest(b)
|
||||||
|
|
||||||
|
hash := crypto.Keccak256Hash([]byte("topic")).Bytes()
|
||||||
|
|
||||||
|
b.ResetTimer()
|
||||||
|
b.ReportAllocs()
|
||||||
|
|
||||||
|
for i := 0; i < b.N; i++ {
|
||||||
|
suite.app.EvmKeeper.SetCode(suite.address, hash)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func BenchmarkAddLog(b *testing.B) {
|
||||||
|
suite := KeeperTestSuite{}
|
||||||
|
suite.DoSetupTest(b)
|
||||||
|
|
||||||
|
topic := crypto.Keccak256Hash([]byte("topic"))
|
||||||
|
txHash := crypto.Keccak256Hash([]byte("tx_hash"))
|
||||||
|
blockHash := crypto.Keccak256Hash([]byte("block_hash"))
|
||||||
|
|
||||||
|
b.ResetTimer()
|
||||||
|
b.ReportAllocs()
|
||||||
|
|
||||||
|
for i := 0; i < b.N; i++ {
|
||||||
|
suite.app.EvmKeeper.AddLog(ðtypes.Log{
|
||||||
|
Address: suite.address,
|
||||||
|
Topics: []common.Hash{topic},
|
||||||
|
Data: []byte("data"),
|
||||||
|
BlockNumber: 1,
|
||||||
|
TxHash: txHash,
|
||||||
|
TxIndex: 1,
|
||||||
|
BlockHash: blockHash,
|
||||||
|
Index: 1,
|
||||||
|
Removed: false,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func BenchmarkSnapshot(b *testing.B) {
|
||||||
|
suite := KeeperTestSuite{}
|
||||||
|
suite.DoSetupTest(b)
|
||||||
|
|
||||||
|
b.ResetTimer()
|
||||||
|
b.ReportAllocs()
|
||||||
|
|
||||||
|
for i := 0; i < b.N; i++ {
|
||||||
|
target := suite.app.EvmKeeper.Snapshot()
|
||||||
|
require.Equal(b, i, target)
|
||||||
|
}
|
||||||
|
|
||||||
|
for i := b.N - 1; i >= 0; i-- {
|
||||||
|
require.NotPanics(b, func() {
|
||||||
|
suite.app.EvmKeeper.RevertToSnapshot(i)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user