Skip to content

Commit f9a9348

Browse files
committed
Verify L1 signers per authorized range
1 parent 8e4deb1 commit f9a9348

File tree

2 files changed

+44
-9
lines changed

2 files changed

+44
-9
lines changed

consensus/system_contract/consensus.go

+35-7
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import (
66
"fmt"
77
"io"
88
"math/big"
9+
"sort"
910
"time"
1011

1112
"github.com/scroll-tech/go-ethereum/accounts"
@@ -122,7 +123,7 @@ func (s *SystemContract) verifyHeader(chain consensus.ChainHeaderReader, header
122123
return errInvalidUncleHash
123124
}
124125
// Ensure that the difficulty is one
125-
if header.Difficulty.Cmp(common.Big0) != 1 {
126+
if header.Difficulty.Cmp(common.Big1) != 0 {
126127
return errInvalidDifficulty
127128
}
128129
// Verify that the gas limit is <= 2^63-1
@@ -174,20 +175,48 @@ func (s *SystemContract) verifyCascadingFields(chain consensus.ChainHeaderReader
174175
return err
175176
}
176177

177-
signer, err := ecrecover(header)
178+
if err := s.correctSigner(header); err != nil {
179+
return err
180+
}
181+
return nil
182+
}
183+
184+
// correctSigner checks that the actual block signer matches
185+
// the L1-authorized signer for this block's number.
186+
func (s *SystemContract) correctSigner(header *types.Header) error {
187+
actualSigner, err := ecrecover(header)
178188
if err != nil {
179189
return err
180190
}
181191

182-
s.lock.Lock()
183-
defer s.lock.Unlock()
192+
expectedSigner, err := s.findSignerSlice(header.Number.Uint64())
193+
if err != nil {
194+
return err // e.g. "no signer for block"
195+
}
184196

185-
if signer != s.signerAddressL1 {
197+
if actualSigner != expectedSigner {
186198
return errUnauthorizedSigner
187199
}
188200
return nil
189201
}
190202

203+
func (s *SystemContract) findSignerSlice(blockNum uint64) (common.Address, error) {
204+
// Acquire read-lock before accessing s.signerAddressesL1
205+
s.lock.RLock()
206+
defer s.lock.RUnlock()
207+
transitions := s.signerAddressesL1
208+
idx := sort.Search(len(transitions), func(i int) bool {
209+
// We want the first transition with StartBlock > blockNum
210+
return transitions[i].StartBlock > blockNum
211+
})
212+
// idx is now the insertion point for 'blockNum'
213+
// so the real match is at idx-1 if idx > 0
214+
if idx == 0 {
215+
return common.Address{}, errors.New("no signer for block")
216+
}
217+
return transitions[idx-1].Signer, nil
218+
}
219+
191220
// VerifyUncles implements consensus.Engine, always returning an error for any
192221
// uncles as this consensus mechanism doesn't permit uncles.
193222
func (s *SystemContract) VerifyUncles(chain consensus.ChainReader, block *types.Block) error {
@@ -300,7 +329,6 @@ func SealHash(header *types.Header) (hash common.Hash) {
300329
return hash
301330
}
302331

303-
304332
// ecrecover extracts the Ethereum account address from a signed header.
305333
func ecrecover(header *types.Header) (common.Address, error) {
306334
signature := header.Extra[0:]
@@ -368,4 +396,4 @@ func encodeSigHeader(w io.Writer, header *types.Header) {
368396
if err := rlp.Encode(w, enc); err != nil {
369397
panic("can't encode: " + err.Error())
370398
}
371-
}
399+
}

consensus/system_contract/system_contract.go

+9-2
Original file line numberDiff line numberDiff line change
@@ -16,12 +16,18 @@ const (
1616
defaultSyncInterval = 10
1717
)
1818

19+
type SignerAddressL1 struct {
20+
StartBlock uint64
21+
Signer common.Address
22+
}
23+
1924
// SystemContract
2025
type SystemContract struct {
2126
config *params.SystemContractConfig // Consensus engine configuration parameters
2227
client sync_service.EthClient
2328

24-
signerAddressL1 common.Address // Address of the signer stored in L1 System Contract
29+
signerAddressL1 common.Address // Address of the signer stored in L1 System Contract
30+
signerAddressesL1 []SignerAddressL1
2531

2632
signer common.Address // Ethereum address of the signing key
2733
signFn SignerFn // Signer function to authorize hashes with
@@ -77,6 +83,7 @@ func (s *SystemContract) Start() {
7783
case <-s.ctx.Done():
7884
return
7985
case <-syncTicker.C:
86+
//TODO here
8087
blockNumber := big.NewInt(-1) // todo: get block number from L1BlocksContract (l1 block hash relay) or other source (depending on exact design)
8188
address, err := s.client.StorageAt(s.ctx, s.config.SystemContractAddress, s.config.SystemContractSlot, blockNumber)
8289
if err != nil {
@@ -94,4 +101,4 @@ func (s *SystemContract) Start() {
94101
func (s *SystemContract) Close() error {
95102
s.cancel()
96103
return nil
97-
}
104+
}

0 commit comments

Comments
 (0)