6
6
"fmt"
7
7
"io"
8
8
"math/big"
9
+ "sort"
9
10
"time"
10
11
11
12
"github.com/scroll-tech/go-ethereum/accounts"
@@ -122,7 +123,7 @@ func (s *SystemContract) verifyHeader(chain consensus.ChainHeaderReader, header
122
123
return errInvalidUncleHash
123
124
}
124
125
// Ensure that the difficulty is one
125
- if header .Difficulty .Cmp (common .Big0 ) != 1 {
126
+ if header .Difficulty .Cmp (common .Big1 ) != 0 {
126
127
return errInvalidDifficulty
127
128
}
128
129
// Verify that the gas limit is <= 2^63-1
@@ -174,20 +175,48 @@ func (s *SystemContract) verifyCascadingFields(chain consensus.ChainHeaderReader
174
175
return err
175
176
}
176
177
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 )
178
188
if err != nil {
179
189
return err
180
190
}
181
191
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
+ }
184
196
185
- if signer != s . signerAddressL1 {
197
+ if actualSigner != expectedSigner {
186
198
return errUnauthorizedSigner
187
199
}
188
200
return nil
189
201
}
190
202
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
+
191
220
// VerifyUncles implements consensus.Engine, always returning an error for any
192
221
// uncles as this consensus mechanism doesn't permit uncles.
193
222
func (s * SystemContract ) VerifyUncles (chain consensus.ChainReader , block * types.Block ) error {
@@ -300,7 +329,6 @@ func SealHash(header *types.Header) (hash common.Hash) {
300
329
return hash
301
330
}
302
331
303
-
304
332
// ecrecover extracts the Ethereum account address from a signed header.
305
333
func ecrecover (header * types.Header ) (common.Address , error ) {
306
334
signature := header .Extra [0 :]
@@ -368,4 +396,4 @@ func encodeSigHeader(w io.Writer, header *types.Header) {
368
396
if err := rlp .Encode (w , enc ); err != nil {
369
397
panic ("can't encode: " + err .Error ())
370
398
}
371
- }
399
+ }
0 commit comments