@@ -4,9 +4,12 @@ import (
4
4
"errors"
5
5
"math/big"
6
6
7
+ "github.com/holiman/uint256"
7
8
"github.com/onflow/atree"
9
+ "github.com/onflow/go-ethereum/common"
8
10
gethCommon "github.com/onflow/go-ethereum/common"
9
11
gethCore "github.com/onflow/go-ethereum/core"
12
+ "github.com/onflow/go-ethereum/core/tracing"
10
13
gethTypes "github.com/onflow/go-ethereum/core/types"
11
14
gethVM "github.com/onflow/go-ethereum/core/vm"
12
15
gethCrypto "github.com/onflow/go-ethereum/crypto"
@@ -76,7 +79,8 @@ type ReadOnlyBlockView struct {
76
79
77
80
// BalanceOf returns the balance of the given address
78
81
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
80
84
}
81
85
82
86
// NonceOf returns the nonce of the given address
@@ -124,8 +128,6 @@ func (bl *BlockView) DirectCall(call *types.DirectCall) (*types.Result, error) {
124
128
}
125
129
fallthrough
126
130
default :
127
- // TODO: when we support mutiple calls per block, we need
128
- // to update the value zero here for tx index
129
131
return proc .runDirect (call .Message (), txHash , 0 )
130
132
}
131
133
}
@@ -160,7 +162,7 @@ func (bl *BlockView) RunTransaction(
160
162
if err != nil {
161
163
return nil , err
162
164
}
163
- // all commmit errors (StateDB errors) has to be returned
165
+ // all commit errors (StateDB errors) has to be returned
164
166
if err := proc .commit (true ); err != nil {
165
167
return nil , err
166
168
}
@@ -197,7 +199,7 @@ func (bl *BlockView) BatchRunTransactions(txs []*gethTypes.Transaction) ([]*type
197
199
if err != nil {
198
200
return nil , err
199
201
}
200
- // all commmit errors (StateDB errors) has to be returned
202
+ // all commit errors (StateDB errors) has to be returned
201
203
if err := proc .commit (false ); err != nil {
202
204
return nil , err
203
205
}
@@ -322,6 +324,11 @@ func (proc *procedure) mintTo(
322
324
return nil , types .ErrInvalidBalance
323
325
}
324
326
327
+ value , overflow := uint256 .FromBig (call .Value )
328
+ if overflow {
329
+ return nil , types .ErrInvalidBalance
330
+ }
331
+
325
332
bridge := call .From .ToCommon ()
326
333
327
334
// create bridge account if not exist
@@ -330,7 +337,7 @@ func (proc *procedure) mintTo(
330
337
}
331
338
332
339
// add balance to the bridge account before transfer
333
- proc .state .AddBalance (bridge , call . Value )
340
+ proc .state .AddBalance (bridge , value , tracing . BalanceIncreaseWithdrawal )
334
341
335
342
msg := call .Message ()
336
343
proc .evm .TxContext .Origin = msg .From
@@ -361,6 +368,11 @@ func (proc *procedure) withdrawFrom(
361
368
return nil , types .ErrInvalidBalance
362
369
}
363
370
371
+ value , overflow := uint256 .FromBig (call .Value )
372
+ if overflow {
373
+ return nil , types .ErrInvalidBalance
374
+ }
375
+
364
376
bridge := call .To .ToCommon ()
365
377
366
378
// create bridge account if not exist
@@ -383,7 +395,7 @@ func (proc *procedure) withdrawFrom(
383
395
}
384
396
385
397
// now deduct the balance from the bridge
386
- proc .state .SubBalance (bridge , call . Value )
398
+ proc .state .SubBalance (bridge , value , tracing . BalanceIncreaseWithdrawal )
387
399
// all commmit errors (StateDB errors) has to be returned
388
400
return res , proc .commit (true )
389
401
}
@@ -407,16 +419,25 @@ func (proc *procedure) deployAt(
407
419
return nil , types .ErrInvalidBalance
408
420
}
409
421
422
+ castedValue , overflow := uint256 .FromBig (value )
423
+ if overflow {
424
+ return nil , types .ErrInvalidBalance
425
+ }
426
+
410
427
res := & types.Result {
411
428
TxType : types .DirectCallTxType ,
412
429
TxHash : txHash ,
413
430
}
414
431
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
+ }
416
436
437
+ addr := to .ToCommon ()
417
438
// precheck 1 - check balance of the source
418
439
if value .Sign () != 0 &&
419
- ! proc .evm .Context .CanTransfer (proc .state , caller .ToCommon (), value ) {
440
+ ! proc .evm .Context .CanTransfer (proc .state , caller .ToCommon (), castedValue ) {
420
441
res .SetValidationError (gethCore .ErrInsufficientFundsForTransfer )
421
442
return res , nil
422
443
}
@@ -445,26 +466,18 @@ func (proc *procedure) deployAt(
445
466
proc .state ,
446
467
caller .ToCommon (),
447
468
addr ,
448
- value ,
469
+ uint256 . MustFromBig ( value ) ,
449
470
)
450
471
}
451
472
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
-
460
473
// run code through interpreter
461
474
// this would check for errors and computes the final bytes to be stored under account
462
475
var err error
463
476
inter := gethVM .NewEVMInterpreter (proc .evm )
464
477
contract := gethVM .NewContract (
465
478
gethVM .AccountRef (caller .ToCommon ()),
466
479
gethVM .AccountRef (addr ),
467
- value ,
480
+ castedValue ,
468
481
gasLimit )
469
482
470
483
contract .SetCallCode (& addr , gethCrypto .Keccak256Hash (data ), data )
@@ -629,6 +642,53 @@ func (proc *procedure) capturePrecompiledCalls() ([]byte, error) {
629
642
return apc .Encode ()
630
643
}
631
644
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
+
632
692
func AddOne64th (n uint64 ) uint64 {
633
693
// NOTE: Go's integer division floors, but that is desirable here
634
694
return n + (n / 64 )
0 commit comments