diff --git a/node/tests/swamp/swamp.go b/node/tests/swamp/swamp.go index efe4d522de..a106c25b61 100644 --- a/node/tests/swamp/swamp.go +++ b/node/tests/swamp/swamp.go @@ -32,13 +32,14 @@ var queryEvent string = types.QueryForEvent(types.EventNewBlock).String() // Swamp represents the main functionality that is needed for the test-case: // - Network to link the nodes // - CoreClient to share between Bridge nodes -// - Slices of created Bridge/Light Nodes +// - Slices of created Bridge/Full/Light Nodes // - trustedHash taken from the CoreClient and shared between nodes type Swamp struct { t *testing.T Network mocknet.Mocknet CoreClient core.Client BridgeNodes []*node.Node + FullNodes []*node.Node LightNodes []*node.Node trustedHash string } @@ -65,7 +66,7 @@ func NewSwamp(t *testing.T, ic *Components) *Swamp { require.NoError(t, err) swp.t.Cleanup(func() { - swp.stopAllNodes(ctx, swp.BridgeNodes, swp.LightNodes) + swp.stopAllNodes(ctx, swp.BridgeNodes, swp.FullNodes, swp.LightNodes) }) return swp @@ -185,6 +186,15 @@ func (s *Swamp) NewBridgeNode(options ...node.Option) *node.Node { return s.NewBridgeNodeWithStore(store, options...) } +// NewFullNode creates a new instance of a FullNode providing a default config +// and a mockstore to the NewFullNodeWithStore method +func (s *Swamp) NewFullNode(options ...node.Option) *node.Node { + cfg := node.DefaultConfig(node.Full) + store := node.MockStore(s.t, cfg) + + return s.NewFullNodeWithStore(store, options...) +} + // NewLightNode creates a new instance of a LightNode providing a default config // and a mockstore to the NewLightNodeWithStore method func (s *Swamp) NewLightNode(options ...node.Option) *node.Node { @@ -215,6 +225,26 @@ func (s *Swamp) NewBridgeNodeWithStore(store node.Store, options ...node.Option) return node } +// NewFullNodeWithStore creates a new instance of FullNode with predefined Store. +// Afterwards, the instance is stored in the swamp's FullNodes slice +func (s *Swamp) NewFullNodeWithStore(store node.Store, options ...node.Option) *node.Node { + ks, err := store.Keystore() + require.NoError(s.t, err) + + // TODO(@Bidon15): If for some reason, we receive one of existing options + // like from the test case, we need to check them and not use + // default that are set here + options = append(options, + node.WithHost(s.createPeer(ks)), + node.WithTrustedHash(s.trustedHash), + ) + + node, err := node.New(node.Full, store, options...) + require.NoError(s.t, err) + s.FullNodes = append(s.FullNodes, node) + return node +} + // NewLightNodeWithStore creates a new instance of LightNode with predefined Store. // Afterwards, the instance is stored in the swamp's LightNodes slice func (s *Swamp) NewLightNodeWithStore(store node.Store, options ...node.Option) *node.Node { @@ -248,6 +278,9 @@ func (s *Swamp) RemoveNode(n *node.Node, t node.Type) error { case node.Bridge: s.BridgeNodes, err = s.remove(n, s.BridgeNodes) return err + case node.Full: + s.FullNodes, err = s.remove(n, s.FullNodes) + return err default: return fmt.Errorf("no such type or node") } diff --git a/node/tests/sync_test.go b/node/tests/sync_test.go index b7766a09d9..904364d831 100644 --- a/node/tests/sync_test.go +++ b/node/tests/sync_test.go @@ -112,3 +112,105 @@ func TestSyncStartStopLightWithBridge(t *testing.T) { assert.EqualValues(t, h.Commit.BlockID.Hash, sw.GetCoreBlockHashByHeight(ctx, 40)) } + +/* +Test-Case: Sync a Full Node with a Bridge Node +Steps: +1. Create a Bridge Node(BN) +2. Start a BN +3. Check BN is synced to height 20 +4. Create a Full Node(FN) with a connection to BN as a trusted peer +5. Start a FN +6. Check FN is synced to height 30 +*/ +func TestSyncFullWithBridge(t *testing.T) { + sw := swamp.NewSwamp(t, swamp.DefaultComponents()) + + bridge := sw.NewBridgeNode() + + ctx, cancel := context.WithTimeout(context.Background(), 20*time.Second) + t.Cleanup(cancel) + + sw.WaitTillHeight(ctx, 20) + + err := bridge.Start(ctx) + require.NoError(t, err) + + h, err := bridge.HeaderServ.GetByHeight(ctx, 20) + require.NoError(t, err) + + assert.EqualValues(t, h.Commit.BlockID.Hash, sw.GetCoreBlockHashByHeight(ctx, 20)) + + addrs, err := peer.AddrInfoToP2pAddrs(host.InfoFromHost(bridge.Host)) + require.NoError(t, err) + + full := sw.NewFullNode(node.WithTrustedPeer(addrs[0].String())) + require.NoError(t, full.Start(ctx)) + + h, err = full.HeaderServ.GetByHeight(ctx, 30) + require.NoError(t, err) + + assert.EqualValues(t, h.Commit.BlockID.Hash, sw.GetCoreBlockHashByHeight(ctx, 30)) +} + +/* +Test-Case: Sync a Light Node from a Full Node +Pre-Requisites: +- CoreClient is started by swamp +- CoreClient has generated 20 blocks +Steps: +1. Create a Bridge Node(BN) +2. Start a BN +3. Check BN is synced to height 20 +4. Create a Full Node(FN) with a connection to BN as a trusted peer +5. Start a FN +6. Check FN is synced to height 30 +7. Create a Light Node(LN) with a connection to FN as a trusted peer +8. Start a LN with a defined connection to the FN +9. Start LN +10. Check LN is synced to height 50 +*/ +func TestSyncLightWithFull(t *testing.T) { + sw := swamp.NewSwamp(t, swamp.DefaultComponents()) + + bridge := sw.NewBridgeNode() + + ctx, cancel := context.WithTimeout(context.Background(), 20*time.Second) + t.Cleanup(cancel) + + sw.WaitTillHeight(ctx, 20) + + err := bridge.Start(ctx) + require.NoError(t, err) + + h, err := bridge.HeaderServ.GetByHeight(ctx, 20) + require.NoError(t, err) + + assert.EqualValues(t, h.Commit.BlockID.Hash, sw.GetCoreBlockHashByHeight(ctx, 20)) + + addrs, err := peer.AddrInfoToP2pAddrs(host.InfoFromHost(bridge.Host)) + require.NoError(t, err) + + full := sw.NewFullNode(node.WithTrustedPeer(addrs[0].String())) + require.NoError(t, full.Start(ctx)) + + h, err = full.HeaderServ.GetByHeight(ctx, 30) + require.NoError(t, err) + + assert.EqualValues(t, h.Commit.BlockID.Hash, sw.GetCoreBlockHashByHeight(ctx, 30)) + + addrs, err = peer.AddrInfoToP2pAddrs(host.InfoFromHost(full.Host)) + require.NoError(t, err) + light := sw.NewLightNode(node.WithTrustedPeer(addrs[0].String())) + + err = sw.Network.UnlinkPeers(bridge.Host.ID(), light.Host.ID()) + require.NoError(t, err) + + err = light.Start(ctx) + require.NoError(t, err) + + h, err = light.HeaderServ.GetByHeight(ctx, 50) + require.NoError(t, err) + + assert.EqualValues(t, h.Commit.BlockID.Hash, sw.GetCoreBlockHashByHeight(ctx, 50)) +}