Skip to content

Commit 9e7fe2c

Browse files
authored
Merge pull request #6205 from onflow/ramtin/6189-geth-version-update
[Flow EVM] Geth version update
2 parents e2cf1b8 + 944eadf commit 9e7fe2c

28 files changed

+758
-402
lines changed

fvm/evm/debug/tracer.go

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -22,15 +22,15 @@ const (
2222

2323
type EVMTracer interface {
2424
WithBlockID(identifier flow.Identifier)
25-
TxTracer() tracers.Tracer
25+
TxTracer() *tracers.Tracer
2626
Collect(txID gethCommon.Hash)
2727
}
2828

2929
var _ EVMTracer = &CallTracer{}
3030

3131
type CallTracer struct {
3232
logger zerolog.Logger
33-
tracer tracers.Tracer
33+
tracer *tracers.Tracer
3434
uploader Uploader
3535
blockID flow.Identifier
3636
}
@@ -48,7 +48,7 @@ func NewEVMCallTracer(uploader Uploader, logger zerolog.Logger) (*CallTracer, er
4848
}, nil
4949
}
5050

51-
func (t *CallTracer) TxTracer() tracers.Tracer {
51+
func (t *CallTracer) TxTracer() *tracers.Tracer {
5252
return t.tracer
5353
}
5454

@@ -102,7 +102,7 @@ var _ EVMTracer = &nopTracer{}
102102

103103
type nopTracer struct{}
104104

105-
func (n nopTracer) TxTracer() tracers.Tracer {
105+
func (n nopTracer) TxTracer() *tracers.Tracer {
106106
return nil
107107
}
108108

fvm/evm/debug/tracer_test.go

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import (
66
"testing"
77

88
gethCommon "github.com/onflow/go-ethereum/common"
9+
gethTypes "github.com/onflow/go-ethereum/core/types"
910
"github.com/onflow/go-ethereum/core/vm"
1011
"github.com/rs/zerolog"
1112
"github.com/stretchr/testify/require"
@@ -34,15 +35,19 @@ func Test_CallTracer(t *testing.T) {
3435

3536
from := gethCommon.HexToAddress("0x01")
3637
to := gethCommon.HexToAddress("0x02")
38+
nonce := uint64(10)
39+
data := []byte{0x02, 0x04}
40+
amount := big.NewInt(1)
3741

3842
tr := tracer.TxTracer()
3943
require.NotNil(t, tr)
4044

41-
tr.CaptureStart(nil, from, to, true, []byte{0x01, 0x02}, 10, big.NewInt(1))
42-
tr.CaptureTxStart(100)
43-
tr.CaptureEnter(vm.ADD, from, to, []byte{0x02, 0x04}, 20, big.NewInt(2))
44-
tr.CaptureTxEnd(500)
45-
tr.CaptureEnd([]byte{0x02}, 200, nil)
45+
tr.OnEnter(0, 0, from, to, []byte{0x01, 0x02}, 10, big.NewInt(1))
46+
tx := gethTypes.NewTransaction(nonce, to, amount, 100, big.NewInt(10), data)
47+
tr.OnTxStart(nil, tx, from)
48+
tr.OnEnter(1, byte(vm.ADD), from, to, data, 20, big.NewInt(2))
49+
tr.OnTxEnd(&gethTypes.Receipt{}, nil)
50+
tr.OnExit(0, []byte{0x02}, 200, nil, false)
4651

4752
res, err = tr.GetResult()
4853
require.NoError(t, err)

fvm/evm/debug/uploader_test.go

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import (
1111

1212
"cloud.google.com/go/storage"
1313
gethCommon "github.com/onflow/go-ethereum/common"
14+
gethTypes "github.com/onflow/go-ethereum/core/types"
1415
"github.com/onflow/go-ethereum/core/vm"
1516
"github.com/rs/zerolog"
1617
"github.com/stretchr/testify/require"
@@ -64,9 +65,18 @@ func Test_TracerUploaderIntegration(t *testing.T) {
6465
tr := tracer.TxTracer()
6566
require.NotNil(t, tr)
6667

67-
tr.CaptureTxStart(1000)
68-
tr.CaptureEnter(vm.ADD, gethCommon.HexToAddress("0x01"), gethCommon.HexToAddress("0x02"), []byte{0x01}, 10, big.NewInt(2))
69-
tr.CaptureTxEnd(500)
68+
from := gethCommon.HexToAddress("0x01")
69+
to := gethCommon.HexToAddress("0x02")
70+
nonce := uint64(10)
71+
gas := uint64(100)
72+
gasPrice := big.NewInt(1)
73+
value := big.NewInt(2)
74+
input := []byte{0x01}
75+
tx := gethTypes.NewTransaction(nonce, to, value, gas, gasPrice, input)
76+
77+
tr.OnTxStart(nil, tx, from)
78+
tr.OnEnter(0, byte(vm.ADD), from, to, input, gas, value)
79+
tr.OnTxEnd(&gethTypes.Receipt{}, nil)
7080

7181
traces, err := tr.GetResult()
7282
require.NoError(t, err)

fvm/evm/emulator/config.go

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,7 @@ var DefaultChainConfig = &gethParams.ChainConfig{
7272
ShanghaiTime: &zero, // already on Shanghai
7373
CancunTime: &zero, // already on Cancun
7474
PragueTime: nil, // not on Prague
75+
VerkleTime: nil, // not on Verkle
7576
}
7677

7778
// Default config supports the dynamic fee structure (EIP-1559)
@@ -213,9 +214,11 @@ func WithRandom(rand *gethCommon.Hash) Option {
213214
}
214215

215216
// WithTransactionTracer sets a transaction tracer
216-
func WithTransactionTracer(tracer tracers.Tracer) Option {
217+
func WithTransactionTracer(tracer *tracers.Tracer) Option {
217218
return func(c *Config) *Config {
218-
c.EVMConfig.Tracer = tracer
219+
if tracer != nil {
220+
c.EVMConfig.Tracer = tracer.Hooks
221+
}
219222
return c
220223
}
221224
}

fvm/evm/emulator/emulator.go

Lines changed: 79 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,12 @@ import (
44
"errors"
55
"math/big"
66

7+
"github.com/holiman/uint256"
78
"github.com/onflow/atree"
9+
"github.com/onflow/go-ethereum/common"
810
gethCommon "github.com/onflow/go-ethereum/common"
911
gethCore "github.com/onflow/go-ethereum/core"
12+
"github.com/onflow/go-ethereum/core/tracing"
1013
gethTypes "github.com/onflow/go-ethereum/core/types"
1114
gethVM "github.com/onflow/go-ethereum/core/vm"
1215
gethCrypto "github.com/onflow/go-ethereum/crypto"
@@ -76,7 +79,8 @@ type ReadOnlyBlockView struct {
7679

7780
// BalanceOf returns the balance of the given address
7881
func (bv *ReadOnlyBlockView) BalanceOf(address types.Address) (*big.Int, error) {
79-
return bv.state.GetBalance(address.ToCommon()), nil
82+
bal := bv.state.GetBalance(address.ToCommon())
83+
return bal.ToBig(), nil
8084
}
8185

8286
// NonceOf returns the nonce of the given address
@@ -124,8 +128,6 @@ func (bl *BlockView) DirectCall(call *types.DirectCall) (*types.Result, error) {
124128
}
125129
fallthrough
126130
default:
127-
// TODO: when we support mutiple calls per block, we need
128-
// to update the value zero here for tx index
129131
return proc.runDirect(call.Message(), txHash, 0)
130132
}
131133
}
@@ -160,7 +162,7 @@ func (bl *BlockView) RunTransaction(
160162
if err != nil {
161163
return nil, err
162164
}
163-
// all commmit errors (StateDB errors) has to be returned
165+
// all commit errors (StateDB errors) has to be returned
164166
if err := proc.commit(true); err != nil {
165167
return nil, err
166168
}
@@ -197,7 +199,7 @@ func (bl *BlockView) BatchRunTransactions(txs []*gethTypes.Transaction) ([]*type
197199
if err != nil {
198200
return nil, err
199201
}
200-
// all commmit errors (StateDB errors) has to be returned
202+
// all commit errors (StateDB errors) has to be returned
201203
if err := proc.commit(false); err != nil {
202204
return nil, err
203205
}
@@ -322,6 +324,11 @@ func (proc *procedure) mintTo(
322324
return nil, types.ErrInvalidBalance
323325
}
324326

327+
value, overflow := uint256.FromBig(call.Value)
328+
if overflow {
329+
return nil, types.ErrInvalidBalance
330+
}
331+
325332
bridge := call.From.ToCommon()
326333

327334
// create bridge account if not exist
@@ -330,7 +337,7 @@ func (proc *procedure) mintTo(
330337
}
331338

332339
// add balance to the bridge account before transfer
333-
proc.state.AddBalance(bridge, call.Value)
340+
proc.state.AddBalance(bridge, value, tracing.BalanceIncreaseWithdrawal)
334341

335342
msg := call.Message()
336343
proc.evm.TxContext.Origin = msg.From
@@ -361,6 +368,11 @@ func (proc *procedure) withdrawFrom(
361368
return nil, types.ErrInvalidBalance
362369
}
363370

371+
value, overflow := uint256.FromBig(call.Value)
372+
if overflow {
373+
return nil, types.ErrInvalidBalance
374+
}
375+
364376
bridge := call.To.ToCommon()
365377

366378
// create bridge account if not exist
@@ -383,7 +395,7 @@ func (proc *procedure) withdrawFrom(
383395
}
384396

385397
// now deduct the balance from the bridge
386-
proc.state.SubBalance(bridge, call.Value)
398+
proc.state.SubBalance(bridge, value, tracing.BalanceIncreaseWithdrawal)
387399
// all commmit errors (StateDB errors) has to be returned
388400
return res, proc.commit(true)
389401
}
@@ -407,16 +419,25 @@ func (proc *procedure) deployAt(
407419
return nil, types.ErrInvalidBalance
408420
}
409421

422+
castedValue, overflow := uint256.FromBig(value)
423+
if overflow {
424+
return nil, types.ErrInvalidBalance
425+
}
426+
410427
res := &types.Result{
411428
TxType: types.DirectCallTxType,
412429
TxHash: txHash,
413430
}
414431

415-
addr := to.ToCommon()
432+
if proc.evm.Config.Tracer != nil {
433+
proc.captureTraceBegin(0, gethVM.CREATE2, caller.ToCommon(), to.ToCommon(), data, gasLimit, value)
434+
defer proc.captureTraceEnd(0, gasLimit, res.ReturnedData, res.Receipt(0), res.VMError)
435+
}
416436

437+
addr := to.ToCommon()
417438
// precheck 1 - check balance of the source
418439
if value.Sign() != 0 &&
419-
!proc.evm.Context.CanTransfer(proc.state, caller.ToCommon(), value) {
440+
!proc.evm.Context.CanTransfer(proc.state, caller.ToCommon(), castedValue) {
420441
res.SetValidationError(gethCore.ErrInsufficientFundsForTransfer)
421442
return res, nil
422443
}
@@ -445,26 +466,18 @@ func (proc *procedure) deployAt(
445466
proc.state,
446467
caller.ToCommon(),
447468
addr,
448-
value,
469+
uint256.MustFromBig(value),
449470
)
450471
}
451472

452-
if tracer := proc.evm.Config.Tracer; tracer != nil {
453-
tracer.CaptureStart(proc.evm, caller.ToCommon(), to.ToCommon(), true, data, gasLimit, value)
454-
455-
defer func() {
456-
tracer.CaptureEnd(res.ReturnedData, res.GasConsumed, res.VMError)
457-
}()
458-
}
459-
460473
// run code through interpreter
461474
// this would check for errors and computes the final bytes to be stored under account
462475
var err error
463476
inter := gethVM.NewEVMInterpreter(proc.evm)
464477
contract := gethVM.NewContract(
465478
gethVM.AccountRef(caller.ToCommon()),
466479
gethVM.AccountRef(addr),
467-
value,
480+
castedValue,
468481
gasLimit)
469482

470483
contract.SetCallCode(&addr, gethCrypto.Keccak256Hash(data), data)
@@ -629,6 +642,53 @@ func (proc *procedure) capturePrecompiledCalls() ([]byte, error) {
629642
return apc.Encode()
630643
}
631644

645+
func (proc *procedure) captureTraceBegin(
646+
depth int,
647+
typ gethVM.OpCode,
648+
from common.Address,
649+
to common.Address,
650+
input []byte,
651+
startGas uint64,
652+
value *big.Int) {
653+
tracer := proc.evm.Config.Tracer
654+
if tracer.OnTxStart != nil {
655+
tracer.OnTxStart(nil, gethTypes.NewTransaction(0, to, value, startGas, nil, input), from)
656+
}
657+
if tracer.OnEnter != nil {
658+
tracer.OnEnter(depth, byte(typ), from, to, input, startGas, value)
659+
}
660+
if tracer.OnGasChange != nil {
661+
tracer.OnGasChange(0, startGas, tracing.GasChangeCallInitialBalance)
662+
}
663+
}
664+
665+
func (proc *procedure) captureTraceEnd(
666+
depth int,
667+
startGas uint64,
668+
ret []byte,
669+
receipt *gethTypes.Receipt,
670+
err error,
671+
) {
672+
tracer := proc.evm.Config.Tracer
673+
leftOverGas := startGas - receipt.GasUsed
674+
if leftOverGas != 0 && tracer.OnGasChange != nil {
675+
tracer.OnGasChange(leftOverGas, 0, tracing.GasChangeCallLeftOverReturned)
676+
}
677+
var reverted bool
678+
if err != nil {
679+
reverted = true
680+
}
681+
if errors.Is(err, gethVM.ErrCodeStoreOutOfGas) {
682+
reverted = false
683+
}
684+
if tracer.OnExit != nil {
685+
tracer.OnExit(depth, ret, startGas-leftOverGas, gethVM.VMErrorFromErr(err), reverted)
686+
}
687+
if tracer.OnTxEnd != nil {
688+
tracer.OnTxEnd(receipt, err)
689+
}
690+
}
691+
632692
func AddOne64th(n uint64) uint64 {
633693
// NOTE: Go's integer division floors, but that is desirable here
634694
return n + (n / 64)

0 commit comments

Comments
 (0)