Skip to content

Commit

Permalink
Split BEEFY relayer into two separate relayers (#1216)
Browse files Browse the repository at this point in the history
Co-authored-by: ron <[email protected]>
  • Loading branch information
vgeddes and yrong authored Jun 4, 2024
1 parent ed49363 commit a0c1c47
Show file tree
Hide file tree
Showing 12 changed files with 460 additions and 288 deletions.
6 changes: 3 additions & 3 deletions contracts/foundry.toml
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
[profile.default]
solc_version = "0.8.25"
optimizer = true
optimizer_runs = 200
via_ir = true
optimizer_runs = 20000
via_ir = false
test = 'test'
script = 'scripts'
fs_permissions = [{ access = "read-write", path = "test/data" }, { access = "read", path = "./" }]
Expand All @@ -13,7 +13,7 @@ ignored_error_codes = [
]

[profile.production]
optimizer_runs = 20_000
via_ir = true

[profile.production.etherscan]
mainnet = { key = "${ETHERSCAN_API_KEY}" }
2 changes: 1 addition & 1 deletion contracts/scripts/deploy.sh
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

set -eux

forge script "scripts/Deploy.sol:${1}" \
forge script "scripts/DeployBeefyClient.sol:DeployBeefyClient" \
--chain-id 1 \
--rpc-url "${MAINNET_RPC_URL}" \
--ledger \
Expand Down
1 change: 1 addition & 0 deletions relayer/cmd/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ func init() {
rootCmd.AddCommand(storeBeaconStateCmd())
rootCmd.AddCommand(importBeaconStateCmd())
rootCmd.AddCommand(listBeaconStateCmd())
rootCmd.AddCommand(syncBeefyCommitmentCmd())
}

func Execute() {
Expand Down
7 changes: 3 additions & 4 deletions relayer/cmd/scan_beefy.go
Original file line number Diff line number Diff line change
Expand Up @@ -55,10 +55,9 @@ func ScanBeefyFn(cmd *cobra.Command, _ []string) error {
beefyBlock, _ := cmd.Flags().GetUint64("beefy-block")
validatorSetID, _ := cmd.Flags().GetUint64("validator-set-id")
logrus.WithFields(logrus.Fields{
"polkadot-url": polkadotUrl,
"fast-forward-depth": fastForwardDepth,
"beefy-block": beefyBlock,
"validator-set-id": validatorSetID,
"polkadot-url": polkadotUrl,
"beefy-block": beefyBlock,
"validator-set-id": validatorSetID,
}).Info("Connected to relaychain.")

commitments, err := polkadotListener.Start(ctx, eg, beefyBlock, validatorSetID)
Expand Down
64 changes: 64 additions & 0 deletions relayer/cmd/sync_beefy_commitment.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
package cmd

import (
"fmt"
"log"

"github.com/sirupsen/logrus"
"github.com/snowfork/snowbridge/relayer/chain/ethereum"
"github.com/snowfork/snowbridge/relayer/relays/beefy"
"github.com/spf13/cobra"
"github.com/spf13/viper"
)

func syncBeefyCommitmentCmd() *cobra.Command {
cmd := &cobra.Command{
Use: "sync-latest-beefy-commitment",
Short: "Sync beefy commitment on demand",
Args: cobra.ExactArgs(0),
RunE: SyncBeefyCommitmentFn,
}

cmd.Flags().String("config", "/tmp/snowbridge/beefy-relay.json", "Path to configuration file")
cmd.Flags().String("private-key", "", "Ethereum private key")
cmd.Flags().String("private-key-file", "", "The file from which to read the private key")
cmd.Flags().Uint64P("block-number", "b", 0, "Relay block number which contains a Parachain message")
cmd.MarkFlagRequired("block-number")
return cmd
}

func SyncBeefyCommitmentFn(cmd *cobra.Command, _ []string) error {
ctx := cmd.Context()

log.SetOutput(logrus.WithFields(logrus.Fields{"logger": "stdlib"}).WriterLevel(logrus.InfoLevel))
logrus.SetLevel(logrus.DebugLevel)

configFile, err := cmd.Flags().GetString("config")
viper.SetConfigFile(configFile)
if err := viper.ReadInConfig(); err != nil {
return err
}

var config beefy.Config
err = viper.Unmarshal(&config)
if err != nil {
return err
}
privateKey, _ := cmd.Flags().GetString("private-key")
privateKeyFile, _ := cmd.Flags().GetString("private-key-file")
if privateKey == "" && privateKeyFile == "" {
return fmt.Errorf("missing private key")
}
keypair, err := ethereum.ResolvePrivateKey(privateKey, privateKeyFile)
if err != nil {
return err
}

relay, err := beefy.NewRelay(&config, keypair)
if err != nil {
return err
}
blockNumber, _ := cmd.Flags().GetUint64("block-number")
err = relay.OneShotSync(ctx, blockNumber)
return err
}
92 changes: 62 additions & 30 deletions relayer/relays/beefy/ethereum-writer.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,23 +40,6 @@ func NewEthereumWriter(
}

func (wr *EthereumWriter) Start(ctx context.Context, eg *errgroup.Group, requests <-chan Request) error {
address := common.HexToAddress(wr.config.Contracts.BeefyClient)
contract, err := contracts.NewBeefyClient(address, wr.conn.Client())
if err != nil {
return fmt.Errorf("create beefy client: %w", err)
}
wr.contract = contract

callOpts := bind.CallOpts{
Context: ctx,
}
blockWaitPeriod, err := wr.contract.RandaoCommitDelay(&callOpts)
if err != nil {
return fmt.Errorf("create randao commit delay: %w", err)
}
wr.blockWaitPeriod = blockWaitPeriod.Uint64()
log.WithField("randaoCommitDelay", wr.blockWaitPeriod).Trace("Fetched randaoCommitDelay")

// launch task processor
eg.Go(func() error {
for {
Expand All @@ -68,7 +51,24 @@ func (wr *EthereumWriter) Start(ctx context.Context, eg *errgroup.Group, request
return nil
}

err := wr.submit(ctx, task)
state, err := wr.queryBeefyClientState(ctx)
if err != nil {
return fmt.Errorf("query beefy client state: %w", err)
}

if task.SignedCommitment.Commitment.BlockNumber < uint32(state.LatestBeefyBlock) {
log.WithFields(logrus.Fields{
"beefyBlockNumber": task.SignedCommitment.Commitment.BlockNumber,
"latestBeefyBlock": state.LatestBeefyBlock,
}).Info("Commitment already synced")
continue
}

// Mandatory commitments are always signed by the next validator set recorded in
// the beefy light client
task.ValidatorsRoot = state.NextValidatorSetRoot

err = wr.submit(ctx, task)
if err != nil {
return fmt.Errorf("submit request: %w", err)
}
Expand All @@ -79,32 +79,43 @@ func (wr *EthereumWriter) Start(ctx context.Context, eg *errgroup.Group, request
return nil
}

func (wr *EthereumWriter) submit(ctx context.Context, task Request) error {
type BeefyClientState struct {
LatestBeefyBlock uint64
CurrentValidatorSetID uint64
CurrentValidatorSetRoot [32]byte
NextValidatorSetID uint64
NextValidatorSetRoot [32]byte
}

func (wr *EthereumWriter) queryBeefyClientState(ctx context.Context) (*BeefyClientState, error) {
callOpts := bind.CallOpts{
Context: ctx,
}

latestBeefyBlock, err := wr.contract.LatestBeefyBlock(&callOpts)
if err != nil {
return err
}
if uint32(latestBeefyBlock) >= task.SignedCommitment.Commitment.BlockNumber {
return nil
return nil, err
}

currentValidatorSet, err := wr.contract.CurrentValidatorSet(&callOpts)
if err != nil {
return err
return nil, err
}
nextValidatorSet, err := wr.contract.NextValidatorSet(&callOpts)
if err != nil {
return err
}
task.ValidatorsRoot = currentValidatorSet.Root
if task.IsHandover {
task.ValidatorsRoot = nextValidatorSet.Root
return nil, err
}

return &BeefyClientState{
LatestBeefyBlock: latestBeefyBlock,
CurrentValidatorSetID: currentValidatorSet.Id.Uint64(),
CurrentValidatorSetRoot: currentValidatorSet.Root,
NextValidatorSetID: nextValidatorSet.Id.Uint64(),
NextValidatorSetRoot: nextValidatorSet.Root,
}, nil
}

func (wr *EthereumWriter) submit(ctx context.Context, task Request) error {
// Initial submission
tx, initialBitfield, err := wr.doSubmitInitial(ctx, &task)
if err != nil {
Expand All @@ -131,6 +142,7 @@ func (wr *EthereumWriter) submit(ctx context.Context, task Request) error {
wr.conn.MakeTxOpts(ctx),
*commitmentHash,
)

_, err = wr.conn.WatchTransaction(ctx, tx, 1)
if err != nil {
log.WithError(err).Error("Failed to CommitPrevRandao")
Expand All @@ -153,7 +165,6 @@ func (wr *EthereumWriter) submit(ctx context.Context, task Request) error {
log.WithFields(logrus.Fields{
"tx": tx.Hash().Hex(),
"blockNumber": task.SignedCommitment.Commitment.BlockNumber,
"IsHandover": task.IsHandover,
}).Debug("Transaction SubmitFinal succeeded")

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

return tx, nil
}

func (wr *EthereumWriter) initialize(ctx context.Context) error {
address := common.HexToAddress(wr.config.Contracts.BeefyClient)
contract, err := contracts.NewBeefyClient(address, wr.conn.Client())
if err != nil {
return fmt.Errorf("create beefy client: %w", err)
}
wr.contract = contract

callOpts := bind.CallOpts{
Context: ctx,
}
blockWaitPeriod, err := wr.contract.RandaoCommitDelay(&callOpts)
if err != nil {
return fmt.Errorf("create randao commit delay: %w", err)
}
wr.blockWaitPeriod = blockWaitPeriod.Uint64()
log.WithField("randaoCommitDelay", wr.blockWaitPeriod).Trace("Fetched randaoCommitDelay")

return nil
}
1 change: 0 additions & 1 deletion relayer/relays/beefy/fixture-data-logger.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,6 @@ func (wr *EthereumWriter) makeSubmitFinalLogFields(
"leafProofOrder": params.LeafProofOrder,
},
"commitmentHash": commitmentHash,
"handover": task.IsHandover,
}

return fields, nil
Expand Down
Loading

0 comments on commit a0c1c47

Please sign in to comment.