This repository has been archived by the owner on Oct 31, 2024. It is now read-only.
forked from 0xPolygon/polygon-edge
-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathpos_poa_switch_test.go
167 lines (134 loc) · 4.34 KB
/
pos_poa_switch_test.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
package e2e
import (
"context"
"crypto/ecdsa"
"sync"
"testing"
"time"
"github.com/0xPolygon/polygon-edge/consensus/ibft/fork"
ibftOp "github.com/0xPolygon/polygon-edge/consensus/ibft/proto"
"github.com/0xPolygon/polygon-edge/crypto"
"github.com/0xPolygon/polygon-edge/e2e/framework"
"github.com/0xPolygon/polygon-edge/types"
"github.com/stretchr/testify/assert"
)
// Test scenario:
// PoA [0, 29]
// - Check validator set in each validator equals to genesis validator
// - 3 validators stake to the validator contract after contract deploys at block #10
// PoS [30, ]
// - Check validator set in each validator has only 3 validators
func TestPoAPoSSwitch(t *testing.T) {
var (
// switch configuration
posDeployContractAt = uint64(10)
posStartAt = uint64(30)
defaultBalance = framework.EthToWei(1000)
stakeAmount = framework.EthToWei(5)
)
ibftManager := framework.NewIBFTServersManager(
t,
IBFTMinNodes,
IBFTDirPrefix,
func(i int, config *framework.TestServerConfig) {
config.PremineValidatorBalance(defaultBalance)
})
// Set switch configuration into genesis.json
err := ibftManager.GetServer(0).SwitchIBFTType(fork.PoS, posStartAt, nil, &posDeployContractAt)
assert.NoError(t, err)
// Get server slice
servers := make([]*framework.TestServer, 0)
for i := 0; i < IBFTMinNodes; i++ {
servers = append(servers, ibftManager.GetServer(i))
}
// Get genesis validators
genesisValidatorKeys := make([]*ecdsa.PrivateKey, IBFTMinNodes)
genesisValidatorAddrs := make([]types.Address, IBFTMinNodes)
for idx := 0; idx < IBFTMinNodes; idx++ {
validatorKey, err := ibftManager.GetServer(idx).Config.PrivateKey()
assert.NoError(t, err)
validatorAddr := crypto.PubKeyToAddress(&validatorKey.PublicKey)
genesisValidatorKeys[idx] = validatorKey
genesisValidatorAddrs[idx] = validatorAddr
}
// Start servers
ctx, cancel := context.WithTimeout(context.Background(), time.Minute)
defer cancel()
ibftManager.StartServers(ctx)
// Test in PoA
validateSnapshot := func(
ctx context.Context,
srv *framework.TestServer,
height uint64,
expectedValidators []types.Address,
) {
res, err := srv.IBFTOperator().GetSnapshot(ctx, &ibftOp.SnapshotReq{
Number: height,
})
assert.NoError(t, err)
snapshotValidators := make([]types.Address, len(res.Validators))
for idx, v := range res.Validators {
snapshotValidators[idx] = types.BytesToAddress(v.Data)
}
assert.ElementsMatch(t, expectedValidators, snapshotValidators)
}
// Check validator set in each validator
var wg sync.WaitGroup
for i := 0; i < IBFTMinNodes; i++ {
wg.Add(1)
srv := ibftManager.GetServer(i)
go func(srv *framework.TestServer) {
defer wg.Done()
ctx, cancel := context.WithTimeout(context.Background(), framework.DefaultTimeout)
defer cancel()
// every validator should have 4 validators in validator set
validateSnapshot(ctx, srv, 1, genesisValidatorAddrs)
}(srv)
}
wg.Wait()
// Wait until the staking contract is deployed
waitErrors := framework.WaitForServersToSeal(servers, posDeployContractAt)
if len(waitErrors) != 0 {
t.Fatalf("Unable to wait for all nodes to seal blocks, %v", waitErrors)
}
// Stake balance
// 4 genesis validators will stake but 1 gensis validator won't
numStakedValidators := 4
wg = sync.WaitGroup{}
for idx := 0; idx < numStakedValidators; idx++ {
wg.Add(1)
srv := ibftManager.GetServer(idx)
key, addr := genesisValidatorKeys[idx], genesisValidatorAddrs[idx]
go func(srv *framework.TestServer, key *ecdsa.PrivateKey, addr types.Address) {
defer wg.Done()
err := framework.StakeAmount(
addr,
key,
stakeAmount,
srv,
)
assert.NoError(t, err)
}(srv, key, addr)
}
wg.Wait()
// Wait until PoS begins
waitErrors = framework.WaitForServersToSeal(servers, posStartAt)
if len(waitErrors) != 0 {
t.Fatalf("Unable to wait for all nodes to seal blocks, %v", waitErrors)
}
expectedPoSValidators := genesisValidatorAddrs[:4]
// Test in PoS
wg = sync.WaitGroup{}
for i := 0; i < IBFTMinNodes; i++ {
wg.Add(1)
srv := ibftManager.GetServer(i)
go func(srv *framework.TestServer) {
defer wg.Done()
ctx, cancel := context.WithTimeout(context.Background(), framework.DefaultTimeout)
defer cancel()
// every validator should have only 4 validators in validator set
validateSnapshot(ctx, srv, posStartAt, expectedPoSValidators)
}(srv)
}
wg.Wait()
}