@@ -14,6 +14,7 @@ import (
1414 "github.com/ethereum/go-ethereum/accounts/abi"
1515 "github.com/ethereum/go-ethereum/accounts/abi/bind"
1616 "github.com/ethereum/go-ethereum/common"
17+ "github.com/ethereum/go-ethereum/core/types"
1718 "github.com/ethereum/go-ethereum/crypto"
1819 "github.com/ethereum/go-ethereum/ethclient"
1920 "github.com/pkg/errors"
@@ -24,10 +25,30 @@ import (
2425 "github.com/flare-foundation/go-flare-common/pkg/contracts/registry"
2526)
2627
28+ const breakingEpochCoston2 = 5338
29+
30+ const (
31+ newRegistryCoston2Addr = "0x6a0AF07b7972177B176d3D422555cbc98DfDe914"
32+ oldRegistryCoston2Addr = "0xc6E40401395DCc648bC4bBb38fE4552423cD9BAC"
33+
34+ newPreRegistryCoston2Addr = "0xee963D1867d8B5f3D3E304802B40BC55B3eDeCB8"
35+ oldPreRegistryCoston2Addr = "0x47469Af25c253B4fb9b2a207BF4069574C6CcBd7"
36+ )
37+
2738var (
28- registratorArguments abi.Arguments
29- registryAbi * abi.ABI
30- preregistryAbi * abi.ABI
39+ newRegistryCoston2 = common .HexToAddress (newRegistryCoston2Addr )
40+ oldRegistryCoston2 = common .HexToAddress (oldRegistryCoston2Addr )
41+
42+ newPreRegistryCoston2 = common .HexToAddress (newPreRegistryCoston2Addr )
43+ oldPreRegistryCoston2 = common .HexToAddress (oldPreRegistryCoston2Addr )
44+ )
45+
46+ var (
47+ registratorArguments abi.Arguments
48+ registratorArgumentsNew abi.Arguments
49+
50+ registryAbi * abi.ABI
51+ preregistryAbi * abi.ABI
3152
3253 fallbackGasPrice = big .NewInt (50 * 1e9 ) // 50 GWei
3354)
@@ -56,8 +77,27 @@ func init() {
5677 // panic, this error is fatal
5778 panic (err )
5879 }
80+
81+ uint256Ty , err := abi .NewType ("uint256" , "uint256" , nil )
82+ if err != nil {
83+ // panic, this error is fatal
84+ panic (err )
85+ }
86+
5987 registratorArguments = abi.Arguments {
60- { // nextRewardEpochId
88+ { // nextRewardEpochIDs
89+ Type : uint32Ty ,
90+ },
91+ { // address
92+ Type : addressTy ,
93+ },
94+ }
95+
96+ registratorArgumentsNew = abi.Arguments {
97+ { // chainID
98+ Type : uint256Ty ,
99+ },
100+ { // nextRewardEpochID
61101 Type : uint32Ty ,
62102 },
63103 { // address
@@ -84,14 +124,17 @@ type registryContractClient interface {
84124
85125type registryContractClientImpl struct {
86126 ethClient * ethclient.Client
87- address common.Address
127+ registryAddress common.Address
88128 preregistryAddress common.Address
89129 registry * registry.Registry
130+ oldRegistry * registry.Registry
90131 preregistry * preregistry.Preregistry
132+ oldPreregistry * preregistry.Preregistry
91133 senderTxOpts * bind.TransactOpts
92134 gasCfg * config.Gas
93135 txVerifier * chain.TxVerifier
94136 signerPrivateKey * ecdsa.PrivateKey
137+ chainID int
95138}
96139
97140func NewRegistryContractClient (
@@ -101,32 +144,53 @@ func NewRegistryContractClient(
101144 preregistryAddress common.Address ,
102145 senderTxOpts * bind.TransactOpts ,
103146 signerPk * ecdsa.PrivateKey ,
147+ chainID int ,
104148) (* registryContractClientImpl , error ) {
105- registry , err := registry .NewRegistry (registryAddress , ethClient )
149+ registryBinding , err := registry .NewRegistry (registryAddress , ethClient )
106150 if err != nil {
107151 return nil , err
108152 }
109- preregistry , err := preregistry .NewPreregistry (preregistryAddress , ethClient )
153+ preregistryBinding , err := preregistry .NewPreregistry (preregistryAddress , ethClient )
110154 if err != nil {
111155 return nil , err
112156 }
157+
158+ var oldRegistryBinding * registry.Registry
159+ if registryAddress == newRegistryCoston2 {
160+ oldRegistryBinding , err = registry .NewRegistry (oldRegistryCoston2 , ethClient )
161+ if err != nil {
162+ return nil , err
163+ }
164+ }
165+
166+ var oldPreRegistryBinding * preregistry.Preregistry
167+ if preregistryAddress == newPreRegistryCoston2 {
168+ oldPreRegistryBinding , err = preregistry .NewPreregistry (oldPreRegistryCoston2 , ethClient )
169+ if err != nil {
170+ return nil , err
171+ }
172+ }
173+
113174 return & registryContractClientImpl {
114175 ethClient : ethClient ,
115- address : registryAddress ,
176+ registryAddress : registryAddress ,
116177 preregistryAddress : preregistryAddress ,
117- registry : registry ,
118- preregistry : preregistry ,
178+ registry : registryBinding ,
179+ oldRegistry : oldRegistryBinding ,
180+ preregistry : preregistryBinding ,
181+ oldPreregistry : oldPreRegistryBinding ,
119182 senderTxOpts : senderTxOpts ,
120183 gasCfg : gasCfg ,
121184 txVerifier : chain .NewTxVerifier (ethClient ),
122185 signerPrivateKey : signerPk ,
186+ chainID : chainID ,
123187 }, nil
124188}
125189
126190// RegisterVoter tries to register voter on VoterRegistry smart contract.
127- func (r * registryContractClientImpl ) RegisterVoter (nextRewardEpochId * big.Int , address common.Address ) <- chan shared.ExecuteStatus [any ] {
191+ func (r * registryContractClientImpl ) RegisterVoter (nextRewardEpochID * big.Int , address common.Address ) <- chan shared.ExecuteStatus [any ] {
128192 return shared .ExecuteWithRetryChan (func () (any , error ) {
129- err := r .sendRegisterVoter (nextRewardEpochId , address )
193+ err := r .sendRegisterVoter (nextRewardEpochID , address )
130194 if err != nil {
131195 if shared .ExistsAsSubstring (nonFatalRegisterErrors , err .Error ()) {
132196 logger .Debugf ("Non fatal error sending register voter: %v" , err )
@@ -138,12 +202,29 @@ func (r *registryContractClientImpl) RegisterVoter(nextRewardEpochId *big.Int, a
138202 }, shared .MaxTxSendRetriesLong , shared .TxRetryIntervalLong )
139203}
140204
141- func (r * registryContractClientImpl ) sendRegisterVoter (nextRewardEpochId * big.Int , address common.Address ) error {
142- epochId := uint32 (nextRewardEpochId .Uint64 ())
143- signature , err := r .createSignature (epochId , address )
144- if err != nil {
145- return err
205+ func (r * registryContractClientImpl ) sendRegisterVoter (nextRewardEpochID * big.Int , address common.Address ) error {
206+ epochID := uint32 (nextRewardEpochID .Uint64 ())
207+ old , oldAddress := shouldUseOldRegistry (epochID , r .registryAddress )
208+ rAddress := r .registryAddress
209+
210+ var (
211+ signature []byte
212+ err error
213+ )
214+
215+ if old {
216+ rAddress = oldAddress
217+ signature , err = r .createSignatureOld (epochID , address )
218+ if err != nil {
219+ return fmt .Errorf ("creating registry signature old: %w" , err )
220+ }
221+ } else {
222+ signature , err = r .createSignatureNew (r .chainID , epochID , address )
223+ if err != nil {
224+ return fmt .Errorf ("creating pre registry signature new: %w" , err )
225+ }
146226 }
227+
147228 vrsSignature := registry.IVoterRegistrySignature {
148229 R : [32 ]byte (signature [0 :32 ]),
149230 S : [32 ]byte (signature [32 :64 ]),
@@ -159,7 +240,7 @@ func (r *registryContractClientImpl) sendRegisterVoter(nextRewardEpochId *big.In
159240 r .ethClient ,
160241 chain .DefaultTxTimeout ,
161242 r .senderTxOpts .From ,
162- r . address ,
243+ rAddress ,
163244 common .Big0 ,
164245 registryAbi ,
165246 "registerVoter" ,
@@ -176,15 +257,25 @@ func (r *registryContractClientImpl) sendRegisterVoter(nextRewardEpochId *big.In
176257 r .senderTxOpts .GasLimit = estimatedGasLimit
177258 }
178259
179- tx , err := r .registry .RegisterVoter (r .senderTxOpts , address , vrsSignature )
180- if err != nil {
181- return err
260+ var tx * types.Transaction
261+
262+ if old {
263+ tx , err = r .oldRegistry .RegisterVoter (r .senderTxOpts , address , vrsSignature )
264+ if err != nil {
265+ return fmt .Errorf ("sending registry tx old: %w" , err )
266+ }
267+ } else {
268+ tx , err = r .registry .RegisterVoter (r .senderTxOpts , address , vrsSignature )
269+ if err != nil {
270+ return fmt .Errorf ("sending registry tx new: %w" , err )
271+ }
182272 }
273+
183274 err = r .txVerifier .WaitUntilMined (r .senderTxOpts .From , tx , chain .DefaultTxTimeout )
184275 if err != nil {
185276 return err
186277 }
187- logger .Infof ("Voter %s registered for epoch %v" , address , nextRewardEpochId )
278+ logger .Infof ("Voter %s registered for epoch %v" , address , nextRewardEpochID )
188279 return nil
189280}
190281
@@ -203,12 +294,29 @@ func (r *registryContractClientImpl) PreregisterVoter(nextRewardEpochId *big.Int
203294 }, shared .MaxTxSendRetries , shared .TxRetryInterval )
204295}
205296
206- func (r * registryContractClientImpl ) sendPreRegisterVoter (nextRewardEpochId * big.Int , address common.Address ) error {
207- epochId := uint32 (nextRewardEpochId .Uint64 ())
208- signature , err := r .createSignature (epochId , address )
209- if err != nil {
210- return err
297+ func (r * registryContractClientImpl ) sendPreRegisterVoter (nextRewardEpochID * big.Int , address common.Address ) error {
298+ epochID := uint32 (nextRewardEpochID .Uint64 ())
299+ old , oldAddress := shouldUseOldPreRegistry (epochID , r .registryAddress )
300+ prAddress := r .preregistryAddress
301+
302+ var (
303+ signature []byte
304+ err error
305+ )
306+
307+ if old {
308+ prAddress = oldAddress
309+ signature , err = r .createSignatureOld (epochID , address )
310+ if err != nil {
311+ return fmt .Errorf ("creating pre registry signature old: %w" , err )
312+ }
313+ } else {
314+ signature , err = r .createSignatureNew (r .chainID , epochID , address )
315+ if err != nil {
316+ return fmt .Errorf ("creating pre registry signature new: %w" , err )
317+ }
211318 }
319+
212320 vrsSignature := preregistry.IVoterRegistrySignature {
213321 R : [32 ]byte (signature [0 :32 ]),
214322 S : [32 ]byte (signature [32 :64 ]),
@@ -217,14 +325,14 @@ func (r *registryContractClientImpl) sendPreRegisterVoter(nextRewardEpochId *big
217325
218326 err = SetGas (r .senderTxOpts , r .ethClient , r .gasCfg )
219327 if err != nil {
220- return err
328+ return fmt . Errorf ( "setting gas pre registry:%w" , err )
221329 }
222330
223331 estimatedGasLimit , err := chain .DryRunTxAbi (
224332 r .ethClient ,
225333 chain .DefaultTxTimeout ,
226334 r .senderTxOpts .From ,
227- r . preregistryAddress ,
335+ prAddress ,
228336 common .Big0 ,
229337 preregistryAbi ,
230338 "preRegisterVoter" ,
@@ -241,21 +349,42 @@ func (r *registryContractClientImpl) sendPreRegisterVoter(nextRewardEpochId *big
241349 r .senderTxOpts .GasLimit = estimatedGasLimit
242350 }
243351
244- tx , err := r .preregistry .PreRegisterVoter (r .senderTxOpts , address , vrsSignature )
245- if err != nil {
246- return err
352+ var tx * types.Transaction
353+ if old {
354+ tx , err = r .oldPreregistry .PreRegisterVoter (r .senderTxOpts , address , vrsSignature )
355+ if err != nil {
356+ return fmt .Errorf ("sending preregistry tx old: %w" , err )
357+ }
358+ } else {
359+ tx , err = r .preregistry .PreRegisterVoter (r .senderTxOpts , address , vrsSignature )
360+ if err != nil {
361+ return fmt .Errorf ("sending preregistry tx new: %w" , err )
362+ }
247363 }
364+
248365 err = r .txVerifier .WaitUntilMined (r .senderTxOpts .From , tx , chain .DefaultTxTimeout )
249366 if err != nil {
250367 return err
251368 }
252- logger .Infof ("Voter %s pre-registered for epoch %v" , address , nextRewardEpochId )
369+ logger .Infof ("Voter %s pre-registered for epoch %v" , address , nextRewardEpochID )
253370 return nil
254371}
255372
256- // createSignature creates ECDSA message signature keccak256(abi.encode(nextRewardEpochId, address)) with signerPrivateKey
257- func (r * registryContractClientImpl ) createSignature (nextRewardEpochId uint32 , address common.Address ) ([]byte , error ) {
258- message , err := registratorArguments .Pack (nextRewardEpochId , address )
373+ // createSignatureOld creates ECDSA message signature keccak256(abi.encode(nextRewardEpochID, address)) with signerPrivateKey
374+ func (r * registryContractClientImpl ) createSignatureOld (nextRewardEpochID uint32 , address common.Address ) ([]byte , error ) {
375+ message , err := registratorArguments .Pack (nextRewardEpochID , address )
376+ if err != nil {
377+ return nil , err
378+ }
379+ messageHash := crypto .Keccak256 (message )
380+ return crypto .Sign (accounts .TextHash (messageHash ), r .signerPrivateKey )
381+ }
382+
383+ // createSignatureOld creates ECDSA message signature keccak256(abi.encode(chainID, nextRewardEpochID, address)) with signerPrivateKey
384+ func (r * registryContractClientImpl ) createSignatureNew (chainID int , nextRewardEpochID uint32 , address common.Address ) ([]byte , error ) {
385+ chainIDB := big .NewInt (int64 (chainID ))
386+
387+ message , err := registratorArgumentsNew .Pack (chainIDB , nextRewardEpochID , address )
259388 if err != nil {
260389 return nil , err
261390 }
@@ -311,3 +440,19 @@ func SetGas(txOptions *bind.TransactOpts, client *ethclient.Client, gasConfig *c
311440 return fmt .Errorf ("unsupported tx type: %d" , gasConfig .TxType )
312441 }
313442}
443+
444+ func shouldUseOldRegistry (epochID uint32 , address common.Address ) (bool , common.Address ) {
445+ if address == newRegistryCoston2 && epochID <= breakingEpochCoston2 {
446+ return true , oldRegistryCoston2
447+ }
448+
449+ return false , common.Address {}
450+ }
451+
452+ func shouldUseOldPreRegistry (epochID uint32 , address common.Address ) (bool , common.Address ) {
453+ if address == newPreRegistryCoston2 && epochID <= breakingEpochCoston2 {
454+ return true , oldPreRegistryCoston2
455+ }
456+
457+ return false , common.Address {}
458+ }
0 commit comments