Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[factory] move SimulateExecution() out of factory interface #4476

Merged
merged 2 commits into from
Nov 12, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 12 additions & 4 deletions action/protocol/execution/evm/evm.go
Original file line number Diff line number Diff line change
Expand Up @@ -613,6 +613,7 @@ func SimulateExecution(
sm protocol.StateManager,
caller address.Address,
ex action.TxDataForSimulation,
opts ...protocol.SimulateOption,
) ([]byte, *action.Receipt, error) {
ctx, span := tracer.NewSpan(ctx, "evm.SimulateExecution")
defer span.End()
Expand All @@ -632,7 +633,16 @@ func SimulateExecution(
if err != nil {
return nil, nil, err
}
ctx = protocol.WithBlockCtx(
cfg := &protocol.SimulateOptionConfig{}
for _, opt := range opts {
opt(cfg)
}
if cfg.PreOpt != nil {
if err := cfg.PreOpt(sm); err != nil {
return nil, nil, err
}
}
ctx = protocol.WithFeatureCtx(protocol.WithBlockCtx(
ctx,
protocol.BlockCtx{
BlockHeight: bcCtx.Tip.Height + 1,
Expand All @@ -642,8 +652,6 @@ func SimulateExecution(
BaseFee: protocol.CalcBaseFee(g.Blockchain, &bcCtx.Tip),
ExcessBlobGas: protocol.CalcExcessBlobGas(bcCtx.Tip.ExcessBlobGas, bcCtx.Tip.BlobGasUsed),
},
)

ctx = protocol.WithFeatureCtx(ctx)
))
return ExecuteContract(ctx, sm, ex)
}
6 changes: 5 additions & 1 deletion action/protocol/execution/protocol_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -293,7 +293,11 @@ func readExecution(
GetBlockTime: getBlockTimeForTest,
DepositGasFunc: rewarding.DepositGas,
})
return sf.SimulateExecution(ctx, addr, elp)
ws, err := sf.WorkingSet(ctx)
if err != nil {
return nil, nil, err
}
return evm.SimulateExecution(ctx, ws, addr, elp)
}

func (sct *SmartContractTest) runExecutions(
Expand Down
12 changes: 10 additions & 2 deletions api/coreservice.go
Original file line number Diff line number Diff line change
Expand Up @@ -1820,7 +1820,11 @@ func (core *coreService) ReadContractStorage(ctx context.Context, addr address.A
if err != nil {
return nil, status.Error(codes.Internal, err.Error())
}
return core.sf.ReadContractStorage(ctx, addr, key)
ws, err := core.sf.WorkingSet(ctx)
if err != nil {
return nil, status.Error(codes.Internal, err.Error())
}
return evm.ReadContractStorage(ctx, ws, addr, key)
}

func (core *coreService) ReceiveBlock(blk *block.Block) error {
Expand Down Expand Up @@ -1969,7 +1973,11 @@ func (core *coreService) simulateExecution(ctx context.Context, addr address.Add
GetBlockTime: core.getBlockTime,
DepositGasFunc: rewarding.DepositGas,
})
return core.sf.SimulateExecution(ctx, addr, elp, opts...)
ws, err := core.sf.WorkingSet(ctx)
if err != nil {
return nil, nil, status.Error(codes.Internal, err.Error())
}
return evm.SimulateExecution(ctx, ws, addr, elp, opts...)
}

func filterReceipts(receipts []*action.Receipt, actHash hash.Hash256) *action.Receipt {
Expand Down
6 changes: 5 additions & 1 deletion chainservice/builder.go
Original file line number Diff line number Diff line change
Expand Up @@ -735,7 +735,11 @@ func (builder *Builder) registerRollDPoSProtocol() error {
GetBlockTime: getBlockTime,
DepositGasFunc: rewarding.DepositGas,
})
data, _, err := factory.SimulateExecution(ctx, addr, elp)
ws, err := factory.WorkingSet(ctx)
if err != nil {
return nil, err
}
data, _, err := evm.SimulateExecution(ctx, ws, addr, elp)
return data, err
},
candidatesutil.CandidatesFromDB,
Expand Down
7 changes: 5 additions & 2 deletions e2etest/staking_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -125,8 +125,11 @@ func TestStakingContract(t *testing.T) {
GetBlockTime: fakeGetBlockTime,
DepositGasFunc: rewarding.DepositGas,
})
data, _, err := sf.SimulateExecution(ctx, addr, elp)

