Skip to content
This repository has been archived by the owner on Sep 23, 2024. It is now read-only.

Commit

Permalink
feat: authorized signers (#110)
Browse files Browse the repository at this point in the history
* Test arbitrary configured signer
* Modify the workflow so we can omit the request when there's a locally configured signer
  • Loading branch information
praetoriansentry authored Mar 30, 2024
1 parent 0268d7d commit f311637
Show file tree
Hide file tree
Showing 5 changed files with 93 additions and 19 deletions.
4 changes: 4 additions & 0 deletions config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,14 @@ const (

type FullNodeRPCs map[uint32]string

// ProofSigners holds the address for authorized signers of proofs for a given rollup ip
type ProofSigners map[uint32]common.Address

// Config represents the full configuration of the data node
type Config struct {
FullNodeRPCs FullNodeRPCs `mapstructure:"FullNodeRPCs"`
RPC jRPC.Config `mapstructure:"RPC"`
ProofSigners ProofSigners `mapstructure:"ProofSigners"`
Log log.Config `mapstructure:"Log"`
DB db.Config `mapstructure:"DB"`
EthTxManager EthTxManagerConfig `mapstructure:"EthTxManager"`
Expand Down
4 changes: 4 additions & 0 deletions config/default.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,10 @@ const DefaultValues = `
WriteTimeout = "60s"
MaxRequestsPerIPAndSecond = 5000
# Address should be adjusted
[ProofSigners]
# 1 = "0x0000000000000000000000000000000000000000"
[Log]
Environment = "development" # "production" or "development"
Level = "debug"
Expand Down
4 changes: 4 additions & 0 deletions docker/data/agglayer/agglayer.toml
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,10 @@
WriteTimeout = "60s"
MaxRequestsPerIPAndSecond = 5000

# Address should be adjusted
[ProofSigners]
# 1 = "0x0000000000000000000000000000000000000000"

[Log]
Environment = "development" # "production" or "development"
Level = "debug"
Expand Down
25 changes: 19 additions & 6 deletions interop/executor.go
Original file line number Diff line number Diff line change
Expand Up @@ -131,12 +131,25 @@ func (e *Executor) verifySignature(stx tx.SignedTx) error {
return errors.New("failed to get signer")
}

sequencer, err := e.etherman.GetSequencerAddr(stx.Tx.RollupID)
if err != nil {
return errors.New("failed to get admin from L1")
}
if sequencer != signer {
return errors.New("unexpected signer")
// Attempt to retrieve the authorized proof signer for the given rollup, if one exists
authorizedProofSigner, hasKey := e.config.ProofSigners[stx.Tx.RollupID]

// If an authorized proof signer is defined and matches the signer, no further checks are needed
if hasKey {
// If an authorized proof signer exists but does not match the signer, return an error.
if authorizedProofSigner != signer {
return fmt.Errorf("unexpected signer: expected authorized signer %s, but got %s", authorizedProofSigner, signer)
}
} else {
sequencer, err := e.etherman.GetSequencerAddr(stx.Tx.RollupID)
if err != nil {
return errors.New("failed to get admin from L1")
}

// If no specific authorized proof signer is defined, fall back to comparing with the sequencer
if sequencer != signer {
return fmt.Errorf("unexpected signer: expected sequencer %s but got %s", sequencer, signer)
}
}

opts := metric.WithAttributes(attribute.Key("rollup_id").Int(int(stx.Tx.RollupID)))
Expand Down
75 changes: 62 additions & 13 deletions interop/executor_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -144,23 +144,72 @@ func TestExecutor_VerifySignature(t *testing.T) {
RollupID: 1,
}

pk, err := crypto.GenerateKey()
sequencerKey, err := crypto.GenerateKey()
require.NoError(t, err)

signedTx, err := txn.Sign(pk)
require.NoError(t, err)
t.Run("use sequencer key, correct signature", func(t *testing.T) {
etherman.On(
"GetSequencerAddr",
uint32(1),
).Return(
crypto.PubkeyToAddress(sequencerKey.PublicKey),
nil,
).Once()

etherman.On(
"GetSequencerAddr",
uint32(1),
).Return(
crypto.PubkeyToAddress(pk.PublicKey),
nil,
).Once()
signedTx, err := txn.Sign(sequencerKey)
require.NoError(t, err)

err = executor.verifySignature(*signedTx)
require.NoError(t, err)
etherman.AssertExpectations(t)
err = executor.verifySignature(*signedTx)
require.NoError(t, err)
etherman.AssertExpectations(t)
})

t.Run("use sequencer key, wrong signature", func(t *testing.T) {
etherman.On(
"GetSequencerAddr",
uint32(1),
).Return(
common.Address{0x1},
nil,
).Once()

signedTx, err := txn.Sign(sequencerKey)
require.NoError(t, err)

err = executor.verifySignature(*signedTx)
require.Error(t, err)
etherman.AssertExpectations(t)
})

t.Run("configured proof signers, correct signature", func(t *testing.T) {
anotherKey, err := crypto.GenerateKey()
require.NoError(t, err)

cfg.ProofSigners = config.ProofSigners{1: crypto.PubkeyToAddress(anotherKey.PublicKey)}

signedTx, err := txn.Sign(anotherKey)
require.NoError(t, err)

executor = New(nil, cfg, interopAdminAddr, etherman, ethTxManager)

err = executor.verifySignature(*signedTx)
require.NoError(t, err)
})

t.Run("configured proof signers, wrong signature", func(t *testing.T) {
anotherKey, err := crypto.GenerateKey()
require.NoError(t, err)

cfg.ProofSigners = config.ProofSigners{1: common.Address{0x1}}

signedTx, err := txn.Sign(anotherKey)
require.NoError(t, err)

executor = New(nil, cfg, interopAdminAddr, etherman, ethTxManager)

err = executor.verifySignature(*signedTx)
require.Error(t, err)
})
}

func TestExecutor_Execute(t *testing.T) {
Expand Down

0 comments on commit f311637

Please sign in to comment.