Skip to content

Commit

Permalink
Merge pull request #5236 from onflow/ramtin/5222-unify-balance-repres…
Browse files Browse the repository at this point in the history
…entation

[Flow EVM] use `big.Int` for any balance related fields
  • Loading branch information
ramtinms authored Jan 22, 2024
2 parents 82a344e + 42e05c5 commit e3f4d9c
Show file tree
Hide file tree
Showing 4 changed files with 26 additions and 26 deletions.
3 changes: 2 additions & 1 deletion fvm/evm/handler/blockstore_test.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package handler_test

import (
"math/big"
"testing"

"github.com/stretchr/testify/require"
Expand Down Expand Up @@ -32,7 +33,7 @@ func TestBlockStore(t *testing.T) {
require.Equal(t, expectedParentHash, bp.ParentBlockHash)

// commit block proposal
supply := uint64(100)
supply := big.NewInt(100)
bp.TotalSupply = supply
err = bs.CommitBlockProposal()
require.NoError(t, err)
Expand Down
36 changes: 16 additions & 20 deletions fvm/evm/handler/handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package handler

import (
"bytes"
"math/big"

gethTypes "github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/rlp"
Expand All @@ -14,14 +15,6 @@ import (

// ContractHandler is responsible for triggering calls to emulator, metering,
// event emission and updating the block
//
// TODO and Warning: currently database keeps a copy of roothash, and if after
// commiting the changes by the evm we want to revert in this code we need to reset that
// or we should always do all the checks and return before calling the emulator,
// after that should be only event emissions and computation usage updates.
// thats another reason we first check the computation limit before using.
// in the future we might benefit from a view style of access to db passed as
// a param to the emulator.
type ContractHandler struct {
flowTokenAddress common.Address
blockstore types.BlockStore
Expand Down Expand Up @@ -199,7 +192,7 @@ func (a *Account) Deposit(v *types.FLOWTokenVault) {
a.address,
v.Balance().ToAttoFlow(),
)
a.executeAndHandleCall(a.fch.getBlockContext(), call, v.Balance().ToAttoFlow().Uint64(), false)
a.executeAndHandleCall(a.fch.getBlockContext(), call, v.Balance().ToAttoFlow(), false)
}

// Withdraw deducts the balance from the account and
Expand All @@ -213,15 +206,16 @@ func (a *Account) Withdraw(b types.Balance) *types.FLOWTokenVault {
// check balance of flex vault
bp, err := a.fch.blockstore.BlockProposal()
handleError(err)
if b.ToAttoFlow().Uint64() > bp.TotalSupply {
// b > total supply
if b.ToAttoFlow().Cmp(bp.TotalSupply) == 1 {
handleError(types.ErrInsufficientTotalSupply)
}

call := types.NewWithdrawCall(
a.address,
b.ToAttoFlow(),
)
a.executeAndHandleCall(a.fch.getBlockContext(), call, b.ToAttoFlow().Uint64(), true)
a.executeAndHandleCall(a.fch.getBlockContext(), call, b.ToAttoFlow(), true)

return types.NewFlowTokenVault(b)
}
Expand All @@ -238,7 +232,7 @@ func (a *Account) Transfer(to types.Address, balance types.Balance) {
to,
balance.ToAttoFlow(),
)
a.executeAndHandleCall(ctx, call, 0, false)
a.executeAndHandleCall(ctx, call, nil, false)
}

// Deploy deploys a contract to the EVM environment
Expand All @@ -254,7 +248,7 @@ func (a *Account) Deploy(code types.Code, gaslimit types.GasLimit, balance types
uint64(gaslimit),
balance.ToAttoFlow(),
)
res := a.executeAndHandleCall(a.fch.getBlockContext(), call, 0, false)
res := a.executeAndHandleCall(a.fch.getBlockContext(), call, nil, false)
return types.Address(res.DeployedContractAddress)
}

Expand All @@ -272,14 +266,14 @@ func (a *Account) Call(to types.Address, data types.Data, gaslimit types.GasLimi
uint64(gaslimit),
balance.ToAttoFlow(),
)
res := a.executeAndHandleCall(a.fch.getBlockContext(), call, 0, false)
res := a.executeAndHandleCall(a.fch.getBlockContext(), call, nil, false)
return res.ReturnedValue
}

func (a *Account) executeAndHandleCall(
ctx types.BlockContext,
call *types.DirectCall,
totalSupplyDiff uint64,
totalSupplyDiff *big.Int,
deductSupplyDiff bool,
) *types.Result {
// execute the call
Expand All @@ -300,11 +294,13 @@ func (a *Account) executeAndHandleCall(
bp, err := a.fch.blockstore.BlockProposal()
handleError(err)
bp.AppendTxHash(callHash)
if deductSupplyDiff {
bp.TotalSupply -= totalSupplyDiff
} else {
// TODO: add overflow errors (even though we might never get there)
bp.TotalSupply += totalSupplyDiff
if totalSupplyDiff != nil {
if deductSupplyDiff {
bp.TotalSupply = new(big.Int).Sub(bp.TotalSupply, totalSupplyDiff)
} else {
bp.TotalSupply = new(big.Int).Add(bp.TotalSupply, totalSupplyDiff)
}

}

// emit events
Expand Down
9 changes: 6 additions & 3 deletions fvm/evm/types/block.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package types

import (
"math/big"

gethCommon "github.com/ethereum/go-ethereum/common"
gethTypes "github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/rlp"
Expand All @@ -15,8 +17,8 @@ type Block struct {
// Height returns the height of this block
Height uint64

// holds the total amount of the native token deposited in the evm side.
TotalSupply uint64
// holds the total amount of the native token deposited in the evm side. (in attoflow)
TotalSupply *big.Int

// ReceiptRoot returns the root hash of the receipts emitted in this block
ReceiptRoot gethCommon.Hash
Expand All @@ -42,7 +44,7 @@ func (b *Block) AppendTxHash(txHash gethCommon.Hash) {
}

// NewBlock constructs a new block
func NewBlock(height, uuidIndex, totalSupply uint64,
func NewBlock(height, uuidIndex uint64, totalSupply *big.Int,
stateRoot, receiptRoot gethCommon.Hash,
txHashes []gethCommon.Hash,
) *Block {
Expand All @@ -65,5 +67,6 @@ func NewBlockFromBytes(encoded []byte) (*Block, error) {
var GenesisBlock = &Block{
ParentBlockHash: gethCommon.Hash{},
Height: uint64(0),
TotalSupply: new(big.Int),
ReceiptRoot: gethTypes.EmptyRootHash,
}
4 changes: 2 additions & 2 deletions fvm/evm/types/events.go
Original file line number Diff line number Diff line change
Expand Up @@ -169,7 +169,7 @@ var blockExecutedEventCadenceType = &cadence.EventType{
Fields: []cadence.Field{
cadence.NewField("height", cadence.UInt64Type{}),
cadence.NewField("hash", cadence.StringType{}),
cadence.NewField("totalSupply", cadence.UInt64Type{}),
cadence.NewField("totalSupply", cadence.IntType{}),
cadence.NewField("parentHash", cadence.StringType{}),
cadence.NewField("receiptRoot", cadence.StringType{}),
cadence.NewField(
Expand Down Expand Up @@ -197,7 +197,7 @@ func (p *BlockExecutedEventPayload) CadenceEvent() (cadence.Event, error) {
fields := []cadence.Value{
cadence.NewUInt64(p.Block.Height),
cadence.String(blockHash.String()),
cadence.NewUInt64(p.Block.TotalSupply),
cadence.NewIntFromBig(p.Block.TotalSupply),
cadence.String(p.Block.ParentBlockHash.String()),
cadence.String(p.Block.ReceiptRoot.String()),
cadence.NewArray(hashes).WithType(cadence.NewVariableSizedArrayType(cadence.StringType{})),
Expand Down

0 comments on commit e3f4d9c

Please sign in to comment.