ws, err := sf.WorkingSet(ctx)
if err != nil {
return nil, err
}
data, _, err := evm.SimulateExecution(ctx, ws, addr, elp)
return data, err
})
require.NoError(err)
Expand Down
47 changes: 9 additions & 38 deletions state/factory/factory.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright (c) 2022 IoTeX Foundation
// Copyright (c) 2024 IoTeX Foundation
// This source code is provided 'as is' and no warranties are given as to title or non-infringement, merchantability
// or fitness for purpose and, to the extent permitted by law, all liability for your use of the code is disclaimed.
// This source code is governed by Apache License 2.0 that can be found in the LICENSE file.
Expand All @@ -18,7 +18,6 @@ import (

"github.com/iotexproject/go-pkgs/cache"
"github.com/iotexproject/go-pkgs/hash"
"github.com/iotexproject/iotex-address/address"

"github.com/iotexproject/iotex-core/v2/action"
"github.com/iotexproject/iotex-core/v2/action/protocol"
Expand Down Expand Up @@ -86,12 +85,12 @@ type (
Validate(context.Context, *block.Block) error
// NewBlockBuilder creates block builder
NewBlockBuilder(context.Context, actpool.ActPool, func(action.Envelope) (*action.SealedEnvelope, error)) (*block.Builder, error)
SimulateExecution(context.Context, address.Address, action.Envelope, ...protocol.SimulateOption) ([]byte, *action.Receipt, error)
ReadContractStorage(context.Context, address.Address, []byte) ([]byte, error)
PutBlock(context.Context, *block.Block) error
DeleteTipBlock(context.Context, *block.Block) error
StateAtHeight(uint64, interface{}, ...protocol.StateOption) error
StatesAtHeight(uint64, ...protocol.StateOption) (state.Iterator, error)
WorkingSet(context.Context) (protocol.StateManager, error)
WorkingSetAtHeight(context.Context, uint64) (protocol.StateManager, error)
}

// factory implements StateFactory interface, tracks changes to account/contract and batch-commits to DB
Expand Down Expand Up @@ -382,44 +381,16 @@ func (sf *factory) NewBlockBuilder(
return blkBuilder, nil
}

// SimulateExecution simulates a running of smart contract operation, this is done off the network since it does not
// cause any state change
func (sf *factory) SimulateExecution(
ctx context.Context,
caller address.Address,
elp action.Envelope,
opts ...protocol.SimulateOption,
) ([]byte, *action.Receipt, error) {
ctx, span := tracer.NewSpan(ctx, "factory.SimulateExecution")
defer span.End()

func (sf *factory) WorkingSet(ctx context.Context) (protocol.StateManager, error) {
sf.mutex.Lock()
ws, err := sf.newWorkingSet(ctx, sf.currentChainHeight+1)
sf.mutex.Unlock()
if err != nil {
return nil, nil, errors.Wrap(err, "failed to obtain working set from state factory")
}
cfg := &protocol.SimulateOptionConfig{}
for _, opt := range opts {
opt(cfg)
}
if cfg.PreOpt != nil {
if err := cfg.PreOpt(ws); err != nil {
return nil, nil, err
}
}
return evm.SimulateExecution(ctx, ws, caller, elp)
defer sf.mutex.Unlock()
return sf.newWorkingSet(ctx, sf.currentChainHeight+1)
}

// ReadContractStorage reads contract's storage
func (sf *factory) ReadContractStorage(ctx context.Context, contract address.Address, key []byte) ([]byte, error) {
func (sf *factory) WorkingSetAtHeight(ctx context.Context, height uint64) (protocol.StateManager, error) {
sf.mutex.Lock()
ws, err := sf.newWorkingSet(ctx, sf.currentChainHeight+1)
sf.mutex.Unlock()
if err != nil {
return nil, errors.Wrap(err, "failed to generate working set from state factory")
}
return evm.ReadContractStorage(ctx, ws, contract, key)
defer sf.mutex.Unlock()
return sf.newWorkingSet(ctx, height+1)
}

// PutBlock persists all changes in RunActions() into the DB
Expand Down
4 changes: 3 additions & 1 deletion state/factory/factory_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1224,7 +1224,9 @@ func testSimulateExecution(ctx context.Context, sf Factory, t *testing.T) {
},
DepositGasFunc: rewarding.DepositGas,
})
_, _, err = sf.SimulateExecution(ctx, addr, elp)
ws, err := sf.WorkingSet(ctx)
require.NoError(err)
_, _, err = evm.SimulateExecution(ctx, ws, addr, elp)
require.NoError(err)
}

