Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Flow EVM] use big.Int for any balance related fields #5236

Merged
merged 11 commits into from
Jan 22, 2024
Merged
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
8 changes: 5 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 Down
2 changes: 1 addition & 1 deletion fvm/evm/types/events.go
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,7 @@ func (p *BlockExecutedEventPayload) CadenceEvent() (cadence.Event, error) {

fields := []cadence.Value{
cadence.NewUInt64(p.Block.Height),
cadence.NewUInt64(p.Block.TotalSupply),
cadence.String(p.Block.TotalSupply.String()),
ramtinms marked this conversation as resolved.
Show resolved Hide resolved
cadence.String(p.Block.ReceiptRoot.String()),
cadence.String(p.Block.ParentBlockHash.String()),
cadence.NewArray(hashes).WithType(cadence.NewVariableSizedArrayType(cadence.StringType{})),
Expand Down
Loading