github.com/halybang/go-ethereum@v1.0.5-0.20180325041310-3b262bc1367c/core/ppow_consensus_test.go (about)

     1  // Copyright 2014 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 core
    18  
    19  import (
    20  	"math/big"
    21  	"github.com/wanchain/go-wanchain/consensus/ethash"
    22  	"github.com/wanchain/go-wanchain/core/vm"
    23  	"github.com/wanchain/go-wanchain/ethdb"
    24  	"github.com/wanchain/go-wanchain/params"
    25  	"testing"
    26  	"github.com/wanchain/go-wanchain/core/types"
    27  )
    28  
    29  /*
    30  Test
    31  VerifyHeader
    32  
    33  VerifyHeaders
    34  VerifyPPOWReorg
    35  
    36  
    37  verifySignerIdentity and snapshot are called by
    38  对被测试接口的数据状态的分解
    39  */
    40  
    41  var (
    42  	genesisBlock * types.Block
    43  )
    44  // newTestBlockChain creates a blockchain without validation.
    45  func newTestBlockChainEx(fake bool) (*BlockChain, *ChainEnv) {
    46  	db, _ := ethdb.NewMemDatabase()
    47  	gspec := DefaultPPOWTestingGenesisBlock()
    48  	gspec.ExtraData = make([]byte, 0)
    49  	for k := range signerSet{
    50  		gspec.ExtraData = append(gspec.ExtraData, k.Bytes()...)
    51  	}
    52  	gspec.Difficulty = big.NewInt(1)
    53  	genesisBlock = gspec.MustCommit(db)
    54  	engine := ethash.NewFullFaker(db)
    55  	if !fake {
    56  		engine = ethash.NewTester(db)
    57  	}
    58  	blockchain, err := NewBlockChain(db, gspec.Config, engine, vm.Config{})
    59  	if err != nil {
    60  		panic(err)
    61  	}
    62  	chainEnv := NewChainEnv(params.TestChainConfig, gspec, engine, blockchain, db)
    63  	blockchain.SetValidator(bproc{})
    64  	return blockchain, chainEnv
    65  }
    66  
    67  func TestVerifyHeader(t *testing.T)  {
    68  	blockchain, chainEnv := newTestBlockChainEx(false)
    69  	blocks, _ := chainEnv.GenerateChainEx(genesisBlock, []int{1,2,3}, nil)
    70  	err := blockchain.engine.VerifyHeader(blockchain, blocks[0].Header(), true)
    71  	if err != nil {
    72  		t.Error("valid block verify failed unexpect")
    73  	}
    74  
    75  	headers := make([]*types.Header, len(blocks))
    76  	seals := make([]bool, 0)
    77  	for i, block := range blocks{
    78  		headers[i] = block.Header()
    79  		seals = append(seals, true)
    80  	}
    81  
    82  	abort, results := blockchain.engine.VerifyHeaders(blockchain, headers, seals)
    83  	defer close(abort)
    84  
    85  	for _ = range headers {
    86  		err := <- results
    87  		if err != nil {
    88  			t.Error("valid headers verify failed unexpected")
    89  		}
    90  	}
    91  }
    92  
    93  func TestVerifyHeadersFailed(t *testing.T)  {
    94  	blockchain, chainEnv := newTestBlockChainEx(false)
    95  	blocks, _ := chainEnv.GenerateChainEx(genesisBlock, []int{1,2,3,4, 1,1,1}, nil)
    96  
    97  	headers := make([]*types.Header, len(blocks))
    98  	seals := make([]bool, 0)
    99  	for i, block := range blocks{
   100  		headers[i] = block.Header()
   101  		seals = append(seals, true)
   102  	}
   103  
   104  	abort, results := blockchain.engine.VerifyHeaders(blockchain, headers, seals)
   105  	defer close(abort)
   106  
   107  	isFail := false
   108  	for _ = range headers {
   109  		err := <- results
   110  		//fmt.Printf("verify %s \n", headers[i].Coinbase.String())
   111  		if err != nil {
   112  			isFail = true
   113  			break
   114  		}
   115  	}
   116  	if isFail != true {
   117  		t.Error("invalid headers verify passed unexpected")
   118  	}
   119  }
   120  
   121  
   122  func TestVerifyHeaderLoadSnapshot(t *testing.T)  {
   123  	blockchain, chainEnv := newTestBlockChainEx(true)
   124  	signerSeq := make([]int, 0)
   125  	for i := 0 ; i < 100; i++ {
   126  		signerSeq = append(signerSeq, i%20)
   127  	}
   128  	blocks, _ := chainEnv.GenerateChainEx(genesisBlock, signerSeq, nil)
   129  	blockchain.InsertChain(blocks[:99])
   130  
   131  	err := blockchain.engine.VerifyHeader(blockchain, blocks[99].Header(), true)
   132  	if err != nil {
   133  		t.Error("valid block verify failed unexpect")
   134  	}
   135  }
   136  
   137  
   138  func create2ChainContextSameGenesis()(*BlockChain, *ChainEnv, *BlockChain, *ChainEnv) {
   139  	db, _ := ethdb.NewMemDatabase()
   140  	gspec := DefaultPPOWTestingGenesisBlock()
   141  	gspec.ExtraData = make([]byte, 0)
   142  	for k := range signerSet{
   143  		gspec.ExtraData = append(gspec.ExtraData, k.Bytes()...)
   144  	}
   145  	gspec.Difficulty = big.NewInt(1)
   146  	genesisBlock = gspec.MustCommit(db)
   147  
   148  	engine := ethash.NewFaker(db)
   149  	blockchain, err := NewBlockChain(db, gspec.Config, engine, vm.Config{})
   150  	if err != nil {
   151  		panic(err)
   152  	}
   153  	chainEnv := NewChainEnv(params.TestChainConfig, gspec, engine, blockchain, db)
   154  	blockchain.SetValidator(bproc{})
   155  
   156  	newDb, _ := ethdb.NewMemDatabase()
   157  	gspec.MustCommit(newDb)
   158  	newBlockChain, err := NewBlockChain(newDb, gspec.Config, engine, vm.Config{})
   159  	if err != nil {
   160  		panic(err)
   161  	}
   162  	newChainEnv := NewChainEnv(params.TestChainConfig, gspec, engine, newBlockChain, newDb)
   163  
   164  	return blockchain, chainEnv, newBlockChain, newChainEnv
   165  
   166  }
   167  func TestVerifyPPOWReorgSuccess(t *testing.T){
   168  	blockchain, chainEnv, _, longChainEnv := create2ChainContextSameGenesis()
   169  	signerSeq := make([]int, 0)
   170  	for i := 0 ; i < 100; i++ {
   171  		signerSeq = append(signerSeq, i%10)
   172  	}
   173  	blocks, _ := chainEnv.GenerateChainEx(genesisBlock, signerSeq, nil)
   174  	blockchain.InsertChain(blocks[:99])
   175  
   176  	longSignerSeq := make([]int, 0)
   177  	for i := 0 ; i < 110; i++ {
   178  		longSignerSeq = append(longSignerSeq, (i+1)%20)
   179  	}
   180  	longBlocks, _ := longChainEnv.GenerateChainEx(genesisBlock, longSignerSeq, nil)
   181  	_, err := blockchain.InsertChain(longBlocks)
   182  	if err != nil{
   183  		t.Errorf("valid reorg failed: %s\n" , err.Error())
   184  	}
   185  }
   186  
   187  func TestVerifyPPOWReorgFailed(t *testing.T){
   188  	blockchain, chainEnv, _, longChainEnv := create2ChainContextSameGenesis()
   189  	signerSeq := make([]int, 0)
   190  	for i := 0 ; i < 100; i++ {
   191  		signerSeq = append(signerSeq, i%20)
   192  	}
   193  	blocks, _ := chainEnv.GenerateChainEx(genesisBlock, signerSeq, nil)
   194  	blockchain.InsertChain(blocks[:99])
   195  
   196  	longSignerSeq := make([]int, 0)
   197  	for i := 0 ; i < 110; i++ {
   198  		longSignerSeq = append(longSignerSeq, (i+1)%10)
   199  	}
   200  	longBlocks, _ := longChainEnv.GenerateChainEx(genesisBlock, longSignerSeq, nil)
   201  	_, err := blockchain.InsertChain(longBlocks)
   202  	if err == nil{
   203  		t.Errorf("invalid reorg shouldn't sucess: %s\n" , err.Error())
   204  	}
   205  }