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

create new codec with correct type #752

Merged
merged 3 commits into from
Jan 17, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion plugin/evm/atomic/sync/atomic_sync_extender.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ func NewAtomicSyncExtender(backend interfaces.AtomicBackend, stateSyncRequestSiz
}

func (a *AtomicSyncExtender) Sync(ctx context.Context, client syncclient.LeafClient, verDB *versiondb.Database, syncSummary message.Syncable) error {
atomicSyncSummary, ok := syncSummary.(*AtomicBlockSyncSummary)
atomicSyncSummary, ok := syncSummary.(*AtomicSyncSummary)
if !ok {
return fmt.Errorf("expected *AtomicBlockSyncSummary, got %T", syncSummary)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@ import (
"context"
"fmt"

"github.com/ava-labs/avalanchego/codec"
"github.com/ava-labs/avalanchego/ids"
"github.com/ava-labs/coreth/plugin/evm/atomic"
"github.com/ava-labs/coreth/plugin/evm/message"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/crypto"
Expand All @@ -17,13 +17,26 @@ import (
)

var (
_ message.Syncable = (*AtomicBlockSyncSummary)(nil)
_ message.Syncable = (*AtomicSyncSummary)(nil)
_ message.SyncableParser = (*AtomicSyncSummaryParser)(nil)
)

// AtomicBlockSyncSummary provides the information necessary to sync a node starting
// codecWithAtomicSync is the codec manager that contains the codec for AtomicBlockSyncSummary and
// other message types that are used in the network protocol. This is to ensure that the codec
// version is consistent across all message types and includes the codec for AtomicBlockSyncSummary.
var codecWithAtomicSync codec.Manager

func init() {
var err error
codecWithAtomicSync, err = message.NewCodec(AtomicSyncSummary{})
if err != nil {
panic(fmt.Errorf("failed to create codec manager: %w", err))
}
}

// AtomicSyncSummary provides the information necessary to sync a node starting
// at the given block.
type AtomicBlockSyncSummary struct {
type AtomicSyncSummary struct {
BlockNumber uint64 `serialize:"true"`
BlockHash common.Hash `serialize:"true"`
BlockRoot common.Hash `serialize:"true"`
Expand All @@ -34,19 +47,15 @@ type AtomicBlockSyncSummary struct {
acceptImpl message.AcceptImplFn
}

func init() {
message.SyncSummaryType = &AtomicBlockSyncSummary{}
}

type AtomicSyncSummaryParser struct{}

func NewAtomicSyncSummaryParser() *AtomicSyncSummaryParser {
return &AtomicSyncSummaryParser{}
}

func (a *AtomicSyncSummaryParser) ParseFromBytes(summaryBytes []byte, acceptImpl message.AcceptImplFn) (message.Syncable, error) {
summary := AtomicBlockSyncSummary{}
if codecVersion, err := atomic.Codec.Unmarshal(summaryBytes, &summary); err != nil {
summary := AtomicSyncSummary{}
if codecVersion, err := codecWithAtomicSync.Unmarshal(summaryBytes, &summary); err != nil {
return nil, fmt.Errorf("failed to parse syncable summary: %w", err)
} else if codecVersion != message.Version {
return nil, fmt.Errorf("failed to parse syncable summary due to unexpected codec version (got %d, expected %d)", codecVersion, message.Version)
Expand All @@ -62,14 +71,14 @@ func (a *AtomicSyncSummaryParser) ParseFromBytes(summaryBytes []byte, acceptImpl
return &summary, nil
}

func NewAtomicSyncSummary(blockHash common.Hash, blockNumber uint64, blockRoot common.Hash, atomicRoot common.Hash) (*AtomicBlockSyncSummary, error) {
summary := AtomicBlockSyncSummary{
func NewAtomicSyncSummary(blockHash common.Hash, blockNumber uint64, blockRoot common.Hash, atomicRoot common.Hash) (*AtomicSyncSummary, error) {
summary := AtomicSyncSummary{
BlockNumber: blockNumber,
BlockHash: blockHash,
BlockRoot: blockRoot,
AtomicRoot: atomicRoot,
}
bytes, err := atomic.Codec.Marshal(message.Version, &summary)
bytes, err := codecWithAtomicSync.Marshal(message.Version, &summary)
if err != nil {
return nil, fmt.Errorf("failed to marshal syncable summary: %w", err)
}
Expand All @@ -84,35 +93,31 @@ func NewAtomicSyncSummary(blockHash common.Hash, blockNumber uint64, blockRoot c
return &summary, nil
}

func (a *AtomicBlockSyncSummary) GetBlockNumber() uint64 {
return a.BlockNumber
}

func (a *AtomicBlockSyncSummary) GetBlockHash() common.Hash {
func (a *AtomicSyncSummary) GetBlockHash() common.Hash {
return a.BlockHash
}

func (a *AtomicBlockSyncSummary) GetBlockRoot() common.Hash {
func (a *AtomicSyncSummary) GetBlockRoot() common.Hash {
return a.BlockRoot
}

func (a *AtomicBlockSyncSummary) Bytes() []byte {
func (a *AtomicSyncSummary) Bytes() []byte {
return a.bytes
}

func (a *AtomicBlockSyncSummary) Height() uint64 {
func (a *AtomicSyncSummary) Height() uint64 {
return a.BlockNumber
}

func (a *AtomicBlockSyncSummary) ID() ids.ID {
func (a *AtomicSyncSummary) ID() ids.ID {
return a.summaryID
}

func (a *AtomicBlockSyncSummary) String() string {
func (a *AtomicSyncSummary) String() string {
return fmt.Sprintf("AtomicBlockSyncSummary(BlockHash=%s, BlockNumber=%d, BlockRoot=%s, AtomicRoot=%s)", a.BlockHash, a.BlockNumber, a.BlockRoot, a.AtomicRoot)
}

func (a *AtomicBlockSyncSummary) Accept(context.Context) (block.StateSyncMode, error) {
func (a *AtomicSyncSummary) Accept(context.Context) (block.StateSyncMode, error) {
if a.acceptImpl == nil {
return block.StateSyncSkipped, fmt.Errorf("accept implementation not specified for summary: %s", a)
}
Expand Down
46 changes: 46 additions & 0 deletions plugin/evm/atomic/sync/atomic_sync_summary_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
// (c) 2021-2022, Ava Labs, Inc. All rights reserved.
// See the file LICENSE for licensing terms.

package sync

import (
"context"
"encoding/base64"
"testing"

"github.com/ava-labs/avalanchego/snow/engine/snowman/block"
"github.com/ava-labs/coreth/plugin/evm/message"
"github.com/ethereum/go-ethereum/common"
"github.com/stretchr/testify/require"
)

func TestMarshalAtomicSyncSummary(t *testing.T) {
atomicSyncSummary, err := NewAtomicSyncSummary(common.Hash{1}, 2, common.Hash{3}, common.Hash{4})
require.NoError(t, err)

require.Equal(t, common.Hash{1}, atomicSyncSummary.GetBlockHash())
require.Equal(t, uint64(2), atomicSyncSummary.Height())
require.Equal(t, common.Hash{3}, atomicSyncSummary.GetBlockRoot())

expectedBase64Bytes := "AAAAAAAAAAAAAgEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=="
require.Equal(t, expectedBase64Bytes, base64.StdEncoding.EncodeToString(atomicSyncSummary.Bytes()))

parser := NewAtomicSyncSummaryParser()
called := false
acceptImplTest := func(message.Syncable) (block.StateSyncMode, error) {
called = true
return block.StateSyncSkipped, nil
}
s, err := parser.ParseFromBytes(atomicSyncSummary.Bytes(), acceptImplTest)
require.NoError(t, err)
require.Equal(t, atomicSyncSummary.GetBlockHash(), s.GetBlockHash())
require.Equal(t, atomicSyncSummary.Height(), s.Height())
require.Equal(t, atomicSyncSummary.GetBlockRoot(), s.GetBlockRoot())
require.Equal(t, atomicSyncSummary.AtomicRoot, s.(*AtomicSyncSummary).AtomicRoot)
require.Equal(t, atomicSyncSummary.Bytes(), s.Bytes())

mode, err := s.Accept(context.TODO())
require.NoError(t, err)
require.Equal(t, block.StateSyncSkipped, mode)
require.True(t, called)
}
6 changes: 3 additions & 3 deletions plugin/evm/atomic/sync/atomic_syncer_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,14 +47,14 @@ func testAtomicSyncer(t *testing.T, serverTrieDB *triedb.Database, targetHeight

numLeaves := 0
mockClient := syncclient.NewMockClient(
message.Codec,
handlers.NewLeafsRequestHandler(serverTrieDB, state.AtomicTrieKeyLength, nil, message.Codec, handlerstats.NewNoopHandlerStats()),
codecWithAtomicSync,
handlers.NewLeafsRequestHandler(serverTrieDB, state.AtomicTrieKeyLength, nil, codecWithAtomicSync, handlerstats.NewNoopHandlerStats()),
nil,
nil,
)

clientDB := versiondb.New(memdb.New())
repo, err := state.NewAtomicTxRepository(clientDB, message.Codec, 0)
repo, err := state.NewAtomicTxRepository(clientDB, codecWithAtomicSync, 0)
if err != nil {
t.Fatal("could not initialize atomix tx repository", err)
}
Expand Down
4 changes: 1 addition & 3 deletions plugin/evm/message/block_request.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,7 @@ import (
"github.com/ethereum/go-ethereum/common"
)

var (
_ Request = BlockRequest{}
)
var _ Request = BlockRequest{}

// BlockRequest is a request to retrieve Parents number of blocks starting from Hash from newest-oldest manner
type BlockRequest struct {
Expand Down
8 changes: 4 additions & 4 deletions plugin/evm/message/block_request_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,12 +23,12 @@ func TestMarshalBlockRequest(t *testing.T) {

base64BlockRequest := "AAAAAAAAAAAAAAAAAABzb21lIGhhc2ggaXMgaGVyZSB5bwAAAAAAAAU5AEA="

blockRequestBytes, err := Codec.Marshal(Version, blockRequest)
blockRequestBytes, err := codecWithBlockSync.Marshal(Version, blockRequest)
assert.NoError(t, err)
assert.Equal(t, base64BlockRequest, base64.StdEncoding.EncodeToString(blockRequestBytes))

var b BlockRequest
_, err = Codec.Unmarshal(blockRequestBytes, &b)
_, err = codecWithBlockSync.Unmarshal(blockRequestBytes, &b)
assert.NoError(t, err)
assert.Equal(t, blockRequest.Hash, b.Hash)
assert.Equal(t, blockRequest.Height, b.Height)
Expand All @@ -54,12 +54,12 @@ func TestMarshalBlockResponse(t *testing.T) {

base64BlockResponse := "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"

blockResponseBytes, err := Codec.Marshal(Version, blockResponse)
blockResponseBytes, err := codecWithBlockSync.Marshal(Version, blockResponse)
assert.NoError(t, err)
assert.Equal(t, base64BlockResponse, base64.StdEncoding.EncodeToString(blockResponseBytes))

var b BlockResponse
_, err = Codec.Unmarshal(blockResponseBytes, &b)
_, err = codecWithBlockSync.Unmarshal(blockResponseBytes, &b)
assert.NoError(t, err)
assert.Equal(t, blockResponse.Blocks, b.Blocks)
}
119 changes: 119 additions & 0 deletions plugin/evm/message/block_sync_summary.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
// (c) 2021-2022, Ava Labs, Inc. All rights reserved.
// See the file LICENSE for licensing terms.

package message

import (
"context"
"fmt"

"github.com/ava-labs/avalanchego/codec"
"github.com/ava-labs/avalanchego/ids"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/crypto"

"github.com/ava-labs/avalanchego/snow/engine/snowman/block"
)

var _ Syncable = (*BlockSyncSummary)(nil)

// codecWithBlockSync is the codec manager that contains the codec for BlockSyncSummary and
// other message types that are used in the network protocol. This is to ensure that the codec
// version is consistent across all message types and includes the codec for BlockSyncSummary.
var codecWithBlockSync codec.Manager

func init() {
var err error
codecWithBlockSync, err = NewCodec(BlockSyncSummary{})
if err != nil {
panic(fmt.Errorf("failed to create codec manager: %w", err))
}
}

// BlockSyncSummary provides the information necessary to sync a node starting
// at the given block.
type BlockSyncSummary struct {
BlockNumber uint64 `serialize:"true"`
BlockHash common.Hash `serialize:"true"`
BlockRoot common.Hash `serialize:"true"`

summaryID ids.ID
bytes []byte
acceptImpl AcceptImplFn
}

type BlockSyncSummaryParser struct{}

func NewBlockSyncSummaryParser() *BlockSyncSummaryParser {
return &BlockSyncSummaryParser{}
}

func (b *BlockSyncSummaryParser) ParseFromBytes(summaryBytes []byte, acceptImpl AcceptImplFn) (Syncable, error) {
summary := BlockSyncSummary{}
if codecVersion, err := codecWithBlockSync.Unmarshal(summaryBytes, &summary); err != nil {
return nil, fmt.Errorf("failed to parse syncable summary: %w", err)
} else if codecVersion != Version {
return nil, fmt.Errorf("failed to parse syncable summary due to unexpected codec version (%d != %d)", codecVersion, Version)
}

summary.bytes = summaryBytes
summaryID, err := ids.ToID(crypto.Keccak256(summaryBytes))
if err != nil {
return nil, fmt.Errorf("failed to compute summary ID: %w", err)
}
summary.summaryID = summaryID
summary.acceptImpl = acceptImpl
return &summary, nil
}

func NewBlockSyncSummary(blockHash common.Hash, blockNumber uint64, blockRoot common.Hash) (*BlockSyncSummary, error) {
summary := BlockSyncSummary{
BlockNumber: blockNumber,
BlockHash: blockHash,
BlockRoot: blockRoot,
}
bytes, err := codecWithBlockSync.Marshal(Version, &summary)
if err != nil {
return nil, fmt.Errorf("failed to marshal syncable summary: %w", err)
}

summary.bytes = bytes
summaryID, err := ids.ToID(crypto.Keccak256(bytes))
if err != nil {
return nil, fmt.Errorf("failed to compute summary ID: %w", err)
}
summary.summaryID = summaryID

return &summary, nil
}

func (s *BlockSyncSummary) GetBlockHash() common.Hash {
return s.BlockHash
}

func (s *BlockSyncSummary) GetBlockRoot() common.Hash {
return s.BlockRoot
}

func (s *BlockSyncSummary) Bytes() []byte {
return s.bytes
}

func (s *BlockSyncSummary) Height() uint64 {
return s.BlockNumber
}

func (s *BlockSyncSummary) ID() ids.ID {
return s.summaryID
}

func (s *BlockSyncSummary) String() string {
return fmt.Sprintf("BlockSyncSummary(BlockHash=%s, BlockNumber=%d, BlockRoot=%s)", s.BlockHash, s.BlockNumber, s.BlockRoot)
}

func (s *BlockSyncSummary) Accept(context.Context) (block.StateSyncMode, error) {
if s.acceptImpl == nil {
return block.StateSyncSkipped, fmt.Errorf("accept implementation not specified for summary: %s", s)
}
return s.acceptImpl(s)
}
Loading
Loading