diff --git a/core/genesis.go b/core/genesis.go index 1d17f298a4fb3..57a94cc430500 100644 --- a/core/genesis.go +++ b/core/genesis.go @@ -44,6 +44,12 @@ import ( var errGenesisNoConfig = errors.New("genesis has no chain configuration") +// Various checks on genesis extradata +var ( + extraVanity = 32 // Fixed number of extra-data prefix bytes reserved for signer vanity + extraSeal = crypto.SignatureLength // Fixed number of extra-data suffix bytes reserved for signer seal +) + // Genesis specifies the header fields, state of a genesis block. It also defines hard // fork switch-over blocks through the chain configuration. type Genesis struct { @@ -324,8 +330,13 @@ func (g *Genesis) Commit(db ethdb.Database) (*types.Block, error) { if err := config.CheckConfigForkOrder(); err != nil { return nil, err } - if config.Clique != nil && len(block.Extra()) == 0 { - return nil, errors.New("can't start clique chain without signers") + if config.Clique != nil { + if len(block.Extra()) < extraVanity { + return nil, errors.New("extra-data 32 byte vanity prefix missing") + } + if len(block.Extra()) < extraVanity+extraSeal { + return nil, errors.New("extra-data 65 byte signature suffix missing") + } } rawdb.WriteTd(db, block.Hash(), block.NumberU64(), block.Difficulty()) rawdb.WriteBlock(db, block) diff --git a/rlp/encbuffer.go b/rlp/encbuffer.go index 0e200a9a33bbe..50b83099c3496 100644 --- a/rlp/encbuffer.go +++ b/rlp/encbuffer.go @@ -118,6 +118,10 @@ func (buf *encBuffer) writeBytes(b []byte) { } } +func (buf *encBuffer) writeString(s string) { + buf.writeBytes([]byte(s)) +} + // wordBytes is the number of bytes in a big.Word const wordBytes = (32 << (uint64(^big.Word(0)) >> 63)) / 8 @@ -340,6 +344,11 @@ func (w EncoderBuffer) WriteBytes(b []byte) { w.buf.writeBytes(b) } +// WriteBytes encodes s as an RLP string. +func (w EncoderBuffer) WriteString(s string) { + w.buf.writeString(s) +} + // List starts a list. It returns an internal index. Call EndList with // this index after encoding the content to finish the list. func (w EncoderBuffer) List() int {