code.vegaprotocol.io/vega@v0.79.0/core/validators/erc20multisig/checkpoint_test.go (about) 1 // Copyright (C) 2023 Gobalsky Labs Limited 2 // 3 // This program is free software: you can redistribute it and/or modify 4 // it under the terms of the GNU Affero General Public License as 5 // published by the Free Software Foundation, either version 3 of the 6 // License, or (at your option) any later version. 7 // 8 // This program is distributed in the hope that it will be useful, 9 // but WITHOUT ANY WARRANTY; without even the implied warranty of 10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 // GNU Affero General Public License for more details. 12 // 13 // You should have received a copy of the GNU Affero General Public License 14 // along with this program. If not, see <http://www.gnu.org/licenses/>. 15 16 package erc20multisig_test 17 18 import ( 19 "context" 20 "testing" 21 "time" 22 23 "code.vegaprotocol.io/vega/core/types" 24 "code.vegaprotocol.io/vega/core/validators" 25 26 "github.com/golang/mock/gomock" 27 "github.com/stretchr/testify/assert" 28 "github.com/stretchr/testify/require" 29 ) 30 31 func TestMultisigTopologyCheckpoint(t *testing.T) { 32 top := getTestTopology(t) 33 defer top.ctrl.Finish() 34 35 top.OnTick(context.Background(), time.Unix(10, 0)) 36 // first set the threshold and 1 validator 37 38 // Let's create threshold 39 // first assert we have no threshold 40 assert.Equal(t, uint32(0), top.GetThreshold()) 41 42 thresholdEvent1 := types.SignerThresholdSetEvent{ 43 Threshold: 666, 44 BlockNumber: 10, 45 LogIndex: 11, 46 TxHash: "0xacbde", 47 ID: "someid", 48 Nonce: "123", 49 BlockTime: 123456789, 50 } 51 52 var cb func(interface{}, bool) 53 var res validators.Resource 54 top.witness.EXPECT().StartCheck(gomock.Any(), gomock.Any(), gomock.Any()).Times(1).DoAndReturn(func(r validators.Resource, f func(interface{}, bool), _ time.Time) error { 55 cb = f 56 res = r 57 return nil 58 }) 59 60 assert.NoError(t, top.ProcessThresholdEvent(&thresholdEvent1)) 61 62 // now we can call the callback 63 cb(res, true) 64 65 // now we can update the time 66 top.ocv.EXPECT().GetMultiSigAddress().AnyTimes() 67 top.ethEventSource.EXPECT().UpdateContractBlock(gomock.Any(), gomock.Any(), gomock.Any()).AnyTimes() 68 top.broker.EXPECT().Send(gomock.Any()).Times(1) 69 top.OnTick(context.Background(), time.Unix(11, 0)) 70 assert.Equal(t, top.GetThreshold(), uint32(666)) 71 72 // now the signer 73 74 // first assert we have no signers 75 assert.Len(t, top.GetSigners(), 0) 76 77 signerEvent1 := types.SignerEvent{ 78 BlockNumber: 150, 79 LogIndex: 11, 80 TxHash: "0xacbde", 81 ID: "someid", 82 Address: "0xe82EfC4187705655C9b484dFFA25f240e8A6B0BA", 83 Nonce: "123", 84 BlockTime: 123456789, 85 Kind: types.SignerEventKindAdded, 86 } 87 88 top.witness.EXPECT().StartCheck(gomock.Any(), gomock.Any(), gomock.Any()).Times(1).DoAndReturn(func(r validators.Resource, f func(interface{}, bool), _ time.Time) error { 89 cb = f 90 res = r 91 return nil 92 }) 93 94 assert.NoError(t, top.ProcessSignerEvent(&signerEvent1)) 95 96 // now we can call the callback 97 cb(res, true) 98 99 // now we can update the time 100 top.broker.EXPECT().Send(gomock.Any()).Times(1) 101 top.OnTick(context.Background(), time.Unix(12, 0)) 102 103 t.Run("ensure the signer list is updated", func(t *testing.T) { 104 signers := top.GetSigners() 105 assert.Len(t, signers, 1) 106 assert.Equal(t, "0xe82EfC4187705655C9b484dFFA25f240e8A6B0BA", signers[0]) 107 }) 108 109 t.Run("check if our party IsSigner", func(t *testing.T) { 110 assert.True(t, top.IsSigner("0xe82EfC4187705655C9b484dFFA25f240e8A6B0BA")) 111 }) 112 113 t.Run("check excess signers", func(t *testing.T) { 114 okAddresses := []string{"0xe82EfC4187705655C9b484dFFA25f240e8A6B0BA"} 115 koAddresses := []string{} 116 117 assert.True(t, top.ExcessSigners(koAddresses)) 118 assert.False(t, top.ExcessSigners(okAddresses)) 119 }) 120 121 // now we will add some pending ones 122 123 thresholdEvent2 := types.SignerThresholdSetEvent{ 124 Threshold: 500, 125 BlockNumber: 150, 126 LogIndex: 1, 127 TxHash: "0xacbde2", 128 ID: "someidthreshold2", 129 Nonce: "1234", 130 BlockTime: 133456790, 131 } 132 133 top.witness.EXPECT().StartCheck(gomock.Any(), gomock.Any(), gomock.Any()).Times(1).DoAndReturn(func(r validators.Resource, f func(interface{}, bool), _ time.Time) error { 134 return nil 135 }) 136 137 assert.NoError(t, top.ProcessThresholdEvent(&thresholdEvent2)) 138 139 signerEvent2 := types.SignerEvent{ 140 BlockNumber: 101, 141 LogIndex: 19, 142 TxHash: "0xacbde3", 143 ID: "someid3", 144 Address: "0xa587765281c2514E899ecFFa9626b6254582a3bA", 145 Nonce: "1239", 146 BlockTime: 133456789, 147 Kind: types.SignerEventKindAdded, 148 } 149 150 top.witness.EXPECT().StartCheck(gomock.Any(), gomock.Any(), gomock.Any()).Times(1).DoAndReturn(func(r validators.Resource, f func(interface{}, bool), _ time.Time) error { 151 return nil 152 }) 153 154 assert.NoError(t, top.ProcessSignerEvent(&signerEvent2)) 155 156 // now we can make a checkpoint and load it. 157 // here we expect the following: 158 // threshold set to 666 159 // 1 validator 160 // block set to the most recent pending 161 162 cp, err := top.Checkpoint() 163 assert.NoError(t, err) 164 assert.True(t, len(cp) > 0) 165 166 top2 := getTestTopology(t) 167 top2.ocv.EXPECT().GetMultiSigAddress().AnyTimes() 168 top2.ethEventSource.EXPECT().UpdateContractBlock(gomock.Any(), gomock.Any(), gomock.Any()).AnyTimes() 169 170 top2.broker.EXPECT().Send(gomock.Any()).Times(2) 171 require.NoError(t, top2.Load(context.Background(), cp)) 172 173 // no assert state is restored correctly 174 assert.Equal(t, int(top2.GetThreshold()), 666) 175 signers := top2.GetSigners() 176 assert.Len(t, signers, 1) 177 assert.Equal(t, signers[0], "0xe82EfC4187705655C9b484dFFA25f240e8A6B0BA") 178 }