Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Split BEEFY relayer into two separate relayers #1216

Merged
merged 11 commits into from
Jun 4, 2024
Merged
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
Loading