From eced4f5de4b1be91f14127b4c82c6124bd3acec5 Mon Sep 17 00:00:00 2001 From: Josh Klopfenstein Date: Tue, 28 Nov 2023 16:58:12 -0600 Subject: [PATCH] Validate the --network option --- node/node.go | 14 ++++++++++++++ node/node_test.go | 47 +++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 61 insertions(+) diff --git a/node/node.go b/node/node.go index d6d3369f19..ab96b521b0 100644 --- a/node/node.go +++ b/node/node.go @@ -13,6 +13,7 @@ import ( "github.com/NethermindEth/juno/blockchain" "github.com/NethermindEth/juno/clients/feeder" "github.com/NethermindEth/juno/clients/gateway" + "github.com/NethermindEth/juno/core" "github.com/NethermindEth/juno/db" "github.com/NethermindEth/juno/db/pebble" "github.com/NethermindEth/juno/db/remote" @@ -120,6 +121,19 @@ func New(cfg *Config, version string) (*Node, error) { //nolint:gocyclo,funlen services := make([]service.Service, 0) chain := blockchain.New(database, cfg.Network, log) + + // Verify that cfg.Network is compatible with the database. + head, err := chain.Head() + if err != nil && !errors.Is(err, db.ErrKeyNotFound) { + return nil, fmt.Errorf("get head block from database: %v", err) + } + if head != nil { + // We assume that there is at least one transaction in the block or that it is a pre-0.7 block. + if _, err = core.VerifyBlockHash(head, cfg.Network); err != nil { + return nil, errors.New("unable to verify latest block hash; are the database and --network option compatible?") + } + } + feederClientTimeout := 5 * time.Second client := feeder.NewClient(cfg.Network.FeederURL()).WithUserAgent(ua).WithLogger(log). WithTimeout(feederClientTimeout).WithAPIKey(cfg.GatewayAPIKey) diff --git a/node/node_test.go b/node/node_test.go index 31c677c4dd..7cebf7add8 100644 --- a/node/node_test.go +++ b/node/node_test.go @@ -5,7 +5,12 @@ import ( "testing" "time" + "github.com/NethermindEth/juno/blockchain" + "github.com/NethermindEth/juno/clients/feeder" + "github.com/NethermindEth/juno/db/pebble" "github.com/NethermindEth/juno/node" + adaptfeeder "github.com/NethermindEth/juno/starknetdata/feeder" + "github.com/NethermindEth/juno/sync" "github.com/NethermindEth/juno/utils" "github.com/stretchr/testify/require" ) @@ -41,3 +46,45 @@ func TestNewNode(t *testing.T) { cancel() n.Run(ctx) } + +func TestNetworkVerificationOnNonEmptyDB(t *testing.T) { + network := utils.Integration + tests := map[string]struct { + network utils.Network + errString string + }{ + "same network": { + network: network, + errString: "", + }, + "different network": { + network: utils.Mainnet, + errString: "unable to verify latest block hash; are the database and --network option compatible?", + }, + } + + for description, test := range tests { + t.Run(description, func(t *testing.T) { + dbPath := t.TempDir() + log := utils.NewNopZapLogger() + database, err := pebble.New(dbPath, 1, log) + require.NoError(t, err) + chain := blockchain.New(database, network, log) + syncer := sync.New(chain, adaptfeeder.New(feeder.NewTestClient(t, network)), log, 0, false) + ctx, cancel := context.WithTimeout(context.Background(), 250*time.Millisecond) + require.NoError(t, syncer.Run(ctx)) + cancel() + require.NoError(t, database.Close()) + + _, err = node.New(&node.Config{ + DatabasePath: dbPath, + Network: test.network, + }, "v0.1") + if test.errString == "" { + require.NoError(t, err) + } else { + require.ErrorContains(t, err, test.errString) + } + }) + } +}