Skip to content

Commit

Permalink
[evm] manually correct gas refund in case opcode execution returns Er…
Browse files Browse the repository at this point in the history
…rWriteProtection
  • Loading branch information
dustinxie committed Nov 9, 2022
1 parent ba21de2 commit fd5a1a0
Show file tree
Hide file tree
Showing 4 changed files with 24 additions and 30 deletions.
20 changes: 11 additions & 9 deletions action/protocol/execution/evm/evm.go
Original file line number Diff line number Diff line change
Expand Up @@ -319,7 +319,7 @@ func prepareStateDB(ctx context.Context, sm protocol.StateManager) (*StateDBAdap
opts = append(opts, NotCheckPutStateErrorOption())
}
if !featureCtx.CorrectGasRefund {
opts = append(opts, NotCorrectGasRefundOption())
opts = append(opts, ManualCorrectGasRefundOption())
}

return NewStateDBAdapter(
Expand Down Expand Up @@ -422,17 +422,19 @@ func executeInEVM(ctx context.Context, evmParams *Params, stateDB *StateDBAdapte
// After EIP-3529: refunds are capped to gasUsed / 5
refund = (evmParams.gas - remainingGas) / params.RefundQuotientEIP3529
}
// adjust refund due to dynamicGas
// before London EVM activation (at Okhotsk height), in certain cases dynamicGas
// has caused gas refund to change, which needs to be manually adjusted after
// the tx is reverted. After Okhotsk height, it is fixed inside RevertToSnapshot()
var (
refundLastSnapshot = stateDB.RefundAtLastSnapshot()
currentRefund = stateDB.GetRefund()
featureCtx = protocol.MustGetFeatureCtx(ctx)
refundBeforeDynamicGas = evm.TxContext.RefundBeforeDynamicGas
currentRefund = stateDB.GetRefund()
featureCtx = protocol.MustGetFeatureCtx(ctx)
)
if evmErr != nil && !featureCtx.CorrectGasRefund && refundLastSnapshot > 0 && refundLastSnapshot != currentRefund {
if refundLastSnapshot > currentRefund {
stateDB.AddRefund(refundLastSnapshot - currentRefund)
if evmErr != nil && !featureCtx.CorrectGasRefund && evm.TxContext.HitErrWriteProtection && refundBeforeDynamicGas != currentRefund {
if refundBeforeDynamicGas > currentRefund {
stateDB.AddRefund(refundBeforeDynamicGas - currentRefund)
} else {
stateDB.SubRefund(currentRefund - refundLastSnapshot)
stateDB.SubRefund(currentRefund - refundBeforeDynamicGas)
}
}
if refund > stateDB.GetRefund() {
Expand Down
23 changes: 8 additions & 15 deletions action/protocol/execution/evm/evmstatedbadapter.go
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,6 @@ type (
blockHeight uint64
executionHash hash.Hash256
refund uint64
refundAtLastSnapshot uint64
refundSnapshot map[int]uint64
cachedContract contractMap
contractSnapshot map[int]contractMap // snapshots of contracts
Expand All @@ -76,7 +75,7 @@ type (
fixSnapshotOrder bool
revertLog bool
notCheckPutStateError bool
notCorrectGasRefund bool
manualCorrectGasRefund bool
}
)

Expand Down Expand Up @@ -147,10 +146,13 @@ func NotCheckPutStateErrorOption() StateDBAdapterOption {
}
}

// NotCorrectGasRefundOption set correctGasRefund as true
func NotCorrectGasRefundOption() StateDBAdapterOption {
// ManualCorrectGasRefundOption set manualCorrectGasRefund as true
func ManualCorrectGasRefundOption() StateDBAdapterOption {
return func(adapter *StateDBAdapter) error {
adapter.notCorrectGasRefund = true
// before London EVM activation (at Okhotsk height), in certain cases dynamicGas
// has caused gas refund to change, which needs to be manually adjusted after
// the tx is reverted. After Okhotsk height, it is fixed inside RevertToSnapshot()
adapter.manualCorrectGasRefund = true
return nil
}
}
Expand Down Expand Up @@ -553,10 +555,7 @@ func (stateDB *StateDBAdapter) RevertToSnapshot(snapshot int) {
return
}
// restore gas refund
if stateDB.notCorrectGasRefund {
// check if refund has changed from last snapshot (due to dynamicGas)
stateDB.refundAtLastSnapshot = stateDB.refundSnapshot[snapshot]
} else {
if !stateDB.manualCorrectGasRefund {
stateDB.refund = stateDB.refundSnapshot[snapshot]
}
// restore logs and txLogs
Expand Down Expand Up @@ -641,11 +640,6 @@ func (stateDB *StateDBAdapter) RevertToSnapshot(snapshot int) {
}
}

// RefundAtLastSnapshot returns refund at last snapshot
func (stateDB *StateDBAdapter) RefundAtLastSnapshot() uint64 {
return stateDB.refundAtLastSnapshot
}

func (stateDB *StateDBAdapter) cachedContractAddrs() []hash.Hash160 {
addrs := make([]hash.Hash160, 0, len(stateDB.cachedContract))
for addr := range stateDB.cachedContract {
Expand Down Expand Up @@ -1036,7 +1030,6 @@ func (stateDB *StateDBAdapter) getNewContract(addr hash.Hash160) (Contract, erro

// clear clears local changes
func (stateDB *StateDBAdapter) clear() {
stateDB.refundAtLastSnapshot = 0
stateDB.refundSnapshot = make(map[int]uint64)
stateDB.cachedContract = make(contractMap)
stateDB.contractSnapshot = make(map[int]contractMap)
Expand Down
4 changes: 2 additions & 2 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ require (
github.com/benbjohnson/clock v1.0.3 // indirect
github.com/beorn7/perks v1.0.1 // indirect
github.com/btcsuite/btcd v0.21.0-beta // indirect
github.com/btcsuite/btcd/btcec/v2 v2.2.0 // indirect
github.com/btcsuite/btcd/btcec/v2 v2.1.2 // indirect
github.com/btcsuite/btcutil v1.0.3-0.20201208143702-a53e38424cce // indirect
github.com/cespare/xxhash/v2 v2.1.2 // indirect
github.com/davecgh/go-spew v1.1.1 // indirect
Expand Down Expand Up @@ -200,6 +200,6 @@ require (
gopkg.in/yaml.v3 v3.0.1 // indirect
)

replace github.com/ethereum/go-ethereum => github.com/iotexproject/go-ethereum v0.4.1
replace github.com/ethereum/go-ethereum => github.com/iotexproject/go-ethereum v1.7.4-0.20221109051020-885cbcd15f97

replace golang.org/x/xerrors => golang.org/x/xerrors v0.0.0-20190212162355-a5947ffaace3
7 changes: 3 additions & 4 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -103,9 +103,8 @@ github.com/btcsuite/btcd v0.0.0-20190824003749-130ea5bddde3/go.mod h1:3J08xEfcug
github.com/btcsuite/btcd v0.20.1-beta/go.mod h1:wVuoA8VJLEcwgqHBwHmzLRazpKxTv13Px/pDuV7OomQ=
github.com/btcsuite/btcd v0.21.0-beta h1:At9hIZdJW0s9E/fAz28nrz6AmcNlSVucCH796ZteX1M=
github.com/btcsuite/btcd v0.21.0-beta/go.mod h1:ZSWyehm27aAuS9bvkATT+Xte3hjHZ+MRgMY/8NJ7K94=
github.com/btcsuite/btcd/btcec/v2 v2.1.2 h1:YoYoC9J0jwfukodSBMzZYUVQ8PTiYg4BnOWiJVzTmLs=
github.com/btcsuite/btcd/btcec/v2 v2.1.2/go.mod h1:ctjw4H1kknNJmRN4iP1R7bTQ+v3GJkZBd6mui8ZsAZE=
github.com/btcsuite/btcd/btcec/v2 v2.2.0 h1:fzn1qaOt32TuLjFlkzYSsBC35Q3KUjT1SwPxiMSCF5k=
github.com/btcsuite/btcd/btcec/v2 v2.2.0/go.mod h1:U7MHm051Al6XmscBQ0BoNydpOTsFAn707034b5nY8zU=
github.com/btcsuite/btcd/chaincfg/chainhash v1.0.0/go.mod h1:7SFka0XMvUgj3hfZtydOrQY2mwhPclbT2snogU7SQQc=
github.com/btcsuite/btclog v0.0.0-20170628155309-84c8d2346e9f/go.mod h1:TdznJufoqS23FtqVCzL0ZqgP5MqXbb4fg/WgDys70nA=
github.com/btcsuite/btcutil v0.0.0-20190207003914-4c204d697803/go.mod h1:+5NJ2+qvTyV9exUAL/rxXi3DcLg2Ts+ymUAY5y4NvMg=
Expand Down Expand Up @@ -487,8 +486,8 @@ github.com/influxdata/promql/v2 v2.12.0/go.mod h1:fxOPu+DY0bqCTCECchSRtWfc+0X19y
github.com/influxdata/roaring v0.4.13-0.20180809181101-fc520f41fab6/go.mod h1:bSgUQ7q5ZLSO+bKBGqJiCBGAl+9DxyW63zLTujjUlOE=
github.com/influxdata/tdigest v0.0.0-20181121200506-bf2b5ad3c0a9/go.mod h1:Js0mqiSBE6Ffsg94weZZ2c+v/ciT8QRHFOap7EKDrR0=
github.com/influxdata/usage-client v0.0.0-20160829180054-6d3895376368/go.mod h1:Wbbw6tYNvwa5dlB6304Sd+82Z3f7PmVZHVKU637d4po=
github.com/iotexproject/go-ethereum v0.4.1 h1:8IdCOiMsuJQJl39ipBha0P+NMA60sqxAeYNiQVeshT4=
github.com/iotexproject/go-ethereum v0.4.1/go.mod h1:Lt5WzjM07XlXc95YzrhosmR4J9Ahd6X2wyEV2SvGhk0=
github.com/iotexproject/go-ethereum v1.7.4-0.20221109051020-885cbcd15f97 h1:tT6zI8apTHwiOP+EVfrIsrCwrjW3yN2V8W+6SIWhmfI=
github.com/iotexproject/go-ethereum v1.7.4-0.20221109051020-885cbcd15f97/go.mod h1:Lt5WzjM07XlXc95YzrhosmR4J9Ahd6X2wyEV2SvGhk0=
github.com/iotexproject/go-fsm v1.0.0 h1:Zrg9JnNDUZg4Anpj6oa0Tk4+sXbHTpJzI0v5/Cj5N6A=
github.com/iotexproject/go-fsm v1.0.0/go.mod h1:t3aYXtCCcQxyS7oduQZyuUpPnVI4ddFTwbAagHN7fT0=
github.com/iotexproject/go-p2p v0.3.5 h1:F71XxYQtR25youD+dCXnMgtfiCKGUFh8KDIqU7u5xOk=
Expand Down

0 comments on commit fd5a1a0

Please sign in to comment.