|
@ -73,7 +73,15 @@ func Generate(r *rand.Rand, opts Options) ([]e2e.Manifest, error) { |
|
|
manifests := []e2e.Manifest{} |
|
|
manifests := []e2e.Manifest{} |
|
|
switch opts.P2P { |
|
|
switch opts.P2P { |
|
|
case NewP2PMode, LegacyP2PMode, HybridP2PMode: |
|
|
case NewP2PMode, LegacyP2PMode, HybridP2PMode: |
|
|
|
|
|
defer func() { |
|
|
|
|
|
// avoid modifying the global state.
|
|
|
|
|
|
original := make([]interface{}, len(testnetCombinations["p2p"])) |
|
|
|
|
|
copy(original, testnetCombinations["p2p"]) |
|
|
|
|
|
testnetCombinations["p2p"] = original |
|
|
|
|
|
}() |
|
|
|
|
|
|
|
|
testnetCombinations["p2p"] = []interface{}{opts.P2P} |
|
|
testnetCombinations["p2p"] = []interface{}{opts.P2P} |
|
|
|
|
|
|
|
|
default: |
|
|
default: |
|
|
testnetCombinations["p2p"] = []interface{}{NewP2PMode, LegacyP2PMode, HybridP2PMode} |
|
|
testnetCombinations["p2p"] = []interface{}{NewP2PMode, LegacyP2PMode, HybridP2PMode} |
|
|
} |
|
|
} |
|
@ -154,13 +162,15 @@ func generateTestnet(r *rand.Rand, opt map[string]interface{}) (e2e.Manifest, er |
|
|
case "large": |
|
|
case "large": |
|
|
// FIXME Networks are kept small since large ones use too much CPU.
|
|
|
// FIXME Networks are kept small since large ones use too much CPU.
|
|
|
numSeeds = r.Intn(2) |
|
|
numSeeds = r.Intn(2) |
|
|
numLightClients = r.Intn(3) |
|
|
|
|
|
|
|
|
numLightClients = r.Intn(2) |
|
|
numValidators = 4 + r.Intn(4) |
|
|
numValidators = 4 + r.Intn(4) |
|
|
numFulls = r.Intn(4) |
|
|
numFulls = r.Intn(4) |
|
|
default: |
|
|
default: |
|
|
return manifest, fmt.Errorf("unknown topology %q", opt["topology"]) |
|
|
return manifest, fmt.Errorf("unknown topology %q", opt["topology"]) |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
const legacyP2PFactor float64 = 0.5 |
|
|
|
|
|
|
|
|
// First we generate seed nodes, starting at the initial height.
|
|
|
// First we generate seed nodes, starting at the initial height.
|
|
|
for i := 1; i <= numSeeds; i++ { |
|
|
for i := 1; i <= numSeeds; i++ { |
|
|
node := generateNode(r, manifest, e2e.ModeSeed, 0, false) |
|
|
node := generateNode(r, manifest, e2e.ModeSeed, 0, false) |
|
@ -169,18 +179,23 @@ func generateTestnet(r *rand.Rand, opt map[string]interface{}) (e2e.Manifest, er |
|
|
case LegacyP2PMode: |
|
|
case LegacyP2PMode: |
|
|
node.UseLegacyP2P = true |
|
|
node.UseLegacyP2P = true |
|
|
case HybridP2PMode: |
|
|
case HybridP2PMode: |
|
|
node.UseLegacyP2P = r.Intn(5) < 2 |
|
|
|
|
|
|
|
|
node.UseLegacyP2P = r.Float64() < legacyP2PFactor |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
manifest.Nodes[fmt.Sprintf("seed%02d", i)] = node |
|
|
manifest.Nodes[fmt.Sprintf("seed%02d", i)] = node |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
var ( |
|
|
|
|
|
numSyncingNodes = 0 |
|
|
|
|
|
hybridNumNew = 0 |
|
|
|
|
|
hybridNumLegacy = 0 |
|
|
|
|
|
) |
|
|
|
|
|
|
|
|
// Next, we generate validators. We make sure a BFT quorum of validators start
|
|
|
// Next, we generate validators. We make sure a BFT quorum of validators start
|
|
|
// at the initial height, and that we have two archive nodes. We also set up
|
|
|
// at the initial height, and that we have two archive nodes. We also set up
|
|
|
// the initial validator set, and validator set updates for delayed nodes.
|
|
|
// the initial validator set, and validator set updates for delayed nodes.
|
|
|
nextStartAt := manifest.InitialHeight + 5 |
|
|
nextStartAt := manifest.InitialHeight + 5 |
|
|
quorum := numValidators*2/3 + 1 |
|
|
quorum := numValidators*2/3 + 1 |
|
|
numSyncingNodes := 0 |
|
|
|
|
|
for i := 1; i <= numValidators; i++ { |
|
|
for i := 1; i <= numValidators; i++ { |
|
|
startAt := int64(0) |
|
|
startAt := int64(0) |
|
|
if i > quorum && numSyncingNodes < 2 && r.Float64() >= 0.25 { |
|
|
if i > quorum && numSyncingNodes < 2 && r.Float64() >= 0.25 { |
|
@ -195,7 +210,23 @@ func generateTestnet(r *rand.Rand, opt map[string]interface{}) (e2e.Manifest, er |
|
|
case LegacyP2PMode: |
|
|
case LegacyP2PMode: |
|
|
node.UseLegacyP2P = true |
|
|
node.UseLegacyP2P = true |
|
|
case HybridP2PMode: |
|
|
case HybridP2PMode: |
|
|
node.UseLegacyP2P = r.Intn(5) < 2 |
|
|
|
|
|
|
|
|
node.UseLegacyP2P = r.Float64() < legacyP2PFactor |
|
|
|
|
|
if node.UseLegacyP2P { |
|
|
|
|
|
hybridNumLegacy++ |
|
|
|
|
|
if hybridNumNew == 0 { |
|
|
|
|
|
hybridNumNew++ |
|
|
|
|
|
hybridNumLegacy-- |
|
|
|
|
|
node.UseLegacyP2P = false |
|
|
|
|
|
} |
|
|
|
|
|
} else { |
|
|
|
|
|
hybridNumNew++ |
|
|
|
|
|
if hybridNumLegacy == 0 { |
|
|
|
|
|
hybridNumNew-- |
|
|
|
|
|
hybridNumLegacy++ |
|
|
|
|
|
node.UseLegacyP2P = true |
|
|
|
|
|
|
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
manifest.Nodes[name] = node |
|
|
manifest.Nodes[name] = node |
|
@ -222,7 +253,8 @@ func generateTestnet(r *rand.Rand, opt map[string]interface{}) (e2e.Manifest, er |
|
|
// Finally, we generate random full nodes.
|
|
|
// Finally, we generate random full nodes.
|
|
|
for i := 1; i <= numFulls; i++ { |
|
|
for i := 1; i <= numFulls; i++ { |
|
|
startAt := int64(0) |
|
|
startAt := int64(0) |
|
|
if r.Float64() >= 0.5 { |
|
|
|
|
|
|
|
|
if numSyncingNodes < 2 && r.Float64() >= 0.5 { |
|
|
|
|
|
numSyncingNodes++ |
|
|
startAt = nextStartAt |
|
|
startAt = nextStartAt |
|
|
nextStartAt += 5 |
|
|
nextStartAt += 5 |
|
|
} |
|
|
} |
|
@ -232,7 +264,7 @@ func generateTestnet(r *rand.Rand, opt map[string]interface{}) (e2e.Manifest, er |
|
|
case LegacyP2PMode: |
|
|
case LegacyP2PMode: |
|
|
node.UseLegacyP2P = true |
|
|
node.UseLegacyP2P = true |
|
|
case HybridP2PMode: |
|
|
case HybridP2PMode: |
|
|
node.UseLegacyP2P = r.Intn(5) < 2 |
|
|
|
|
|
|
|
|
node.UseLegacyP2P = r.Float64() > legacyP2PFactor |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
manifest.Nodes[fmt.Sprintf("full%02d", i)] = node |
|
|
manifest.Nodes[fmt.Sprintf("full%02d", i)] = node |
|
|