Skip to content

Commit

Permalink
Merge branch 'master' into bastian/change-key-index-to-uint32
Browse files Browse the repository at this point in the history
  • Loading branch information
turbolent committed Jul 16, 2024
2 parents a45488b + e2cf1b8 commit afefbf5
Show file tree
Hide file tree
Showing 19 changed files with 533 additions and 192 deletions.
2 changes: 1 addition & 1 deletion engine/execution/state/bootstrap/bootstrap_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ func TestBootstrapLedger(t *testing.T) {
}

func TestBootstrapLedger_ZeroTokenSupply(t *testing.T) {
expectedStateCommitmentBytes, _ := hex.DecodeString("65c248c6ed6f6b0fc6fee035a2eb04a30ff8dbe776e1f8bab0de3339badc246a")
expectedStateCommitmentBytes, _ := hex.DecodeString("8084ec7253e5de8fa98c501f4acbcf448aafea3d9d11760d6982bb813926f4ef")
expectedStateCommitment, err := flow.ToStateCommitment(expectedStateCommitmentBytes)
require.NoError(t, err)

Expand Down
2 changes: 1 addition & 1 deletion fvm/evm/emulator/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ var DefaultChainConfig = &gethParams.ChainConfig{
// Fork scheduling based on timestamps
ShanghaiTime: &zero, // already on Shanghai
CancunTime: &zero, // already on Cancun
PragueTime: &zero, // already on Prague
PragueTime: nil, // not on Prague
}

// Default config supports the dynamic fee structure (EIP-1559)
Expand Down
1 change: 0 additions & 1 deletion fvm/evm/evm_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -155,7 +155,6 @@ func TestEVMRun(t *testing.T) {
require.Equal(t, innerTxBytes, txPayload)
require.Equal(t, uint16(types.ErrCodeNoError), txEventPayload.ErrorCode)
require.Equal(t, uint16(0), txEventPayload.Index)
require.Equal(t, blockEventPayload.Hash, txEventPayload.BlockHash)
require.Equal(t, blockEventPayload.Height, txEventPayload.BlockHeight)
require.Equal(t, blockEventPayload.TotalGasUsed, txEventPayload.GasConsumed)
require.Equal(t, uint64(43785), blockEventPayload.TotalGasUsed)
Expand Down
85 changes: 54 additions & 31 deletions fvm/evm/handler/blockstore.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,15 +11,15 @@ import (
)

const (
BlockHashListCapacity = 16
BlockStoreLatestBlockKey = "LatestBlock"
BlockStoreBlockHashesKey = "LatestBlockHashes"
BlockHashListCapacity = 16
BlockStoreLatestBlockKey = "LatestBlock"
BlockStoreLatestBlockProposalKey = "LatestBlockProposal"
BlockStoreBlockHashesKey = "LatestBlockHashes"
)

type BlockStore struct {
backend types.Backend
rootAddress flow.Address
blockProposal *types.Block
backend types.Backend
rootAddress flow.Address
}

var _ types.BlockStore = &BlockStore{}
Expand All @@ -33,11 +33,17 @@ func NewBlockStore(backend types.Backend, rootAddress flow.Address) *BlockStore
}

// BlockProposal returns the block proposal to be updated by the handler
func (bs *BlockStore) BlockProposal() (*types.Block, error) {
if bs.blockProposal != nil {
return bs.blockProposal, nil
func (bs *BlockStore) BlockProposal() (*types.BlockProposal, error) {
// first fetch it from the storage
data, err := bs.backend.GetValue(bs.rootAddress[:], []byte(BlockStoreLatestBlockProposalKey))
if err != nil {
return nil, types.NewFatalError(err)
}
if len(data) != 0 {
return types.NewBlockProposalFromBytes(data)
}

// if available construct a new one
cadenceHeight, err := bs.backend.GetCurrentBlockHeight()
if err != nil {
return nil, err
Expand Down Expand Up @@ -65,25 +71,43 @@ func (bs *BlockStore) BlockProposal() (*types.Block, error) {
// expect timestamps in unix seconds so we convert here
timestamp := uint64(cadenceBlock.Timestamp / int64(time.Second))

bs.blockProposal = types.NewBlock(
blockProposal := types.NewBlockProposal(
parentHash,
lastExecutedBlock.Height+1,
timestamp,
lastExecutedBlock.TotalSupply,
gethCommon.Hash{},
make([]gethCommon.Hash, 0),
)
return bs.blockProposal, nil
return blockProposal, nil
}

// CommitBlockProposal commits the block proposal to the chain
func (bs *BlockStore) CommitBlockProposal() error {
bp, err := bs.BlockProposal()
// UpdateBlockProposal updates the block proposal
func (bs *BlockStore) UpdateBlockProposal(bp *types.BlockProposal) error {
blockProposalBytes, err := bp.ToBytes()
if err != nil {
return err
return types.NewFatalError(err)
}

blockBytes, err := bp.ToBytes()
return bs.backend.SetValue(
bs.rootAddress[:],
[]byte(BlockStoreLatestBlockProposalKey),
blockProposalBytes,
)
}

func (bs *BlockStore) ResetBlockProposal() error {
return bs.backend.SetValue(
bs.rootAddress[:],
[]byte(BlockStoreLatestBlockProposalKey),
nil,
)
}

// CommitBlockProposal commits the block proposal to the chain
func (bs *BlockStore) CommitBlockProposal(bp *types.BlockProposal) error {
// populate receipt root hash
bp.PopulateReceiptRoot()

blockBytes, err := bp.Block.ToBytes()
if err != nil {
return types.NewFatalError(err)
}
Expand All @@ -93,18 +117,21 @@ func (bs *BlockStore) CommitBlockProposal() error {
return err
}

err = bs.updateBlockHashList(bs.blockProposal)
hash, err := bp.Block.Hash()
if err != nil {
return err
}

bs.blockProposal = nil
return nil
}
err = bs.updateBlockHashList(bp.Block.Height, hash)
if err != nil {
return err
}

err = bs.ResetBlockProposal()
if err != nil {
return err
}

// ResetBlockProposal resets the block proposal
func (bs *BlockStore) ResetBlockProposal() error {
bs.blockProposal = nil
return nil
}

Expand Down Expand Up @@ -143,16 +170,12 @@ func (bs *BlockStore) getBlockHashList() (*types.BlockHashList, error) {
return types.NewBlockHashListFromEncoded(data)
}

func (bs *BlockStore) updateBlockHashList(block *types.Block) error {
func (bs *BlockStore) updateBlockHashList(height uint64, hash gethCommon.Hash) error {
bhl, err := bs.getBlockHashList()
if err != nil {
return err
}
hash, err := block.Hash()
if err != nil {
return err
}
err = bhl.Push(block.Height, hash)
err = bhl.Push(height, hash)
if err != nil {
return err
}
Expand Down
59 changes: 59 additions & 0 deletions fvm/evm/handler/blockstore_benchmark_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
package handler_test

import (
"testing"
"time"

"github.com/stretchr/testify/require"

"github.com/onflow/flow-go/fvm/evm/handler"
"github.com/onflow/flow-go/fvm/evm/testutils"
"github.com/onflow/flow-go/model/flow"
)

func BenchmarkProposalGrowth(b *testing.B) { benchmarkBlockProposalGrowth(b, 1000) }

func benchmarkBlockProposalGrowth(b *testing.B, txCounts int) {
testutils.RunWithTestBackend(b, func(backend *testutils.TestBackend) {
testutils.RunWithTestFlowEVMRootAddress(b, backend, func(rootAddr flow.Address) {

bs := handler.NewBlockStore(backend, rootAddr)
for i := 0; i < txCounts; i++ {
bp, err := bs.BlockProposal()
require.NoError(b, err)
res := testutils.RandomResultFixture(b)
bp.AppendTransaction(res)
err = bs.UpdateBlockProposal(bp)
require.NoError(b, err)
}

// check the impact of updating block proposal after x number of transactions
backend.ResetStats()
startTime := time.Now()
bp, err := bs.BlockProposal()
require.NoError(b, err)
res := testutils.RandomResultFixture(b)
bp.AppendTransaction(res)
err = bs.UpdateBlockProposal(bp)
require.NoError(b, err)

b.ReportMetric(float64(time.Since(startTime).Nanoseconds()), "proposal_update_time_ns")
b.ReportMetric(float64(backend.TotalBytesRead()), "proposal_update_bytes_read")
b.ReportMetric(float64(backend.TotalBytesWritten()), "proposal_update_bytes_written")
b.ReportMetric(float64(backend.TotalStorageSize()), "proposal_update_total_storage_size")

// check the impact of block commit after x number of transactions
backend.ResetStats()
startTime = time.Now()
bp, err = bs.BlockProposal()
require.NoError(b, err)
err = bs.CommitBlockProposal(bp)
require.NoError(b, err)

b.ReportMetric(float64(time.Since(startTime).Nanoseconds()), "block_commit_time_ns")
b.ReportMetric(float64(backend.TotalBytesRead()), "block_commit_bytes_read")
b.ReportMetric(float64(backend.TotalBytesWritten()), "block_commit_bytes_written")
b.ReportMetric(float64(backend.TotalStorageSize()), "block_commit_total_storage_size")
})
})
}
52 changes: 40 additions & 12 deletions fvm/evm/handler/blockstore_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,34 +20,59 @@ func TestBlockStore(t *testing.T) {
testutils.RunWithTestFlowEVMRootAddress(t, backend, func(root flow.Address) {
bs := handler.NewBlockStore(backend, root)

// check gensis block
// check the Genesis block
b, err := bs.LatestBlock()
require.NoError(t, err)
require.Equal(t, types.GenesisBlock, b)
h, err := bs.BlockHash(0)
require.NoError(t, err)
require.Equal(t, types.GenesisBlockHash, h)

// test block proposal from genesis
// test block proposal construction from the Genesis block
bp, err := bs.BlockProposal()
require.NoError(t, err)
require.Equal(t, uint64(1), bp.Height)
expectedParentHash, err := types.GenesisBlock.Hash()
require.NoError(t, err)
require.Equal(t, expectedParentHash, bp.ParentBlockHash)

// commit block proposal
// if no commit and again block proposal call should return the same
retbp, err := bs.BlockProposal()
require.NoError(t, err)
require.Equal(t, bp, retbp)

// update the block proposal
bp.TotalGasUsed += 100
err = bs.UpdateBlockProposal(bp)
require.NoError(t, err)

// reset the bs and check if it still return the block proposal
bs = handler.NewBlockStore(backend, root)
retbp, err = bs.BlockProposal()
require.NoError(t, err)
require.Equal(t, bp, retbp)

// update the block proposal again
supply := big.NewInt(100)
bp.TotalSupply = supply
err = bs.CommitBlockProposal()
err = bs.UpdateBlockProposal(bp)
require.NoError(t, err)
b, err = bs.LatestBlock()
// this should still return the gensis block
retb, err := bs.LatestBlock()
require.NoError(t, err)
require.Equal(t, supply, b.TotalSupply)
require.Equal(t, uint64(1), b.Height)
bp, err = bs.BlockProposal()
require.Equal(t, types.GenesisBlock, retb)

// commit the changes
err = bs.CommitBlockProposal(bp)
require.NoError(t, err)
require.Equal(t, uint64(2), bp.Height)
retb, err = bs.LatestBlock()
require.NoError(t, err)
require.Equal(t, supply, retb.TotalSupply)
require.Equal(t, uint64(1), retb.Height)

retbp, err = bs.BlockProposal()
require.NoError(t, err)
require.Equal(t, uint64(2), retbp.Height)

// check block hashes
// genesis
Expand All @@ -58,7 +83,7 @@ func TestBlockStore(t *testing.T) {
// block 1
h, err = bs.BlockHash(1)
require.NoError(t, err)
expected, err := b.Hash()
expected, err := bp.Hash()
require.NoError(t, err)
require.Equal(t, expected, h)

Expand Down Expand Up @@ -147,6 +172,9 @@ func TestBlockStore_AddedTimestamp(t *testing.T) {
err = backend.SetValue(root[:], []byte(handler.BlockStoreLatestBlockKey), blockBytes2)
require.NoError(t, err)

err = bs.ResetBlockProposal()
require.NoError(t, err)

block2, err := bs.LatestBlock()
require.NoError(t, err)

Expand All @@ -160,10 +188,10 @@ func TestBlockStore_AddedTimestamp(t *testing.T) {
bp, err := bs.BlockProposal()
require.NoError(t, err)

blockBytes, err = bp.ToBytes()
blockBytes3, err := gethRLP.EncodeToBytes(bp.Block)
require.NoError(t, err)

err = backend.SetValue(root[:], []byte(handler.BlockStoreLatestBlockKey), blockBytes)
err = backend.SetValue(root[:], []byte(handler.BlockStoreLatestBlockKey), blockBytes3)
require.NoError(t, err)

bb, err := bs.LatestBlock()
Expand Down
Loading

0 comments on commit afefbf5

Please sign in to comment.