From fa781e6bb78b04887a21fdb22e7146ea8c50db08 Mon Sep 17 00:00:00 2001 From: Callum Waters Date: Mon, 15 Mar 2021 13:04:33 +0100 Subject: [PATCH] e2e: fix light client generator (#6236) --- light/client.go | 16 +++++++------ test/e2e/app/main.go | 8 ++++++- test/e2e/generator/generate.go | 42 ++++++++++++++++++++-------------- 3 files changed, 41 insertions(+), 25 deletions(-) diff --git a/light/client.go b/light/client.go index 86f257157..b6785f768 100644 --- a/light/client.go +++ b/light/client.go @@ -1101,14 +1101,16 @@ func (c *Client) compareFirstHeaderWithWitnesses(ctx context.Context, h *types.S and remove witness. Otherwise, use a different primary`, e.WitnessIndex), "witness", c.witnesses[e.WitnessIndex]) return err case errBadWitness: - // If witness sent us an invalid header, then remove it. If it didn't - // respond or couldn't find the block, then we ignore it and move on to - // the next witness. - if _, ok := e.Reason.(provider.ErrBadLightBlock); ok { - c.logger.Info("Witness sent an invalid light block, removing...", "witness", c.witnesses[e.WitnessIndex]) - witnessesToRemove = append(witnessesToRemove, e.WitnessIndex) - } + // If witness sent us an invalid header, then remove it + c.logger.Info("witness sent an invalid light block or didn't respond, removing...", + "witness", c.witnesses[e.WitnessIndex], + "err", err) + witnessesToRemove = append(witnessesToRemove, e.WitnessIndex) + default: // the witness either didn't respond or didn't have the block. We ignore it. + c.logger.Debug("unable to compare first header with witness", + "err", err) } + } // remove all witnesses that misbehaved diff --git a/test/e2e/app/main.go b/test/e2e/app/main.go index 25660ec44..a465bb786 100644 --- a/test/e2e/app/main.go +++ b/test/e2e/app/main.go @@ -349,7 +349,13 @@ func rpcEndpoints(peers string) []string { } // use RPC port instead addr.Port = 26657 - rpcEndpoint := "http://" + addr.Hostname + ":" + fmt.Sprint(addr.Port) + var rpcEndpoint string + // for ipv6 addresses + if strings.Contains(addr.Hostname, ":") { + rpcEndpoint = "http://[" + addr.Hostname + "]:" + fmt.Sprint(addr.Port) + } else { // for ipv4 addresses + rpcEndpoint = "http://" + addr.Hostname + ":" + fmt.Sprint(addr.Port) + } endpoints[i] = rpcEndpoint } return endpoints diff --git a/test/e2e/generator/generate.go b/test/e2e/generator/generate.go index 85646bd74..29614fa3c 100644 --- a/test/e2e/generator/generate.go +++ b/test/e2e/generator/generate.go @@ -144,21 +144,19 @@ func generateTestnet(r *rand.Rand, opt map[string]interface{}) (e2e.Manifest, er r, e2e.ModeFull, startAt, manifest.InitialHeight, false) } - for i := 1; i <= numLightClients; i++ { - startAt := manifest.InitialHeight + 5 - manifest.Nodes[fmt.Sprintf("light%02d", i)] = generateNode( - r, e2e.ModeLight, startAt+(5*int64(i)), manifest.InitialHeight, false, - ) - } - // We now set up peer discovery for nodes. Seed nodes are fully meshed with // each other, while non-seed nodes either use a set of random seeds or a // set of random peers that start before themselves. - var seedNames, peerNames []string + var seedNames, peerNames, lightProviders []string for name, node := range manifest.Nodes { if node.Mode == string(e2e.ModeSeed) { seedNames = append(seedNames, name) } else { + // if the full node or validator is an ideal candidate, it is added as a light provider. + // There are at least two archive nodes so there should be at least two ideal candidates + if (node.StartAt == 0 || node.StartAt == manifest.InitialHeight) && node.RetainBlocks == 0 { + lightProviders = append(lightProviders, name) + } peerNames = append(peerNames, name) } } @@ -183,10 +181,6 @@ func generateTestnet(r *rand.Rand, opt map[string]interface{}) (e2e.Manifest, er } }) for i, name := range peerNames { - // we skip over light clients - they connect to all peers initially - if manifest.Nodes[name].Mode == string(e2e.ModeLight) { - continue - } if len(seedNames) > 0 && (i == 0 || r.Float64() >= 0.5) { manifest.Nodes[name].Seeds = uniformSetChoice(seedNames).Choose(r) } else if i > 0 { @@ -194,6 +188,14 @@ func generateTestnet(r *rand.Rand, opt map[string]interface{}) (e2e.Manifest, er } } + // lastly, set up the light clients + for i := 1; i <= numLightClients; i++ { + startAt := manifest.InitialHeight + 5 + manifest.Nodes[fmt.Sprintf("light%02d", i)] = generateLightNode( + r, startAt+(5*int64(i)), lightProviders, + ) + } + return manifest, nil } @@ -236,11 +238,6 @@ func generateNode( } } - if node.Mode == string(e2e.ModeLight) { - node.ABCIProtocol = "builtin" - node.StateSync = false - } - // If a node which does not persist state also does not retain blocks, randomly // choose to either persist state or retain all blocks. if node.PersistInterval != nil && *node.PersistInterval == 0 && node.RetainBlocks > 0 { @@ -265,6 +262,17 @@ func generateNode( return &node } +func generateLightNode(r *rand.Rand, startAt int64, providers []string) *e2e.ManifestNode { + return &e2e.ManifestNode{ + Mode: string(e2e.ModeLight), + StartAt: startAt, + Database: nodeDatabases.Choose(r).(string), + ABCIProtocol: "builtin", + PersistInterval: ptrUint64(0), + PersistentPeers: providers, + } +} + func ptrUint64(i uint64) *uint64 { return &i }