github.com/MetalBlockchain/metalgo@v1.11.9/snow/consensus/snowball/consensus_performance_test.go (about) 1 // Copyright (C) 2019-2024, Ava Labs, Inc. All rights reserved. 2 // See the file LICENSE for licensing terms. 3 4 package snowball 5 6 import ( 7 "testing" 8 9 "github.com/stretchr/testify/require" 10 "gonum.org/v1/gonum/mathext/prng" 11 ) 12 13 // Test that a network running the lower AlphaPreference converges faster than a 14 // network running equal Alpha values. 15 func TestDualAlphaOptimization(t *testing.T) { 16 require := require.New(t) 17 18 var ( 19 numColors = 10 20 numNodes = 100 21 params = Parameters{ 22 K: 20, 23 AlphaPreference: 15, 24 AlphaConfidence: 15, 25 Beta: 20, 26 } 27 seed uint64 = 0 28 source = prng.NewMT19937() 29 ) 30 31 singleAlphaNetwork := NewNetwork(SnowballFactory, params, numColors, source) 32 33 params.AlphaPreference = params.K/2 + 1 34 dualAlphaNetwork := NewNetwork(SnowballFactory, params, numColors, source) 35 36 source.Seed(seed) 37 for i := 0; i < numNodes; i++ { 38 dualAlphaNetwork.AddNode(NewTree) 39 } 40 41 source.Seed(seed) 42 for i := 0; i < numNodes; i++ { 43 singleAlphaNetwork.AddNode(NewTree) 44 } 45 46 // Although this can theoretically fail with a correct implementation, it 47 // shouldn't in practice 48 runNetworksInLockstep(require, seed, source, dualAlphaNetwork, singleAlphaNetwork) 49 } 50 51 // Test that a network running the snowball tree converges faster than a network 52 // running the flat snowball protocol. 53 func TestTreeConvergenceOptimization(t *testing.T) { 54 require := require.New(t) 55 56 var ( 57 numColors = 10 58 numNodes = 100 59 params = DefaultParameters 60 seed uint64 = 0 61 source = prng.NewMT19937() 62 ) 63 64 treeNetwork := NewNetwork(SnowballFactory, params, numColors, source) 65 flatNetwork := NewNetwork(SnowballFactory, params, numColors, source) 66 67 source.Seed(seed) 68 for i := 0; i < numNodes; i++ { 69 treeNetwork.AddNode(NewTree) 70 } 71 72 source.Seed(seed) 73 for i := 0; i < numNodes; i++ { 74 flatNetwork.AddNode(NewFlat) 75 } 76 77 // Although this can theoretically fail with a correct implementation, it 78 // shouldn't in practice 79 runNetworksInLockstep(require, seed, source, treeNetwork, flatNetwork) 80 } 81 82 func runNetworksInLockstep(require *require.Assertions, seed uint64, source *prng.MT19937, fast *Network, slow *Network) { 83 numRounds := 0 84 for !fast.Finalized() && !fast.Disagreement() && !slow.Finalized() && !slow.Disagreement() { 85 source.Seed(uint64(numRounds) + seed) 86 fast.Round() 87 88 source.Seed(uint64(numRounds) + seed) 89 slow.Round() 90 numRounds++ 91 } 92 93 require.False(fast.Disagreement()) 94 require.False(slow.Disagreement()) 95 require.True(fast.Finalized()) 96 require.True(fast.Agreement()) 97 }