github.com/igggame/nebulas-go@v2.1.0+incompatible/core/blockchain_test.go (about)

     1  // Copyright (C) 2017 go-nebulas authors
     2  //
     3  // This file is part of the go-nebulas library.
     4  //
     5  // the go-nebulas library is free software: you can redistribute it and/or modify
     6  // it under the terms of the GNU General Public License as published by
     7  // the Free Software Foundation, either version 3 of the License, or
     8  // (at your option) any later version.
     9  //
    10  // the go-nebulas library is distributed in the hope that it will be useful,
    11  // but WITHOUT ANY WARRANTY; without even the implied warranty of
    12  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    13  // GNU General Public License for more details.
    14  //
    15  // You should have received a copy of the GNU General Public License
    16  // along with the go-nebulas library.  If not, see <http://www.gnu.org/licenses/>.
    17  //
    18  
    19  package core
    20  
    21  import (
    22  	"testing"
    23  
    24  	"github.com/nebulasio/go-nebulas/crypto"
    25  	"github.com/nebulasio/go-nebulas/crypto/keystore"
    26  	"github.com/nebulasio/go-nebulas/crypto/keystore/secp256k1"
    27  	"github.com/nebulasio/go-nebulas/util"
    28  
    29  	"sync"
    30  	"time"
    31  
    32  	"github.com/stretchr/testify/assert"
    33  )
    34  
    35  func signBlock(block *Block) {
    36  	block.header.alg = keystore.SECP256K1
    37  }
    38  
    39  func TestBlockChain_FindCommonAncestorWithTail(t *testing.T) {
    40  	neb := testNeb(t)
    41  	bc := neb.chain
    42  
    43  	coinbase12, _ := AddressParse("n1FF1nz6tarkDVwWQkMnnwFPuPKUaQTdptE")
    44  	coinbase11, _ := AddressParse("n1GmkKH6nBMw4rrjt16RrJ9WcgvKUtAZP1s")
    45  	coinbase221, _ := AddressParse("n1H4MYms9F55ehcvygwWE71J8tJC4CRr2so")
    46  	coinbase111, _ := AddressParse("n1JAy4X6KKLCNiTd7MWMRsVBjgdVq5WCCpf")
    47  	coinbase222, _ := AddressParse("n1LkDi2gGMqPrjYcczUiweyP4RxTB6Go1qS")
    48  	coinbase1111, _ := AddressParse("n1LmP9K8pFF33fgdgHZonFEMsqZinJ4EUqk")
    49  	coinbase11111, _ := AddressParse("n1MNXBKm6uJ5d76nJTdRvkPNVq85n6CnXAi")
    50  
    51  	//add from reward
    52  	block0, _ := bc.NewBlock(coinbase11)
    53  	block0.header.timestamp = BlockInterval
    54  	block0.Seal()
    55  	signBlock(block0)
    56  	assert.Nil(t, bc.BlockPool().Push(block0))
    57  
    58  	/*
    59  		genesis -- 0 -- 11 -- 111 -- 1111
    60  					 \_ 12 -- 221
    61  					       \_ 222 tail
    62  	*/
    63  	block11, err := bc.NewBlock(coinbase11)
    64  	assert.Nil(t, err)
    65  	block11.header.timestamp = BlockInterval * 2
    66  	block12, err := bc.NewBlock(coinbase12)
    67  	assert.Nil(t, err)
    68  	block12.header.timestamp = BlockInterval * 3
    69  	assert.Nil(t, block11.Seal())
    70  	signBlock(block11)
    71  	assert.Nil(t, block12.Seal())
    72  	signBlock(block12)
    73  
    74  	assert.Nil(t, bc.BlockPool().Push(block11))
    75  	assert.Equal(t, bc.tailBlock.Hash(), block11.Hash())
    76  	block111, err := bc.NewBlock(coinbase111)
    77  	assert.Nil(t, err)
    78  	block111.header.timestamp = BlockInterval * 4
    79  	assert.Nil(t, block111.Seal())
    80  	signBlock(block111)
    81  
    82  	assert.Nil(t, bc.BlockPool().Push(block12))
    83  
    84  	tailBlock, _ := bc.cachedBlocks.Get(block12.Hash().Hex())
    85  	bc.tailBlock = tailBlock.(*Block)
    86  	assert.Nil(t, bc.buildIndexByBlockHeight(bc.genesisBlock, bc.tailBlock))
    87  	block221, _ := bc.NewBlock(coinbase221)
    88  	block221.header.timestamp = BlockInterval * 5
    89  	block222, _ := bc.NewBlock(coinbase222)
    90  	block222.header.timestamp = BlockInterval * 6
    91  	assert.Nil(t, block221.Seal())
    92  	signBlock(block221)
    93  	assert.Nil(t, block222.Seal())
    94  	signBlock(block222)
    95  
    96  	assert.Nil(t, bc.BlockPool().Push(block111))
    97  	block1111, _ := bc.NewBlock(coinbase1111)
    98  	block1111.header.timestamp = BlockInterval * 7
    99  	assert.Nil(t, block1111.Seal())
   100  	signBlock(block1111)
   101  
   102  	assert.Nil(t, bc.BlockPool().Push(block221))
   103  	assert.Nil(t, bc.BlockPool().Push(block222))
   104  
   105  	tailBlock, _ = bc.cachedBlocks.Get(block222.Hash().Hex())
   106  	bc.tailBlock = tailBlock.(*Block)
   107  	assert.Nil(t, bc.buildIndexByBlockHeight(bc.genesisBlock, bc.tailBlock))
   108  	common2, err := bc.FindCommonAncestorWithTail(block221)
   109  	assert.Nil(t, err)
   110  	assert.Equal(t, common2.String(), block12.String())
   111  
   112  	common3, err := bc.FindCommonAncestorWithTail(block111)
   113  	assert.Nil(t, err)
   114  	assert.Equal(t, common3.Hash(), block0.Hash())
   115  
   116  	common4, err := bc.FindCommonAncestorWithTail(bc.tailBlock)
   117  	assert.Nil(t, err)
   118  	assert.Equal(t, common4.Hash(), bc.tailBlock.Hash())
   119  
   120  	common5, err := bc.FindCommonAncestorWithTail(block12)
   121  	assert.Nil(t, err)
   122  	assert.Equal(t, common5.Height(), block12.Height())
   123  
   124  	result := bc.Dump(4)
   125  	assert.Equal(t, result, "["+block222.String()+","+block12.String()+","+block0.String()+","+bc.genesisBlock.String()+"]")
   126  
   127  	assert.Nil(t, bc.BlockPool().Push(block1111))
   128  	tails := bc.DetachedTailBlocks()
   129  	for _, v := range tails {
   130  		if v.Hash().Equals(block221.Hash()) ||
   131  			v.Hash().Equals(block222.Hash()) ||
   132  			v.Hash().Equals(block1111.Hash()) {
   133  			continue
   134  		}
   135  		assert.Equal(t, true, false)
   136  	}
   137  	assert.Equal(t, len(tails), 3)
   138  
   139  	block11111, _ := bc.NewBlock(coinbase11111)
   140  	block11111.header.timestamp = BlockInterval * 8
   141  	assert.Nil(t, block11111.Seal())
   142  	signBlock(block11111)
   143  	assert.Nil(t, bc.BlockPool().Push(block11111))
   144  }
   145  
   146  func TestBlockChain_SimulateTransactionExecution(t *testing.T) {
   147  	priv := secp256k1.GeneratePrivateKey()
   148  	pubdata, _ := priv.PublicKey().Encoded()
   149  	from, _ := NewAddressFromPublicKey(pubdata)
   150  	to := &Address{from.address}
   151  
   152  	payload, err := NewBinaryPayload(nil).ToBytes()
   153  	assert.Nil(t, err)
   154  
   155  	neb := testNeb(t)
   156  	bc := neb.chain
   157  	gasLimit, _ := util.NewUint128FromInt(200000)
   158  	tx, _ := NewTransaction(bc.ChainID(), from, to, util.NewUint128(), 1, TxPayloadBinaryType, payload, TransactionGasPrice, gasLimit)
   159  
   160  	expectedGasUsed, _ := util.NewUint128FromInt(20000)
   161  
   162  	result, err := bc.SimulateTransactionExecution(tx)
   163  	assert.Nil(t, err)
   164  	assert.Equal(t, ErrInsufficientBalance, result.Err)
   165  	assert.Equal(t, expectedGasUsed, result.GasUsed)
   166  }
   167  
   168  func TestTailBlock(t *testing.T) {
   169  	neb := testNeb(t)
   170  	bc := neb.chain
   171  	block, err := bc.LoadTailFromStorage()
   172  	assert.Nil(t, err)
   173  	assert.Equal(t, bc.tailBlock.Hash(), block.Hash())
   174  }
   175  
   176  func TestSetTailBlockEvent(t *testing.T) {
   177  	neb := testNeb(t)
   178  	bc := neb.chain
   179  	bc.eventEmitter.Start()
   180  
   181  	coinbase, _ := AddressParse("n1FF1nz6tarkDVwWQkMnnwFPuPKUaQTdptE")
   182  
   183  	topics := []string{TopicRevertBlock, TopicNewTailBlock, TopicTransactionExecutionResult}
   184  	t1ch := register(bc.eventEmitter, topics[0])
   185  	t2ch := register(bc.eventEmitter, topics[1])
   186  	t3ch := register(bc.eventEmitter, topics[2])
   187  
   188  	block0, err := bc.NewBlock(coinbase)
   189  	assert.Nil(t, err)
   190  
   191  	tx1 := mockNormalTransaction(bc.chainID, 1)
   192  	block0.transactions = append(block0.transactions, tx1)
   193  	tx2 := mockNormalTransaction(bc.chainID, 2)
   194  	block0.transactions = append(block0.transactions, tx2)
   195  	block0.header.timestamp = BlockInterval
   196  	block0.Seal()
   197  	bc.SetTailBlock(block0)
   198  
   199  	wg := new(sync.WaitGroup)
   200  	wg.Add(1)
   201  
   202  	t1c, t2c, t3c := 0, 0, 0
   203  	go func() {
   204  		// send message.
   205  		defer wg.Done()
   206  
   207  		for {
   208  			select {
   209  			case <-time.After(time.Millisecond * 500):
   210  				return
   211  			case e := <-t1ch.eventCh:
   212  				assert.Equal(t, topics[0], e.Topic)
   213  				t1c++
   214  
   215  			case e := <-t2ch.eventCh:
   216  				assert.Equal(t, topics[1], e.Topic)
   217  				t2c++
   218  
   219  			case e := <-t3ch.eventCh:
   220  				assert.Equal(t, topics[2], e.Topic)
   221  				t3c++
   222  			}
   223  		}
   224  	}()
   225  
   226  	wg.Wait()
   227  
   228  	assert.Equal(t, 0, t1c)
   229  	assert.Equal(t, 1, t2c)
   230  	assert.Equal(t, 0, t3c) // tx not execute
   231  
   232  	bc.eventEmitter.Stop()
   233  	time.Sleep(time.Millisecond * 500)
   234  }
   235  
   236  func TestGetPrice(t *testing.T) {
   237  	neb := testNeb(t)
   238  	bc := neb.chain
   239  	assert.Equal(t, bc.GasPrice(), TransactionGasPrice)
   240  
   241  	ks := keystore.DefaultKS
   242  	from := mockAddress()
   243  	key, err := ks.GetUnlocked(from.String())
   244  	assert.Nil(t, err)
   245  	signature, err := crypto.NewSignature(keystore.SECP256K1)
   246  	assert.Nil(t, err)
   247  	signature.InitSign(key.(keystore.PrivateKey))
   248  	block, err := bc.NewBlock(from)
   249  	assert.Nil(t, err)
   250  	GasPriceDetla, _ := util.NewUint128FromInt(1)
   251  	lowerGasPrice, err := TransactionGasPrice.Sub(GasPriceDetla)
   252  	assert.Nil(t, err)
   253  	gasLimit, _ := util.NewUint128FromInt(200000)
   254  	tx1, _ := NewTransaction(bc.ChainID(), from, from, util.NewUint128(), 1, TxPayloadBinaryType, []byte("nas"), lowerGasPrice, gasLimit)
   255  	tx1.Sign(signature)
   256  	tx2, _ := NewTransaction(bc.ChainID(), from, from, util.NewUint128(), 2, TxPayloadBinaryType, []byte("nas"), TransactionGasPrice, gasLimit)
   257  	tx2.Sign(signature)
   258  	block.transactions = append(block.transactions, tx1)
   259  	block.transactions = append(block.transactions, tx2)
   260  	block.Seal()
   261  	block.Sign(signature)
   262  	bc.SetTailBlock(block)
   263  	assert.Equal(t, bc.GasPrice(), lowerGasPrice)
   264  }