@@ -45,14 +45,6 @@ func NewBalanceChangeEntry(acc common.Address, amt *uint256.Int, op Operation) B
4545 return BalanceChangeEntry {acc , amt , op }
4646}
4747
48- // Snapshot contains all state and events previous to the precompile call
49- // This is needed to allow us to revert the changes
50- // during the EVM execution
51- type Snapshot struct {
52- MultiStore storetypes.CacheMultiStore
53- Events sdk.Events
54- }
55-
5648// RequiredGas calculates the base minimum required gas for a transaction or a query.
5749// It uses the method ID to determine if the input is a transaction or a query and
5850// uses the Cosmos SDK gas config flat cost and the flat per byte cost * len(argBz) to calculate the gas.
@@ -66,46 +58,41 @@ func (p Precompile) RequiredGas(input []byte, isTransaction bool) uint64 {
6658 return p .KvGasConfig .ReadCostFlat + (p .KvGasConfig .ReadCostPerByte * uint64 (len (argsBz )))
6759}
6860
69- // RunAtomic is used within the Run function of each Precompile implementation.
70- // It handles rolling back to the provided snapshot if an error is returned from the core precompile logic.
71- // Note: This is only required for stateful precompiles.
72- func (p Precompile ) RunAtomic (s Snapshot , stateDB * statedb.StateDB , fn func () ([]byte , error )) ([]byte , error ) {
73- bz , err := fn ()
74- if err != nil {
75- // revert to snapshot on error
76- stateDB .RevertMultiStore (s .MultiStore , s .Events )
77- }
78- return bz , err
79- }
80-
8161// RunSetup runs the initial setup required to run a transaction or a query.
8262// It returns the sdk Context, EVM stateDB, ABI method, initial gas and calling arguments.
8363func (p Precompile ) RunSetup (
8464 evm * vm.EVM ,
8565 contract * vm.Contract ,
8666 readOnly bool ,
8767 isTransaction func (name * abi.Method ) bool ,
88- ) (ctx sdk.Context , stateDB * statedb.StateDB , s Snapshot , method * abi.Method , gasConfig storetypes.Gas , args []interface {}, err error ) {
68+ ) (ctx sdk.Context , stateDB * statedb.StateDB , method * abi.Method , gasConfig storetypes.Gas , args []interface {}, err error ) {
8969 stateDB , ok := evm .StateDB .(* statedb.StateDB )
9070 if ! ok {
91- return sdk.Context {}, nil , s , nil , uint64 (0 ), nil , errors .New (ErrNotRunInEvm )
71+ return sdk.Context {}, nil , nil , uint64 (0 ), nil , errors .New (ErrNotRunInEvm )
9272 }
9373
9474 // get the stateDB cache ctx
9575 ctx , err = stateDB .GetCacheContext ()
9676 if err != nil {
97- return sdk.Context {}, nil , s , nil , uint64 (0 ), nil , err
77+ return sdk.Context {}, nil , nil , uint64 (0 ), nil , err
9878 }
9979
10080 // take a snapshot of the current state before any changes
10181 // to be able to revert the changes
102- s .MultiStore = stateDB .MultiStoreSnapshot ()
103- s .Events = ctx .EventManager ().Events ()
82+ snapshot := stateDB .MultiStoreSnapshot ()
83+ events := ctx .EventManager ().Events ()
84+
85+ // add precompileCall entry on the stateDB journal
86+ // this allows to revert the changes within an evm txAdd commentMore actions
87+ err = stateDB .AddPrecompileFn (p .Address (), snapshot , events )
88+ if err != nil {
89+ return sdk.Context {}, nil , nil , uint64 (0 ), nil , err
90+ }
10491
10592 // commit the current changes in the cache ctx
10693 // to get the updated state for the precompile call
10794 if err := stateDB .CommitWithCacheCtx (); err != nil {
108- return sdk.Context {}, nil , s , nil , uint64 (0 ), nil , err
95+ return sdk.Context {}, nil , nil , uint64 (0 ), nil , err
10996 }
11097
11198 // NOTE: This is a special case where the calling transaction does not specify a function name.
@@ -131,26 +118,26 @@ func (p Precompile) RunSetup(
131118 }
132119
133120 if err != nil {
134- return sdk.Context {}, nil , s , nil , uint64 (0 ), nil , err
121+ return sdk.Context {}, nil , nil , uint64 (0 ), nil , err
135122 }
136123
137124 // return error if trying to write to state during a read-only call
138125 if readOnly && isTransaction (method ) {
139- return sdk.Context {}, nil , s , nil , uint64 (0 ), nil , vm .ErrWriteProtection
126+ return sdk.Context {}, nil , nil , uint64 (0 ), nil , vm .ErrWriteProtection
140127 }
141128
142129 // if the method type is `function` continue looking for arguments
143130 if method .Type == abi .Function {
144131 argsBz := contract .Input [4 :]
145132 args , err = method .Inputs .Unpack (argsBz )
146133 if err != nil {
147- return sdk.Context {}, nil , s , nil , uint64 (0 ), nil , err
134+ return sdk.Context {}, nil , nil , uint64 (0 ), nil , err
148135 }
149136 }
150137
151138 initialGas := ctx .GasMeter ().GasConsumed ()
152139
153- defer HandleGasError (ctx , contract , initialGas , & err , stateDB , s )()
140+ defer HandleGasError (ctx , contract , initialGas , & err )()
154141
155142 // set the default SDK gas configuration to track gas usage
156143 // we are changing the gas meter type, so it panics gracefully when out of gas
@@ -160,20 +147,16 @@ func (p Precompile) RunSetup(
160147 // we need to consume the gas that was already used by the EVM
161148 ctx .GasMeter ().ConsumeGas (initialGas , "creating a new gas meter" )
162149
163- return ctx , stateDB , s , method , initialGas , args , nil
150+ return ctx , stateDB , method , initialGas , args , nil
164151}
165152
166153// HandleGasError handles the out of gas panic by resetting the gas meter and returning an error.
167154// This is used in order to avoid panics and to allow for the EVM to continue cleanup if the tx or query run out of gas.
168- func HandleGasError (ctx sdk.Context , contract * vm.Contract , initialGas storetypes.Gas , err * error , stateDB * statedb. StateDB , snapshot Snapshot ) func () {
155+ func HandleGasError (ctx sdk.Context , contract * vm.Contract , initialGas storetypes.Gas , err * error ) func () {
169156 return func () {
170157 if r := recover (); r != nil {
171158 switch r .(type ) {
172159 case storetypes.ErrorOutOfGas :
173-
174- // revert to snapshot on error
175- stateDB .RevertMultiStore (snapshot .MultiStore , snapshot .Events )
176-
177160 // update contract gas
178161 usedGas := ctx .GasMeter ().GasConsumed () - initialGas
179162 _ = contract .UseGas (usedGas , nil , tracing .GasChangeCallFailedExecution )
@@ -190,9 +173,7 @@ func HandleGasError(ctx sdk.Context, contract *vm.Contract, initialGas storetype
190173}
191174
192175// AddJournalEntries adds the balanceChange (if corresponds)
193- // and precompileCall entries on the stateDB journal
194- // This allows to revert the call changes within an evm tx
195- func (p Precompile ) AddJournalEntries (stateDB * statedb.StateDB , s Snapshot ) error {
176+ func (p Precompile ) AddJournalEntries (stateDB * statedb.StateDB ) error {
196177 for _ , entry := range p .journalEntries {
197178 switch entry .Op {
198179 case Sub :
@@ -204,7 +185,7 @@ func (p Precompile) AddJournalEntries(stateDB *statedb.StateDB, s Snapshot) erro
204185 }
205186 }
206187
207- return stateDB . AddPrecompileFn ( p . Address (), s . MultiStore , s . Events )
188+ return nil
208189}
209190
210191// SetBalanceChangeEntries sets the balanceChange entries
0 commit comments