Expand Down
43 changes: 5 additions & 38 deletions state/factory/statedb.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ import (

"github.com/iotexproject/go-pkgs/cache"
"github.com/iotexproject/go-pkgs/hash"
"github.com/iotexproject/iotex-address/address"

"github.com/iotexproject/iotex-core/v2/action"
"github.com/iotexproject/iotex-core/v2/action/protocol"
Expand All @@ -30,7 +29,6 @@ import (
"github.com/iotexproject/iotex-core/v2/db/batch"
"github.com/iotexproject/iotex-core/v2/pkg/log"
"github.com/iotexproject/iotex-core/v2/pkg/prometheustimer"
"github.com/iotexproject/iotex-core/v2/pkg/tracer"
"github.com/iotexproject/iotex-core/v2/pkg/util/byteutil"
"github.com/iotexproject/iotex-core/v2/state"
)
Expand Down Expand Up @@ -261,46 +259,15 @@ func (sdb *stateDB) NewBlockBuilder(
return blkBuilder, nil
}

// SimulateExecution simulates a running of smart contract operation, this is done off the network since it does not
// cause any state change
func (sdb *stateDB) SimulateExecution(
ctx context.Context,
caller address.Address,
elp action.Envelope,
opts ...protocol.SimulateOption,
) ([]byte, *action.Receipt, error) {
ctx, span := tracer.NewSpan(ctx, "stateDB.SimulateExecution")
defer span.End()

func (sdb *stateDB) WorkingSet(ctx context.Context) (protocol.StateManager, error) {
sdb.mutex.RLock()
currHeight := sdb.currentChainHeight
height := sdb.currentChainHeight
sdb.mutex.RUnlock()
ws, err := sdb.newWorkingSet(ctx, currHeight+1)
if err != nil {
return nil, nil, err
}
cfg := &protocol.SimulateOptionConfig{}
for _, opt := range opts {
opt(cfg)
}
if cfg.PreOpt != nil {
if err := cfg.PreOpt(ws); err != nil {
return nil, nil, err
}
}
return evm.SimulateExecution(ctx, ws, caller, elp)
return sdb.newWorkingSet(ctx, height+1)
}

// ReadContractStorage reads contract's storage
func (sdb *stateDB) ReadContractStorage(ctx context.Context, contract address.Address, key []byte) ([]byte, error) {
sdb.mutex.RLock()
currHeight := sdb.currentChainHeight
sdb.mutex.RUnlock()
ws, err := sdb.newWorkingSet(ctx, currHeight+1)
if err != nil {
return nil, errors.Wrap(err, "failed to generate working set from state db")
}
return evm.ReadContractStorage(ctx, ws, contract, key)
func (sdb *stateDB) WorkingSetAtHeight(ctx context.Context, height uint64) (protocol.StateManager, error) {
return sdb.newWorkingSet(ctx, height+1)
}

// PutBlock persists all changes in RunActions() into the DB
Expand Down
67 changes: 30 additions & 37 deletions test/mock/mock_factory/mock_factory.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading