Skip to content

Commit c576744

Browse files
vgeddesyrong
andcommitted
Split BEEFY relayer into two separate relayers (#1216)
Co-authored-by: ron <[email protected]>
1 parent 7f10895 commit c576744

12 files changed

+483
-291
lines changed

contracts/foundry.toml

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,19 @@
11
[profile.default]
2-
solc_version = "0.8.23"
2+
solc_version = "0.8.25"
33
optimizer = true
4-
optimizer_runs = 20_000
5-
via_ir = true
4+
optimizer_runs = 20000
5+
via_ir = false
66
test = 'test'
7-
fs_permissions = [{ access = "read-write", path = "test/data"}, { access = "read", path = "./"}]
7+
script = 'scripts'
8+
fs_permissions = [{ access = "read-write", path = "test/data" }, { access = "read", path = "./" }]
89

910
ignored_error_codes = [
10-
# DeployScript.sol is never deployed
11-
5574
11+
# DeployLocal.sol is never deployed
12+
5574,
1213
]
1314

14-
# no_match_test = "testRegenerateBitField"
15+
[profile.production]
16+
via_ir = true
17+
18+
[profile.production.etherscan]
19+
mainnet = { key = "${ETHERSCAN_API_KEY}" }

contracts/scripts/deploy.sh

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
#!/usr/bin/env bash
2+
3+
set -eux
4+
5+
forge script "scripts/DeployBeefyClient.sol:DeployBeefyClient" \
6+
--chain-id 1 \
7+
--rpc-url "${MAINNET_RPC_URL}" \
8+
--ledger \
9+
--mnemonic-derivation-paths "${MNEMONIC_DERIVATION_PATH}" \
10+
--broadcast \
11+
--verify \
12+
--optimize \
13+
--via-ir \
14+
--optimizer-runs 100000 \
15+
-vvvv

relayer/cmd/root.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ func init() {
3535
rootCmd.AddCommand(storeBeaconStateCmd())
3636
rootCmd.AddCommand(importBeaconStateCmd())
3737
rootCmd.AddCommand(listBeaconStateCmd())
38+
rootCmd.AddCommand(syncBeefyCommitmentCmd())
3839
}
3940

4041
func Execute() {

relayer/cmd/scan_beefy.go

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -55,10 +55,9 @@ func ScanBeefyFn(cmd *cobra.Command, _ []string) error {
5555
beefyBlock, _ := cmd.Flags().GetUint64("beefy-block")
5656
validatorSetID, _ := cmd.Flags().GetUint64("validator-set-id")
5757
logrus.WithFields(logrus.Fields{
58-
"polkadot-url": polkadotUrl,
59-
"fast-forward-depth": fastForwardDepth,
60-
"beefy-block": beefyBlock,
61-
"validator-set-id": validatorSetID,
58+
"polkadot-url": polkadotUrl,
59+
"beefy-block": beefyBlock,
60+
"validator-set-id": validatorSetID,
6261
}).Info("Connected to relaychain.")
6362

6463
commitments, err := polkadotListener.Start(ctx, eg, beefyBlock, validatorSetID)

relayer/cmd/sync_beefy_commitment.go

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
package cmd
2+
3+
import (
4+
"fmt"
5+
"log"
6+
7+
"github.com/sirupsen/logrus"
8+
"github.com/snowfork/snowbridge/relayer/chain/ethereum"
9+
"github.com/snowfork/snowbridge/relayer/relays/beefy"
10+
"github.com/spf13/cobra"
11+
"github.com/spf13/viper"
12+
)
13+
14+
func syncBeefyCommitmentCmd() *cobra.Command {
15+
cmd := &cobra.Command{
16+
Use: "sync-latest-beefy-commitment",
17+
Short: "Sync beefy commitment on demand",
18+
Args: cobra.ExactArgs(0),
19+
RunE: SyncBeefyCommitmentFn,
20+
}
21+
22+
cmd.Flags().String("config", "/tmp/snowbridge/beefy-relay.json", "Path to configuration file")
23+
cmd.Flags().String("private-key", "", "Ethereum private key")
24+
cmd.Flags().String("private-key-file", "", "The file from which to read the private key")
25+
cmd.Flags().Uint64P("block-number", "b", 0, "Relay block number which contains a Parachain message")
26+
cmd.MarkFlagRequired("block-number")
27+
return cmd
28+
}
29+
30+
func SyncBeefyCommitmentFn(cmd *cobra.Command, _ []string) error {
31+
ctx := cmd.Context()
32+
33+
log.SetOutput(logrus.WithFields(logrus.Fields{"logger": "stdlib"}).WriterLevel(logrus.InfoLevel))
34+
logrus.SetLevel(logrus.DebugLevel)
35+
36+
configFile, err := cmd.Flags().GetString("config")
37+
viper.SetConfigFile(configFile)
38+
if err := viper.ReadInConfig(); err != nil {
39+
return err
40+
}
41+
42+
var config beefy.Config
43+
err = viper.Unmarshal(&config)
44+
if err != nil {
45+
return err
46+
}
47+
privateKey, _ := cmd.Flags().GetString("private-key")
48+
privateKeyFile, _ := cmd.Flags().GetString("private-key-file")
49+
if privateKey == "" && privateKeyFile == "" {
50+
return fmt.Errorf("missing private key")
51+
}
52+
keypair, err := ethereum.ResolvePrivateKey(privateKey, privateKeyFile)
53+
if err != nil {
54+
return err
55+
}
56+
57+
relay, err := beefy.NewRelay(&config, keypair)
58+
if err != nil {
59+
return err
60+
}
61+
blockNumber, _ := cmd.Flags().GetUint64("block-number")
62+
err = relay.OneShotSync(ctx, blockNumber)
63+
return err
64+
}

relayer/relays/beefy/ethereum-writer.go

Lines changed: 62 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -40,23 +40,6 @@ func NewEthereumWriter(
4040
}
4141

4242
func (wr *EthereumWriter) Start(ctx context.Context, eg *errgroup.Group, requests <-chan Request) error {
43-
address := common.HexToAddress(wr.config.Contracts.BeefyClient)
44-
contract, err := contracts.NewBeefyClient(address, wr.conn.Client())
45-
if err != nil {
46-
return fmt.Errorf("create beefy client: %w", err)
47-
}
48-
wr.contract = contract
49-
50-
callOpts := bind.CallOpts{
51-
Context: ctx,
52-
}
53-
blockWaitPeriod, err := wr.contract.RandaoCommitDelay(&callOpts)
54-
if err != nil {
55-
return fmt.Errorf("create randao commit delay: %w", err)
56-
}
57-
wr.blockWaitPeriod = blockWaitPeriod.Uint64()
58-
log.WithField("randaoCommitDelay", wr.blockWaitPeriod).Trace("Fetched randaoCommitDelay")
59-
6043
// launch task processor
6144
eg.Go(func() error {
6245
for {
@@ -68,7 +51,24 @@ func (wr *EthereumWriter) Start(ctx context.Context, eg *errgroup.Group, request
6851
return nil
6952
}
7053

71-
err := wr.submit(ctx, task)
54+
state, err := wr.queryBeefyClientState(ctx)
55+
if err != nil {
56+
return fmt.Errorf("query beefy client state: %w", err)
57+
}
58+
59+
if task.SignedCommitment.Commitment.BlockNumber < uint32(state.LatestBeefyBlock) {
60+
log.WithFields(logrus.Fields{
61+
"beefyBlockNumber": task.SignedCommitment.Commitment.BlockNumber,
62+
"latestBeefyBlock": state.LatestBeefyBlock,
63+
}).Info("Commitment already synced")
64+
continue
65+
}
66+
67+
// Mandatory commitments are always signed by the next validator set recorded in
68+
// the beefy light client
69+
task.ValidatorsRoot = state.NextValidatorSetRoot
70+
71+
err = wr.submit(ctx, task)
7272
if err != nil {
7373
return fmt.Errorf("submit request: %w", err)
7474
}
@@ -79,32 +79,43 @@ func (wr *EthereumWriter) Start(ctx context.Context, eg *errgroup.Group, request
7979
return nil
8080
}
8181

82-
func (wr *EthereumWriter) submit(ctx context.Context, task Request) error {
82+
type BeefyClientState struct {
83+
LatestBeefyBlock uint64
84+
CurrentValidatorSetID uint64
85+
CurrentValidatorSetRoot [32]byte
86+
NextValidatorSetID uint64
87+
NextValidatorSetRoot [32]byte
88+
}
89+
90+
func (wr *EthereumWriter) queryBeefyClientState(ctx context.Context) (*BeefyClientState, error) {
8391
callOpts := bind.CallOpts{
8492
Context: ctx,
8593
}
8694

8795
latestBeefyBlock, err := wr.contract.LatestBeefyBlock(&callOpts)
8896
if err != nil {
89-
return err
90-
}
91-
if uint32(latestBeefyBlock) >= task.SignedCommitment.Commitment.BlockNumber {
92-
return nil
97+
return nil, err
9398
}
9499

95100
currentValidatorSet, err := wr.contract.CurrentValidatorSet(&callOpts)
96101
if err != nil {
97-
return err
102+
return nil, err
98103
}
99104
nextValidatorSet, err := wr.contract.NextValidatorSet(&callOpts)
100105
if err != nil {
101-
return err
102-
}
103-
task.ValidatorsRoot = currentValidatorSet.Root
104-
if task.IsHandover {
105-
task.ValidatorsRoot = nextValidatorSet.Root
106+
return nil, err
106107
}
107108

109+
return &BeefyClientState{
110+
LatestBeefyBlock: latestBeefyBlock,
111+
CurrentValidatorSetID: currentValidatorSet.Id.Uint64(),
112+
CurrentValidatorSetRoot: currentValidatorSet.Root,
113+
NextValidatorSetID: nextValidatorSet.Id.Uint64(),
114+
NextValidatorSetRoot: nextValidatorSet.Root,
115+
}, nil
116+
}
117+
118+
func (wr *EthereumWriter) submit(ctx context.Context, task Request) error {
108119
// Initial submission
109120
tx, initialBitfield, err := wr.doSubmitInitial(ctx, &task)
110121
if err != nil {
@@ -131,6 +142,7 @@ func (wr *EthereumWriter) submit(ctx context.Context, task Request) error {
131142
wr.conn.MakeTxOpts(ctx),
132143
*commitmentHash,
133144
)
145+
134146
_, err = wr.conn.WatchTransaction(ctx, tx, 1)
135147
if err != nil {
136148
log.WithError(err).Error("Failed to CommitPrevRandao")
@@ -153,7 +165,6 @@ func (wr *EthereumWriter) submit(ctx context.Context, task Request) error {
153165
log.WithFields(logrus.Fields{
154166
"tx": tx.Hash().Hex(),
155167
"blockNumber": task.SignedCommitment.Commitment.BlockNumber,
156-
"IsHandover": task.IsHandover,
157168
}).Debug("Transaction SubmitFinal succeeded")
158169

159170
return nil
@@ -267,3 +278,24 @@ func (wr *EthereumWriter) doSubmitFinal(ctx context.Context, commitmentHash [32]
267278

268279
return tx, nil
269280
}
281+
282+
func (wr *EthereumWriter) initialize(ctx context.Context) error {
283+
address := common.HexToAddress(wr.config.Contracts.BeefyClient)
284+
contract, err := contracts.NewBeefyClient(address, wr.conn.Client())
285+
if err != nil {
286+
return fmt.Errorf("create beefy client: %w", err)
287+
}
288+
wr.contract = contract
289+
290+
callOpts := bind.CallOpts{
291+
Context: ctx,
292+
}
293+
blockWaitPeriod, err := wr.contract.RandaoCommitDelay(&callOpts)
294+
if err != nil {
295+
return fmt.Errorf("create randao commit delay: %w", err)
296+
}
297+
wr.blockWaitPeriod = blockWaitPeriod.Uint64()
298+
log.WithField("randaoCommitDelay", wr.blockWaitPeriod).Trace("Fetched randaoCommitDelay")
299+
300+
return nil
301+
}

relayer/relays/beefy/fixture-data-logger.go

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,6 @@ func (wr *EthereumWriter) makeSubmitFinalLogFields(
4848
"leafProofOrder": params.LeafProofOrder,
4949
},
5050
"commitmentHash": commitmentHash,
51-
"handover": task.IsHandover,
5251
}
5352

5453
return fields, nil

0 commit comments

Comments
 (0)