github.com/Blockdaemon/celo-blockchain@v0.0.0-20200129231733-e667f6b08419/consensus/istanbul/backend/engine_test.go (about)

     1  // Copyright 2017 The go-ethereum Authors
     2  // This file is part of the go-ethereum library.
     3  //
     4  // The go-ethereum library is free software: you can redistribute it and/or modify
     5  // it under the terms of the GNU Lesser General Public License as published by
     6  // the Free Software Foundation, either version 3 of the License, or
     7  // (at your option) any later version.
     8  //
     9  // The go-ethereum library is distributed in the hope that it will be useful,
    10  // but WITHOUT ANY WARRANTY; without even the implied warranty of
    11  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
    12  // GNU Lesser General Public License for more details.
    13  //
    14  // You should have received a copy of the GNU Lesser General Public License
    15  // along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
    16  
    17  package backend
    18  
    19  import (
    20  	"bytes"
    21  	"crypto/ecdsa"
    22  	"fmt"
    23  	"math/big"
    24  	"reflect"
    25  	"testing"
    26  	"time"
    27  
    28  	bls "github.com/celo-org/bls-zexe/go"
    29  	"github.com/ethereum/go-ethereum/accounts"
    30  	"github.com/ethereum/go-ethereum/common"
    31  	"github.com/ethereum/go-ethereum/common/hexutil"
    32  	"github.com/ethereum/go-ethereum/consensus"
    33  	"github.com/ethereum/go-ethereum/consensus/consensustest"
    34  	"github.com/ethereum/go-ethereum/consensus/istanbul"
    35  	"github.com/ethereum/go-ethereum/contract_comm"
    36  	"github.com/ethereum/go-ethereum/core"
    37  	"github.com/ethereum/go-ethereum/core/state"
    38  	"github.com/ethereum/go-ethereum/core/types"
    39  	"github.com/ethereum/go-ethereum/core/vm"
    40  	"github.com/ethereum/go-ethereum/crypto"
    41  	blscrypto "github.com/ethereum/go-ethereum/crypto/bls"
    42  	"github.com/ethereum/go-ethereum/ethdb"
    43  	"github.com/ethereum/go-ethereum/params"
    44  	"github.com/ethereum/go-ethereum/rlp"
    45  )
    46  
    47  // in this test, we can set n to 1, and it means we can process Istanbul and commit a
    48  // block by one node. Otherwise, if n is larger than 1, we have to generate
    49  // other fake events to process Istanbul.
    50  func newBlockChain(n int, isFullChain bool) (*core.BlockChain, *Backend) {
    51  	genesis, nodeKeys := getGenesisAndKeys(n, isFullChain)
    52  	memDB := ethdb.NewMemDatabase()
    53  	config := istanbul.DefaultConfig
    54  	config.ValidatorEnodeDBPath = ""
    55  	config.RoundStateDBPath = ""
    56  	// Use the first key as private key
    57  	address := crypto.PubkeyToAddress(nodeKeys[0].PublicKey)
    58  	signerFn := func(_ accounts.Account, data []byte) ([]byte, error) {
    59  		return crypto.Sign(data, nodeKeys[0])
    60  	}
    61  
    62  	signerBLSHashFn := func(_ accounts.Account, data []byte) (blscrypto.SerializedSignature, error) {
    63  		key := nodeKeys[0]
    64  		privateKeyBytes, err := blscrypto.ECDSAToBLS(key)
    65  		if err != nil {
    66  			return blscrypto.SerializedSignature{}, err
    67  		}
    68  
    69  		privateKey, err := bls.DeserializePrivateKey(privateKeyBytes)
    70  		if err != nil {
    71  			return blscrypto.SerializedSignature{}, err
    72  		}
    73  		defer privateKey.Destroy()
    74  
    75  		signature, err := privateKey.SignMessage(data, []byte{}, false)
    76  		if err != nil {
    77  			return blscrypto.SerializedSignature{}, err
    78  		}
    79  		defer signature.Destroy()
    80  		signatureBytes, err := signature.Serialize()
    81  		if err != nil {
    82  			return blscrypto.SerializedSignature{}, err
    83  		}
    84  
    85  		return blscrypto.SerializedSignatureFromBytes(signatureBytes)
    86  	}
    87  
    88  	signerBLSMessageFn := func(_ accounts.Account, data []byte, extraData []byte) (blscrypto.SerializedSignature, error) {
    89  		key := nodeKeys[0]
    90  		privateKeyBytes, err := blscrypto.ECDSAToBLS(key)
    91  		if err != nil {
    92  			return blscrypto.SerializedSignature{}, err
    93  		}
    94  
    95  		privateKey, err := bls.DeserializePrivateKey(privateKeyBytes)
    96  		if err != nil {
    97  			return blscrypto.SerializedSignature{}, err
    98  		}
    99  		defer privateKey.Destroy()
   100  
   101  		signature, err := privateKey.SignMessage(data, extraData, true)
   102  		if err != nil {
   103  			return blscrypto.SerializedSignature{}, err
   104  		}
   105  		defer signature.Destroy()
   106  		signatureBytes, err := signature.Serialize()
   107  		if err != nil {
   108  			return blscrypto.SerializedSignature{}, err
   109  		}
   110  
   111  		return blscrypto.SerializedSignatureFromBytes(signatureBytes)
   112  	}
   113  
   114  	b, _ := New(config, memDB).(*Backend)
   115  	b.Authorize(address, signerFn, signerBLSHashFn, signerBLSMessageFn)
   116  
   117  	genesis.MustCommit(memDB)
   118  
   119  	blockchain, err := core.NewBlockChain(memDB, nil, genesis.Config, b, vm.Config{}, nil)
   120  	if err != nil {
   121  		panic(err)
   122  	}
   123  
   124  	b.SetChain(blockchain, blockchain.CurrentBlock)
   125  	b.SetBroadcaster(&consensustest.MockBroadcaster{})
   126  	b.SetP2PServer(consensustest.NewMockP2PServer())
   127  
   128  	b.Start(blockchain.HasBadBlock,
   129  		func(parentHash common.Hash) (*state.StateDB, error) {
   130  			parentStateRoot := blockchain.GetHeaderByHash(parentHash).Root
   131  			return blockchain.StateAt(parentStateRoot)
   132  		},
   133  		func(block *types.Block, state *state.StateDB) (types.Receipts, []*types.Log, uint64, error) {
   134  			return blockchain.Processor().Process(block, state, *blockchain.GetVMConfig())
   135  		},
   136  		func(block *types.Block, state *state.StateDB, receipts types.Receipts, usedGas uint64) error {
   137  			return blockchain.Validator().ValidateState(block, nil, state, receipts, usedGas)
   138  		})
   139  	snap, err := b.snapshot(blockchain, 0, common.Hash{}, nil)
   140  	if err != nil {
   141  		panic(err)
   142  	}
   143  	if snap == nil {
   144  		panic("failed to get snapshot")
   145  	}
   146  	proposerAddr := b.AuthorForBlock(snap.Number)
   147  	// proposerAddr := snap.ValSet.GetProposer().Address()
   148  
   149  	// find proposer key
   150  	for _, key := range nodeKeys {
   151  		addr := crypto.PubkeyToAddress(key.PublicKey)
   152  		if addr.String() == proposerAddr.String() {
   153  			signerFn := func(_ accounts.Account, data []byte) ([]byte, error) {
   154  				return crypto.Sign(data, key)
   155  			}
   156  			signerBLSHashFn := func(_ accounts.Account, data []byte) (blscrypto.SerializedSignature, error) {
   157  				privateKeyBytes, err := blscrypto.ECDSAToBLS(key)
   158  				if err != nil {
   159  					return blscrypto.SerializedSignature{}, err
   160  				}
   161  
   162  				privateKey, err := bls.DeserializePrivateKey(privateKeyBytes)
   163  				if err != nil {
   164  					return blscrypto.SerializedSignature{}, err
   165  				}
   166  				defer privateKey.Destroy()
   167  
   168  				signature, err := privateKey.SignMessage(data, []byte{}, false)
   169  				if err != nil {
   170  					return blscrypto.SerializedSignature{}, err
   171  				}
   172  				defer signature.Destroy()
   173  				signatureBytes, err := signature.Serialize()
   174  				if err != nil {
   175  					return blscrypto.SerializedSignature{}, err
   176  				}
   177  
   178  				return blscrypto.SerializedSignatureFromBytes(signatureBytes)
   179  			}
   180  
   181  			signerBLSMessageFn := func(_ accounts.Account, data []byte, extraData []byte) (blscrypto.SerializedSignature, error) {
   182  				privateKeyBytes, err := blscrypto.ECDSAToBLS(key)
   183  				if err != nil {
   184  					return blscrypto.SerializedSignature{}, err
   185  				}
   186  
   187  				privateKey, err := bls.DeserializePrivateKey(privateKeyBytes)
   188  				if err != nil {
   189  					return blscrypto.SerializedSignature{}, err
   190  				}
   191  				defer privateKey.Destroy()
   192  
   193  				signature, err := privateKey.SignMessage(data, extraData, true)
   194  				if err != nil {
   195  					return blscrypto.SerializedSignature{}, err
   196  				}
   197  				defer signature.Destroy()
   198  				signatureBytes, err := signature.Serialize()
   199  				if err != nil {
   200  					return blscrypto.SerializedSignature{}, err
   201  				}
   202  
   203  				return blscrypto.SerializedSignatureFromBytes(signatureBytes)
   204  			}
   205  
   206  			b.Authorize(address, signerFn, signerBLSHashFn, signerBLSMessageFn)
   207  			break
   208  		}
   209  	}
   210  
   211  	contract_comm.SetInternalEVMHandler(blockchain)
   212  
   213  	return blockchain, b
   214  }
   215  
   216  func getGenesisAndKeys(n int, isFullChain bool) (*core.Genesis, []*ecdsa.PrivateKey) {
   217  	// Setup validators
   218  	var nodeKeys = make([]*ecdsa.PrivateKey, n)
   219  	validators := make([]istanbul.ValidatorData, n)
   220  	for i := 0; i < n; i++ {
   221  		var addr common.Address
   222  		if i == 1 {
   223  			nodeKeys[i], _ = generatePrivateKey()
   224  			addr = getAddress()
   225  		} else {
   226  			nodeKeys[i], _ = crypto.GenerateKey()
   227  			addr = crypto.PubkeyToAddress(nodeKeys[i].PublicKey)
   228  		}
   229  		blsPrivateKey, _ := blscrypto.ECDSAToBLS(nodeKeys[i])
   230  		blsPublicKey, _ := blscrypto.PrivateToPublic(blsPrivateKey)
   231  		validators[i] = istanbul.ValidatorData{
   232  			addr,
   233  			blsPublicKey,
   234  		}
   235  
   236  	}
   237  
   238  	// generate genesis block
   239  	genesis := core.DefaultGenesisBlock()
   240  	genesis.Config = params.TestChainConfig
   241  	if !isFullChain {
   242  		genesis.Config.FullHeaderChainAvailable = false
   243  	}
   244  	// force enable Istanbul engine
   245  	genesis.Config.Istanbul = &params.IstanbulConfig{
   246  		Epoch:          10,
   247  		LookbackWindow: 2,
   248  	}
   249  	genesis.Config.Ethash = nil
   250  	genesis.Difficulty = defaultDifficulty
   251  	genesis.Nonce = emptyNonce.Uint64()
   252  	genesis.Mixhash = types.IstanbulDigest
   253  
   254  	AppendValidatorsToGenesisBlock(genesis, validators)
   255  	return genesis, nodeKeys
   256  }
   257  
   258  func makeHeader(parent *types.Block, config *istanbul.Config) *types.Header {
   259  	header := &types.Header{
   260  		ParentHash: parent.Hash(),
   261  		Number:     parent.Number().Add(parent.Number(), common.Big1),
   262  		GasLimit:   core.CalcGasLimit(parent, nil),
   263  		GasUsed:    0,
   264  		Extra:      parent.Extra(),
   265  		Time:       new(big.Int).Add(parent.Time(), new(big.Int).SetUint64(config.BlockPeriod)),
   266  		Difficulty: defaultDifficulty,
   267  	}
   268  	return header
   269  }
   270  
   271  func makeBlock(chain *core.BlockChain, engine *Backend, parent *types.Block) *types.Block {
   272  	block := makeBlockWithoutSeal(chain, engine, parent)
   273  	results := make(chan *types.Block)
   274  	go func() { engine.Seal(chain, block, results, nil) }()
   275  	block = <-results
   276  	return block
   277  }
   278  
   279  func makeBlockWithoutSeal(chain *core.BlockChain, engine *Backend, parent *types.Block) *types.Block {
   280  	header := makeHeader(parent, engine.config)
   281  	engine.Prepare(chain, header)
   282  	state, err := chain.StateAt(parent.Root())
   283  	if err != nil {
   284  		fmt.Printf("Error!! %v\n", err)
   285  	}
   286  	block, err := engine.Finalize(chain, header, state, nil, nil, nil, nil)
   287  	if err != nil {
   288  		fmt.Printf("Error!! %v\n", err)
   289  	}
   290  	return block
   291  }
   292  
   293  func TestPrepare(t *testing.T) {
   294  	chain, engine := newBlockChain(1, true)
   295  	header := makeHeader(chain.Genesis(), engine.config)
   296  	err := engine.Prepare(chain, header)
   297  	if err != nil {
   298  		t.Errorf("error mismatch: have %v, want nil", err)
   299  	}
   300  	header.ParentHash = common.BytesToHash([]byte("1234567890"))
   301  	err = engine.Prepare(chain, header)
   302  	if err != consensus.ErrUnknownAncestor {
   303  		t.Errorf("error mismatch: have %v, want %v", err, consensus.ErrUnknownAncestor)
   304  	}
   305  }
   306  
   307  func TestSealReturns(t *testing.T) {
   308  	chain, engine := newBlockChain(2, true)
   309  	block := makeBlockWithoutSeal(chain, engine, chain.Genesis())
   310  	stop := make(chan struct{}, 1)
   311  	results := make(chan *types.Block)
   312  	returns := make(chan struct{}, 1)
   313  	go func() {
   314  		err := engine.Seal(chain, block, results, stop)
   315  		if err != nil {
   316  			t.Errorf("error mismatch: have %v, want nil", err)
   317  		}
   318  		returns <- struct{}{}
   319  	}()
   320  
   321  	select {
   322  	case <-returns:
   323  	case <-time.After(time.Second):
   324  		t.Errorf("Never returned from seal")
   325  	}
   326  
   327  }
   328  func TestSealStopChannel(t *testing.T) {
   329  	chain, engine := newBlockChain(1, true)
   330  	block := makeBlockWithoutSeal(chain, engine, chain.Genesis())
   331  	stop := make(chan struct{}, 1)
   332  	eventSub := engine.EventMux().Subscribe(istanbul.RequestEvent{})
   333  	eventLoop := func() {
   334  		ev := <-eventSub.Chan()
   335  		_, ok := ev.Data.(istanbul.RequestEvent)
   336  		if !ok {
   337  			t.Errorf("unexpected event comes: %v", reflect.TypeOf(ev.Data))
   338  		}
   339  		stop <- struct{}{}
   340  		eventSub.Unsubscribe()
   341  	}
   342  	go eventLoop()
   343  	results := make(chan *types.Block)
   344  
   345  	err := engine.Seal(chain, block, results, stop)
   346  	if err != nil {
   347  		t.Errorf("error mismatch: have %v, want nil", err)
   348  	}
   349  
   350  	select {
   351  	case <-results:
   352  		t.Errorf("Did not expect a block")
   353  	case <-time.After(time.Second):
   354  	}
   355  }
   356  
   357  // TestSealCommittedOtherHash checks that when Seal() ask for a commit, if we send a
   358  // different block hash, it will abort
   359  func TestSealCommittedOtherHash(t *testing.T) {
   360  	chain, engine := newBlockChain(4, true)
   361  	block := makeBlockWithoutSeal(chain, engine, chain.Genesis())
   362  
   363  	// create a second block which will have a different hash
   364  	otherBlock := makeBlockWithoutSeal(chain, engine, chain.Genesis())
   365  	eventSub := engine.EventMux().Subscribe(istanbul.RequestEvent{})
   366  	eventLoop := func() {
   367  		ev := <-eventSub.Chan()
   368  		_, ok := ev.Data.(istanbul.RequestEvent)
   369  		if !ok {
   370  			t.Errorf("unexpected event comes: %v", reflect.TypeOf(ev.Data))
   371  		}
   372  		engine.Commit(otherBlock, types.IstanbulAggregatedSeal{}, types.IstanbulEpochValidatorSetSeal{})
   373  		eventSub.Unsubscribe()
   374  	}
   375  	go eventLoop()
   376  	results := make(chan *types.Block)
   377  
   378  	go func() { engine.Seal(chain, block, results, nil) }()
   379  	select {
   380  	case <-results:
   381  		t.Error("seal should not be completed")
   382  	case <-time.After(2 * time.Second):
   383  	}
   384  }
   385  
   386  func TestSealCommitted(t *testing.T) {
   387  	chain, engine := newBlockChain(1, true)
   388  	block := makeBlockWithoutSeal(chain, engine, chain.Genesis())
   389  	expectedBlock, _ := engine.updateBlock(engine.chain.GetHeader(block.ParentHash(), block.NumberU64()-1), block)
   390  
   391  	results := make(chan *types.Block)
   392  	go func() {
   393  		err := engine.Seal(chain, block, results, nil)
   394  		if err != nil {
   395  			t.Errorf("error mismatch: have %v, want nil", err)
   396  		}
   397  	}()
   398  
   399  	finalBlock := <-results
   400  	if finalBlock.Hash() != expectedBlock.Hash() {
   401  		t.Errorf("hash mismatch: have %v, want %v", finalBlock.Hash(), expectedBlock.Hash())
   402  	}
   403  }
   404  
   405  func TestVerifyHeader(t *testing.T) {
   406  	chain, engine := newBlockChain(1, true)
   407  
   408  	// errEmptyAggregatedSeal case
   409  	block := makeBlockWithoutSeal(chain, engine, chain.Genesis())
   410  	block, _ = engine.updateBlock(chain.Genesis().Header(), block)
   411  	err := engine.VerifyHeader(chain, block.Header(), false)
   412  	if err != errEmptyAggregatedSeal {
   413  		t.Errorf("error mismatch: have %v, want %v", err, errEmptyAggregatedSeal)
   414  	}
   415  
   416  	// short extra data
   417  	header := block.Header()
   418  	header.Extra = []byte{}
   419  	err = engine.VerifyHeader(chain, header, false)
   420  	if err != errInvalidExtraDataFormat {
   421  		t.Errorf("error mismatch: have %v, want %v", err, errInvalidExtraDataFormat)
   422  	}
   423  	// incorrect extra format
   424  	header.Extra = []byte("0000000000000000000000000000000012300000000000000000000000000000000000000000000000000000000000000000")
   425  	err = engine.VerifyHeader(chain, header, false)
   426  	if err != errInvalidExtraDataFormat {
   427  		t.Errorf("error mismatch: have %v, want %v", err, errInvalidExtraDataFormat)
   428  	}
   429  
   430  	// non zero MixDigest
   431  	block = makeBlockWithoutSeal(chain, engine, chain.Genesis())
   432  	header = block.Header()
   433  	header.MixDigest = common.BytesToHash([]byte("123456789"))
   434  	err = engine.VerifyHeader(chain, header, false)
   435  	if err != errInvalidMixDigest {
   436  		t.Errorf("error mismatch: have %v, want %v", err, errInvalidMixDigest)
   437  	}
   438  
   439  	// invalid uncles hash
   440  	block = makeBlockWithoutSeal(chain, engine, chain.Genesis())
   441  	header = block.Header()
   442  	header.UncleHash = common.BytesToHash([]byte("123456789"))
   443  	err = engine.VerifyHeader(chain, header, false)
   444  	if err != errInvalidUncleHash {
   445  		t.Errorf("error mismatch: have %v, want %v", err, errInvalidUncleHash)
   446  	}
   447  
   448  	// invalid difficulty
   449  	block = makeBlockWithoutSeal(chain, engine, chain.Genesis())
   450  	header = block.Header()
   451  	header.Difficulty = big.NewInt(2)
   452  	err = engine.VerifyHeader(chain, header, false)
   453  	if err != errInvalidDifficulty {
   454  		t.Errorf("error mismatch: have %v, want %v", err, errInvalidDifficulty)
   455  	}
   456  
   457  	// invalid timestamp
   458  	block = makeBlockWithoutSeal(chain, engine, chain.Genesis())
   459  	header = block.Header()
   460  	header.Time = new(big.Int).Add(chain.Genesis().Time(), new(big.Int).SetUint64(engine.config.BlockPeriod-1))
   461  	err = engine.VerifyHeader(chain, header, false)
   462  	if err != errInvalidTimestamp {
   463  		t.Errorf("error mismatch: have %v, want %v", err, errInvalidTimestamp)
   464  	}
   465  
   466  	// future block
   467  	block = makeBlockWithoutSeal(chain, engine, chain.Genesis())
   468  	header = block.Header()
   469  	header.Time = new(big.Int).Add(big.NewInt(now().Unix()), new(big.Int).SetUint64(10))
   470  	err = engine.VerifyHeader(chain, header, false)
   471  	if err != consensus.ErrFutureBlock {
   472  		t.Errorf("error mismatch: have %v, want %v", err, consensus.ErrFutureBlock)
   473  	}
   474  
   475  	// invalid nonce
   476  	block = makeBlockWithoutSeal(chain, engine, chain.Genesis())
   477  	header = block.Header()
   478  	copy(header.Nonce[:], hexutil.MustDecode("0x111111111111"))
   479  	header.Number = big.NewInt(int64(engine.config.Epoch))
   480  	err = engine.VerifyHeader(chain, header, false)
   481  	if err != errInvalidNonce {
   482  		t.Errorf("error mismatch: have %v, want %v", err, errInvalidNonce)
   483  	}
   484  }
   485  
   486  func TestVerifySeal(t *testing.T) {
   487  	chain, engine := newBlockChain(1, true)
   488  	genesis := chain.Genesis()
   489  	// cannot verify genesis
   490  	err := engine.VerifySeal(chain, genesis.Header())
   491  	if err != errUnknownBlock {
   492  		t.Errorf("error mismatch: have %v, want %v", err, errUnknownBlock)
   493  	}
   494  
   495  	block := makeBlock(chain, engine, genesis)
   496  
   497  	// change header content and expect to invalidate signature
   498  	header := block.Header()
   499  	header.Number = big.NewInt(4)
   500  	err = engine.VerifySeal(chain, header)
   501  	if err != errInvalidSignature {
   502  		t.Errorf("error mismatch: have %v, want %v", err, errInvalidSignature)
   503  	}
   504  
   505  	// delete istanbul extra data and expect invalid extra data format
   506  	header = block.Header()
   507  	header.Extra = nil
   508  	err = engine.VerifySeal(chain, header)
   509  	if err != errInvalidExtraDataFormat {
   510  		t.Errorf("error mismatch: have %v, want %v", err, errInvalidExtraDataFormat)
   511  	}
   512  
   513  	// modify seal bitmap and expect to fail the quorum check
   514  	header = block.Header()
   515  	extra, err := types.ExtractIstanbulExtra(header)
   516  	if err != nil {
   517  		t.Fatalf("failed to extract istanbul data: %v", err)
   518  	}
   519  	extra.AggregatedSeal.Bitmap = big.NewInt(0)
   520  	encoded, err := rlp.EncodeToBytes(extra)
   521  	if err != nil {
   522  		t.Fatalf("failed to encode istanbul data: %v", err)
   523  	}
   524  	header.Extra = append(header.Extra[:types.IstanbulExtraVanity], encoded...)
   525  	err = engine.VerifySeal(chain, header)
   526  	if err != errInsufficientSeals {
   527  		t.Errorf("error mismatch: have %v, want %v", err, errInsufficientSeals)
   528  	}
   529  
   530  	// verifiy the seal on the unmodified block.
   531  	err = engine.VerifySeal(chain, block.Header())
   532  	if err != nil {
   533  		t.Errorf("error mismatch: have %v, want nil", err)
   534  	}
   535  }
   536  
   537  func TestVerifyHeaders(t *testing.T) {
   538  	chain, engine := newBlockChain(1, true)
   539  	genesis := chain.Genesis()
   540  
   541  	// success case
   542  	headers := []*types.Header{}
   543  	blocks := []*types.Block{}
   544  	size := 100
   545  
   546  	for i := 0; i < size; i++ {
   547  		var b *types.Block
   548  		if i == 0 {
   549  			b = makeBlockWithoutSeal(chain, engine, genesis)
   550  			b, _ = engine.updateBlock(genesis.Header(), b)
   551  		} else {
   552  			b = makeBlockWithoutSeal(chain, engine, blocks[i-1])
   553  			b, _ = engine.updateBlock(blocks[i-1].Header(), b)
   554  		}
   555  
   556  		blocks = append(blocks, b)
   557  		headers = append(headers, blocks[i].Header())
   558  	}
   559  	now = func() time.Time {
   560  		return time.Unix(headers[size-1].Time.Int64(), 0)
   561  	}
   562  	_, results := engine.VerifyHeaders(chain, headers, nil)
   563  	const timeoutDura = 2 * time.Second
   564  	timeout := time.NewTimer(timeoutDura)
   565  	index := 0
   566  OUT1:
   567  	for {
   568  		select {
   569  		case err := <-results:
   570  			if err != nil {
   571  				if err != errEmptyAggregatedSeal && err != errInvalidAggregatedSeal {
   572  					t.Errorf("error mismatch: have %v, want errEmptyAggregatedSeal|errInvalidAggregatedSeal", err)
   573  					break OUT1
   574  				}
   575  			}
   576  			index++
   577  			if index == size {
   578  				break OUT1
   579  			}
   580  		case <-timeout.C:
   581  			break OUT1
   582  		}
   583  	}
   584  	// abort cases
   585  	abort, results := engine.VerifyHeaders(chain, headers, nil)
   586  	timeout = time.NewTimer(timeoutDura)
   587  	index = 0
   588  OUT2:
   589  	for {
   590  		select {
   591  		case err := <-results:
   592  			if err != nil {
   593  				if err != errEmptyAggregatedSeal && err != errInvalidAggregatedSeal {
   594  					t.Errorf("error mismatch: have %v, want errEmptyAggregatedSeal|errInvalidAggregatedSeal", err)
   595  					break OUT2
   596  				}
   597  			}
   598  			index++
   599  			if index == 5 {
   600  				abort <- struct{}{}
   601  			}
   602  			if index >= size {
   603  				t.Errorf("verifyheaders should be aborted")
   604  				break OUT2
   605  			}
   606  		case <-timeout.C:
   607  			break OUT2
   608  		}
   609  	}
   610  	// error header cases
   611  	headers[2].Number = big.NewInt(100)
   612  	abort, results = engine.VerifyHeaders(chain, headers, nil)
   613  	timeout = time.NewTimer(timeoutDura)
   614  	index = 0
   615  	errors := 0
   616  	expectedErrors := 2
   617  OUT3:
   618  	for {
   619  		select {
   620  		case err := <-results:
   621  			if err != nil {
   622  				if err != errEmptyAggregatedSeal && err != errInvalidAggregatedSeal {
   623  					errors++
   624  				}
   625  			}
   626  			index++
   627  			if index == size {
   628  				if errors != expectedErrors {
   629  					t.Errorf("error mismatch: have %v, want %v", err, expectedErrors)
   630  				}
   631  				break OUT3
   632  			}
   633  		case <-timeout.C:
   634  			break OUT3
   635  		}
   636  	}
   637  }
   638  
   639  func TestVerifyHeaderWithoutFullChain(t *testing.T) {
   640  	chain, engine := newBlockChain(1, false)
   641  
   642  	// allow future block without full chain available
   643  	block := makeBlockWithoutSeal(chain, engine, chain.Genesis())
   644  	header := block.Header()
   645  	header.Time = new(big.Int).Add(big.NewInt(now().Unix()), new(big.Int).SetUint64(3))
   646  	err := engine.VerifyHeader(chain, header, false)
   647  	if err != errEmptyAggregatedSeal {
   648  		t.Errorf("error mismatch: have %v, want %v", err, errEmptyAggregatedSeal)
   649  	}
   650  
   651  	// reject future block without full chain available
   652  	block = makeBlockWithoutSeal(chain, engine, chain.Genesis())
   653  	header = block.Header()
   654  	header.Time = new(big.Int).Add(big.NewInt(now().Unix()), new(big.Int).SetUint64(10))
   655  	err = engine.VerifyHeader(chain, header, false)
   656  	if err != consensus.ErrFutureBlock {
   657  		t.Errorf("error mismatch: have %v, want %v", err, consensus.ErrFutureBlock)
   658  	}
   659  }
   660  
   661  func TestPrepareExtra(t *testing.T) {
   662  	oldValidators := make([]istanbul.ValidatorData, 2)
   663  	oldValidators[0] = istanbul.ValidatorData{
   664  		common.BytesToAddress(hexutil.MustDecode("0x44add0ec310f115a0e603b2d7db9f067778eaf8a")),
   665  		blscrypto.SerializedPublicKey{},
   666  	}
   667  	oldValidators[1] = istanbul.ValidatorData{
   668  		common.BytesToAddress(hexutil.MustDecode("0x294fc7e8f22b3bcdcf955dd7ff3ba2ed833f8212")),
   669  		blscrypto.SerializedPublicKey{},
   670  	}
   671  
   672  	newValidators := make([]istanbul.ValidatorData, 2)
   673  	newValidators[0] = istanbul.ValidatorData{
   674  		common.BytesToAddress(hexutil.MustDecode("0x6beaaed781d2d2ab6350f5c4566a2c6eaac407a6")),
   675  		blscrypto.SerializedPublicKey{},
   676  	}
   677  	newValidators[1] = istanbul.ValidatorData{
   678  		common.BytesToAddress(hexutil.MustDecode("0x8be76812f765c24641ec63dc2852b378aba2b440")),
   679  		blscrypto.SerializedPublicKey{},
   680  	}
   681  
   682  	extra, err := rlp.EncodeToBytes(&types.IstanbulExtra{
   683  		AddedValidators:           []common.Address{},
   684  		AddedValidatorsPublicKeys: []blscrypto.SerializedPublicKey{},
   685  		RemovedValidators:         big.NewInt(0),
   686  		Seal:                      []byte{},
   687  		AggregatedSeal:            types.IstanbulAggregatedSeal{},
   688  		ParentAggregatedSeal:      types.IstanbulAggregatedSeal{},
   689  	})
   690  	h := &types.Header{
   691  		Extra: append(make([]byte, types.IstanbulExtraVanity), extra...),
   692  	}
   693  
   694  	err = writeValidatorSetDiff(h, oldValidators, newValidators)
   695  	if err != nil {
   696  		t.Errorf("error mismatch: have %v, want: nil", err)
   697  	}
   698  
   699  	// the header must have the updated extra data
   700  	updatedExtra, err := types.ExtractIstanbulExtra(h)
   701  	if err != nil {
   702  		t.Errorf("error mismatch: have %v, want: nil", err)
   703  	}
   704  
   705  	var updatedExtraVals []istanbul.ValidatorData
   706  	for i := range updatedExtra.AddedValidators {
   707  		updatedExtraVals = append(updatedExtraVals, istanbul.ValidatorData{
   708  			Address:      updatedExtra.AddedValidators[i],
   709  			BLSPublicKey: updatedExtra.AddedValidatorsPublicKeys[i],
   710  		})
   711  	}
   712  
   713  	if !reflect.DeepEqual(updatedExtraVals, newValidators) {
   714  		t.Errorf("validators were not properly updated")
   715  	}
   716  
   717  	// the validators which were removed were 2, so the bitmap is 11, meaning it
   718  	// should be 3
   719  	if updatedExtra.RemovedValidators.Cmp(big.NewInt(3)) != 0 {
   720  		t.Errorf("Invalid removed validators bitmap, got %v, want %v", updatedExtra.RemovedValidators, big.NewInt(3))
   721  	}
   722  
   723  }
   724  
   725  func TestWriteSeal(t *testing.T) {
   726  	vanity := bytes.Repeat([]byte{0x00}, types.IstanbulExtraVanity)
   727  	istExtra := &types.IstanbulExtra{
   728  		AddedValidators: []common.Address{
   729  			common.BytesToAddress(hexutil.MustDecode("0x6beaaed781d2d2ab6350f5c4566a2c6eaac407a6")),
   730  			common.BytesToAddress(hexutil.MustDecode("0x8be76812f765c24641ec63dc2852b378aba2b440")),
   731  		},
   732  		AddedValidatorsPublicKeys: []blscrypto.SerializedPublicKey{},
   733  		RemovedValidators:         big.NewInt(12), // 1100, remove third and fourth validators
   734  		Seal:                      []byte{},
   735  		AggregatedSeal:            types.IstanbulAggregatedSeal{big.NewInt(0), []byte{}, big.NewInt(0)},
   736  		ParentAggregatedSeal:      types.IstanbulAggregatedSeal{big.NewInt(0), []byte{}, big.NewInt(0)},
   737  	}
   738  	istExtraRaw, err := rlp.EncodeToBytes(&istExtra)
   739  
   740  	expectedSeal := hexutil.MustDecode("0x29fe2612266a3965321c23a2e0382cd819e992f293d9a0032439728e41201d2c387cc9de5914a734873d79addb76c59ce73c1085a98b968384811b4ad050dddc56")
   741  	if len(expectedSeal) != types.IstanbulExtraSeal {
   742  		t.Errorf("incorrect length for seal: have %v, want %v", len(expectedSeal), types.IstanbulExtraSeal)
   743  	}
   744  	expectedIstExtra := istExtra
   745  	expectedIstExtra.Seal = expectedSeal
   746  
   747  	var expectedErr error
   748  
   749  	h := &types.Header{
   750  		Extra: append(vanity, istExtraRaw...),
   751  	}
   752  
   753  	// normal case
   754  	err = writeSeal(h, expectedSeal)
   755  	if err != expectedErr {
   756  		t.Errorf("error mismatch: have %v, want %v", err, expectedErr)
   757  	}
   758  
   759  	// verify istanbul extra-data
   760  	actualIstExtra, err := types.ExtractIstanbulExtra(h)
   761  	if err != nil {
   762  		t.Errorf("error mismatch: have %v, want nil", err)
   763  	}
   764  	if !reflect.DeepEqual(actualIstExtra, expectedIstExtra) {
   765  		t.Errorf("extra data mismatch: have %v, want %v", actualIstExtra, expectedIstExtra)
   766  	}
   767  
   768  	// invalid seal
   769  	unexpectedSeal := append(expectedSeal, make([]byte, 1)...)
   770  	err = writeSeal(h, unexpectedSeal)
   771  	if err != errInvalidSignature {
   772  		t.Errorf("error mismatch: have %v, want %v", err, errInvalidSignature)
   773  	}
   774  }
   775  
   776  func TestWriteAggregatedSeal(t *testing.T) {
   777  	vanity := bytes.Repeat([]byte{0x00}, types.IstanbulExtraVanity)
   778  	istExtra := &types.IstanbulExtra{
   779  		AddedValidators: []common.Address{
   780  			common.BytesToAddress(hexutil.MustDecode("0x6beaaed781d2d2ab6350f5c4566a2c6eaac407a6")),
   781  			common.BytesToAddress(hexutil.MustDecode("0x8be76812f765c24641ec63dc2852b378aba2b440")),
   782  		},
   783  		AddedValidatorsPublicKeys: []blscrypto.SerializedPublicKey{},
   784  		RemovedValidators:         big.NewInt(12), // 1100, remove third and fourth validators
   785  		Seal:                      []byte{},
   786  		AggregatedSeal:            types.IstanbulAggregatedSeal{},
   787  		ParentAggregatedSeal:      types.IstanbulAggregatedSeal{},
   788  	}
   789  	istExtraRaw, err := rlp.EncodeToBytes(&istExtra)
   790  
   791  	aggregatedSeal := types.IstanbulAggregatedSeal{
   792  		Round:     big.NewInt(2),
   793  		Bitmap:    big.NewInt(3),
   794  		Signature: append([]byte{1, 2, 3}, bytes.Repeat([]byte{0x00}, types.IstanbulExtraBlsSignature-3)...),
   795  	}
   796  
   797  	expectedIstExtra := istExtra
   798  	expectedIstExtra.AggregatedSeal = aggregatedSeal
   799  	expectedIstExtra.ParentAggregatedSeal = aggregatedSeal
   800  
   801  	h := &types.Header{
   802  		Extra: append(vanity, istExtraRaw...),
   803  	}
   804  
   805  	// normal case
   806  	err = writeAggregatedSeal(h, aggregatedSeal, false)
   807  	if err != nil {
   808  		t.Errorf("error mismatch: have %v, want nil", err)
   809  	}
   810  
   811  	err = writeAggregatedSeal(h, aggregatedSeal, true)
   812  	if err != nil {
   813  		t.Errorf("error mismatch: have %v, want nil", err)
   814  	}
   815  
   816  	// verify istanbul extra-data
   817  	actualIstExtra, err := types.ExtractIstanbulExtra(h)
   818  	if err != nil {
   819  		t.Errorf("error mismatch: have %v, want nil", err)
   820  	}
   821  	if !reflect.DeepEqual(actualIstExtra, expectedIstExtra) {
   822  		t.Errorf("extra data mismatch: have %v, want %v", actualIstExtra, expectedIstExtra)
   823  	}
   824  
   825  	// try to write an invalid length seal to the CommitedSeal or ParentCommit field
   826  	invalidAggregatedSeal := types.IstanbulAggregatedSeal{
   827  		Round:     big.NewInt(3),
   828  		Bitmap:    big.NewInt(3),
   829  		Signature: append(aggregatedSeal.Signature, make([]byte, 1)...),
   830  	}
   831  	err = writeAggregatedSeal(h, invalidAggregatedSeal, false)
   832  	if err != errInvalidAggregatedSeal {
   833  		t.Errorf("error mismatch: have %v, want %v", err, errInvalidAggregatedSeal)
   834  	}
   835  
   836  	err = writeAggregatedSeal(h, invalidAggregatedSeal, true)
   837  	if err != errInvalidAggregatedSeal {
   838  		t.Errorf("error mismatch: have %v, want %v", err, errInvalidAggregatedSeal)
   839  	}
   840  }