Skip to content

Commit 76f5918

Browse files
author
Or Neeman
authored
Go back to using the transfer's sender in Tobin tax calculation. (#1611)
Even though the Tobin tax calculation doesn't depend on the sender, the change (in PR #1465) of the sender from the transaction's sender to the zero account led to a bad block error (i.e. a hard fork change). This was due to a conjunction of factors including the upstream implementation of EIP-161 not being quite correct for the case of Celo (because of the existence of system EVM calls made from celo-blockchain). This commit reverts the change, by adding an `ExecuteFrom()` method to the EVMRunner type.
1 parent 5083112 commit 76f5918

File tree

5 files changed

+35
-7
lines changed

5 files changed

+35
-7
lines changed

contracts/reserve/tobin_tax.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ func TobinTax(vmRunner vm.EVMRunner, sender common.Address) (tax Ratio, reserveA
3131
return Ratio{}, common.ZeroAddress, err
3232
}
3333

34-
ret, err := vmRunner.Execute(reserveAddress, params.TobinTaxFunctionSelector, params.MaxGasForGetOrComputeTobinTax, big.NewInt(0))
34+
ret, err := vmRunner.ExecuteFrom(sender, reserveAddress, params.TobinTaxFunctionSelector, params.MaxGasForGetOrComputeTobinTax, big.NewInt(0))
3535
if err != nil {
3636
return Ratio{}, common.ZeroAddress, err
3737
}

contracts/testutil/fail_runner.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,10 @@ func (fvm FailingVmRunner) Execute(recipient common.Address, input []byte, gas u
1818
return nil, ErrFailingRunner
1919
}
2020

21+
func (fvm FailingVmRunner) ExecuteFrom(sender, recipient common.Address, input []byte, gas uint64, value *big.Int) (ret []byte, err error) {
22+
return nil, ErrFailingRunner
23+
}
24+
2125
func (fvm FailingVmRunner) Query(recipient common.Address, input []byte, gas uint64) (ret []byte, err error) {
2226
return nil, ErrFailingRunner
2327
}

contracts/testutil/runner.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,11 @@ func (ev *MockEVMRunner) Execute(recipient common.Address, input []byte, gas uin
4545
return mock.Call(input)
4646
}
4747

48+
func (ev *MockEVMRunner) ExecuteFrom(sender, recipient common.Address, input []byte, gas uint64, value *big.Int) (ret []byte, err error) {
49+
// No difference necessary for the mock runner between Execute() and ExecuteFrom()
50+
return ev.Execute(recipient, input, gas, value)
51+
}
52+
4853
func (ev *MockEVMRunner) Query(recipient common.Address, input []byte, gas uint64) (ret []byte, err error) {
4954
mock, ok := ev.contracts[recipient]
5055
if !ok {

core/vm/interface.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,11 @@ type EVMRunner interface {
8989
// It can be seen as a message (input,value) from sender to recipient that returns `ret`
9090
Execute(recipient common.Address, input []byte, gas uint64, value *big.Int) (ret []byte, err error)
9191

92+
// ExecuteFrom is like Execute, but lets you specify the sender to use for the EVM call.
93+
// It exists only for use in the Tobin tax calculation done as part of TobinTransfer, because that
94+
// originally used the transaction's sender instead of the zero address.
95+
ExecuteFrom(sender, recipient common.Address, input []byte, gas uint64, value *big.Int) (ret []byte, err error)
96+
9297
// Query performs a read operation over the runner's state
9398
// It can be seen as a message (input,value) from sender to recipient that returns `ret`
9499
Query(recipient common.Address, input []byte, gas uint64) (ret []byte, err error)

core/vm/vmcontext/runner.go

Lines changed: 20 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ type evmRunnerContext interface {
2525
}
2626

2727
type evmRunner struct {
28-
newEVM func() *vm.EVM
28+
newEVM func(from common.Address) *vm.EVM
2929
state vm.StateDB
3030

3131
dontMeterGas bool
@@ -35,26 +35,35 @@ func NewEVMRunner(chain evmRunnerContext, header *types.Header, state vm.StateDB
3535

3636
return &evmRunner{
3737
state: state,
38-
newEVM: func() *vm.EVM {
38+
newEVM: func(from common.Address) *vm.EVM {
3939
// The EVM Context requires a msg, but the actual field values don't really matter for this case.
40-
// Putting in zero values.
41-
context := New(VMAddress, common.Big0, header, chain, nil)
40+
// Putting in zero values for gas price and tx fee recipient
41+
context := New(from, common.Big0, header, chain, nil)
4242
return vm.NewEVM(context, state, chain.Config(), *chain.GetVMConfig())
4343
},
4444
}
4545
}
4646

4747
func (ev *evmRunner) Execute(recipient common.Address, input []byte, gas uint64, value *big.Int) (ret []byte, err error) {
48-
evm := ev.newEVM()
48+
evm := ev.newEVM(VMAddress)
4949
if ev.dontMeterGas {
5050
evm.StopGasMetering()
5151
}
5252
ret, _, err = evm.Call(vm.AccountRef(evm.Origin), recipient, input, gas, value)
5353
return ret, err
5454
}
5555

56+
func (ev *evmRunner) ExecuteFrom(sender, recipient common.Address, input []byte, gas uint64, value *big.Int) (ret []byte, err error) {
57+
evm := ev.newEVM(sender)
58+
if ev.dontMeterGas {
59+
evm.StopGasMetering()
60+
}
61+
ret, _, err = evm.Call(vm.AccountRef(sender), recipient, input, gas, value)
62+
return ret, err
63+
}
64+
5665
func (ev *evmRunner) Query(recipient common.Address, input []byte, gas uint64) (ret []byte, err error) {
57-
evm := ev.newEVM()
66+
evm := ev.newEVM(VMAddress)
5867
if ev.dontMeterGas {
5968
evm.StopGasMetering()
6069
}
@@ -85,6 +94,11 @@ func (sev *SharedEVMRunner) Execute(recipient common.Address, input []byte, gas
8594
return ret, err
8695
}
8796

97+
func (sev *SharedEVMRunner) ExecuteFrom(sender, recipient common.Address, input []byte, gas uint64, value *big.Int) (ret []byte, err error) {
98+
ret, _, err = sev.Call(vm.AccountRef(sender), recipient, input, gas, value)
99+
return ret, err
100+
}
101+
88102
func (sev *SharedEVMRunner) Query(recipient common.Address, input []byte, gas uint64) (ret []byte, err error) {
89103
ret, _, err = sev.StaticCall(vm.AccountRef(VMAddress), recipient, input, gas)
90104
return ret, err

0 commit comments

Comments
 (0)