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

swamp: Full Node sync tests #441

Merged
merged 4 commits into from
Mar 14, 2022
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
37 changes: 35 additions & 2 deletions node/tests/swamp/swamp.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
}
Expand All @@ -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
Expand Down Expand Up @@ -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 {
Expand Down Expand Up @@ -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 <core, host, hash> 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 {
Expand Down Expand Up @@ -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")
}
Expand Down
102 changes: 102 additions & 0 deletions node/tests/sync_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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())
Bidon15 marked this conversation as resolved.
Show resolved Hide resolved
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))
}