github.com/igggame/nebulas-go@v2.1.0+incompatible/core/block_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  	"reflect"
    23  	"testing"
    24  	"time"
    25  
    26  	"github.com/nebulasio/go-nebulas/common/dag"
    27  	"github.com/nebulasio/go-nebulas/consensus/pb"
    28  	"github.com/nebulasio/go-nebulas/core/state"
    29  	"github.com/nebulasio/go-nebulas/util/byteutils"
    30  
    31  	pb "github.com/gogo/protobuf/proto"
    32  	"github.com/nebulasio/go-nebulas/core/pb"
    33  	"github.com/nebulasio/go-nebulas/crypto"
    34  	"github.com/nebulasio/go-nebulas/crypto/keystore"
    35  	"github.com/nebulasio/go-nebulas/util"
    36  	"github.com/stretchr/testify/assert"
    37  )
    38  
    39  const (
    40  	BlockInterval = 5
    41  )
    42  
    43  func testNeb(t *testing.T) *MockNeb {
    44  	return NewMockNeb(nil, nil, nil)
    45  }
    46  
    47  func TestNeb(t *testing.T) {
    48  	neb := testNeb(t)
    49  	assert.NotNil(t, neb.chain.TailBlock().String())
    50  	assert.Equal(t, neb.chain.ConsensusHandler(), neb.consensus)
    51  	assert.Equal(t, neb.consensus.(*mockConsensus).chain, neb.chain)
    52  }
    53  
    54  func TestNilArguments(t *testing.T) {
    55  	block := new(Block)
    56  	assert.Equal(t, block.Sign(nil), ErrNilArgument)
    57  	var sign keystore.Signature
    58  	assert.Equal(t, block.Sign(sign), ErrNilArgument)
    59  }
    60  
    61  func TestBlockFromProto(t *testing.T) {
    62  	block := new(Block)
    63  	var pb *corepb.Block
    64  	assert.Equal(t, block.FromProto(pb), ErrInvalidProtoToBlock)
    65  
    66  	blockHeader := new(BlockHeader)
    67  	var pbh *corepb.BlockHeader
    68  	assert.Equal(t, blockHeader.FromProto(pbh), ErrInvalidProtoToBlockHeader)
    69  
    70  	tx := new(Transaction)
    71  	var ptx *corepb.Transaction
    72  	assert.Equal(t, tx.FromProto(ptx), ErrInvalidProtoToTransaction)
    73  }
    74  
    75  func TestBlock(t *testing.T) {
    76  	type fields struct {
    77  		header       *BlockHeader
    78  		miner        *Address
    79  		height       uint64
    80  		transactions Transactions
    81  		dependency   *dag.Dag
    82  	}
    83  	from1, _ := NewAddressFromPublicKey([]byte("eb693e1438fce79f5cb2eb693e1438fce79f5cb2eb693e1438fce79f5cb266666"))
    84  	from2, _ := NewAddressFromPublicKey([]byte("eb692e1438fce79f5cb2eb692e1438fce79f5cb2eb692e1438fce79f5cb2uuuuu"))
    85  	to1, _ := NewAddressFromPublicKey([]byte("eb691e1438fce79f5cb2eb691e1438fce79f5cb2eb691e1438fce79f5cb266554"))
    86  	to2, _ := NewAddressFromPublicKey([]byte("eb690e1438fce79f5cb2eb690e1438fce79f5cb2eb690e1438fce79f5cb200000"))
    87  	coinbase, _ := NewAddressFromPublicKey([]byte("5425730430bc2d63f2575425730430bc2d63f2575425730430bc2d63f25733333"))
    88  	gasPrice, _ := util.NewUint128FromInt(1)
    89  	gasLimit, _ := util.NewUint128FromInt(1)
    90  
    91  	tests := []struct {
    92  		name    string
    93  		fields  fields
    94  		wantErr bool
    95  	}{
    96  		{
    97  			"full struct",
    98  			fields{
    99  				&BlockHeader{
   100  					hash:       []byte("a6e5eb190e1438fce79f5cb8774a72621637c2c9654c8b2525ed1d7e4e73653f"),
   101  					parentHash: []byte("a6e5eb240e1438fce79f5cb8774a72621637c2c9654c8b2525ed1d7e4e73653f"),
   102  					stateRoot:  []byte("43656"),
   103  					txsRoot:    []byte("43656"),
   104  					eventsRoot: []byte("43656"),
   105  					consensusRoot: &consensuspb.ConsensusRoot{
   106  						DynastyRoot: []byte("43656"),
   107  					},
   108  					coinbase:  coinbase,
   109  					timestamp: time.Now().Unix(),
   110  					chainID:   100,
   111  					alg:       keystore.SECP256K1,
   112  				},
   113  				&Address{address: []byte("hello")},
   114  				1,
   115  				Transactions{
   116  					&Transaction{
   117  						[]byte("123452"),
   118  						from1,
   119  						to1,
   120  						util.NewUint128(),
   121  						456,
   122  						1516464510,
   123  						&corepb.Data{Type: TxPayloadBinaryType, Payload: []byte("hello")},
   124  						1,
   125  						gasPrice,
   126  						gasLimit,
   127  						keystore.SECP256K1,
   128  						nil,
   129  					},
   130  					&Transaction{
   131  						[]byte("123455"),
   132  						from2,
   133  						to2,
   134  						util.NewUint128(),
   135  						446,
   136  						1516464511,
   137  						&corepb.Data{Type: TxPayloadBinaryType, Payload: []byte("hllo")},
   138  						2,
   139  						gasPrice,
   140  						gasLimit,
   141  						keystore.SECP256K1,
   142  						nil,
   143  					},
   144  				},
   145  				dag.NewDag(),
   146  			},
   147  			false,
   148  		},
   149  	}
   150  	for _, tt := range tests {
   151  		t.Run(tt.name, func(t *testing.T) {
   152  			b := &Block{
   153  				header:       tt.fields.header,
   154  				height:       tt.fields.height,
   155  				transactions: tt.fields.transactions,
   156  				dependency:   tt.fields.dependency,
   157  			}
   158  			proto, err := b.ToProto()
   159  			assert.Nil(t, err)
   160  			ir, err := pb.Marshal(proto)
   161  			assert.Nil(t, err)
   162  			nb := new(Block)
   163  			err = pb.Unmarshal(ir, proto)
   164  			assert.Nil(t, err)
   165  			err = nb.FromProto(proto)
   166  			assert.Nil(t, err)
   167  			b.header.timestamp = nb.header.timestamp
   168  
   169  			if !reflect.DeepEqual(*b.header, *nb.header) {
   170  				t.Errorf("Transaction.Serialize() = %v, want %v", *b.header, *nb.header)
   171  			}
   172  			if !reflect.DeepEqual(*b.transactions[0], *nb.transactions[0]) {
   173  				t.Errorf("Transaction.Serialize() = %v, want %v", *b.transactions[0], *nb.transactions[0])
   174  			}
   175  			if !reflect.DeepEqual(*b.transactions[1], *nb.transactions[1]) {
   176  				t.Errorf("Transaction.Serialize() = %v, want %v", *b.transactions[1], *nb.transactions[1])
   177  			}
   178  		})
   179  	}
   180  }
   181  
   182  func TestBlock_LinkParentBlock(t *testing.T) {
   183  	neb := testNeb(t)
   184  	bc := neb.chain
   185  	genesis := bc.genesisBlock
   186  	assert.Equal(t, genesis.Height(), uint64(1))
   187  	block1 := &Block{
   188  		header: &BlockHeader{
   189  			hash:       []byte("124546"),
   190  			parentHash: GenesisHash,
   191  			stateRoot:  []byte("43656"),
   192  			txsRoot:    []byte("43656"),
   193  			eventsRoot: []byte("43656"),
   194  			consensusRoot: &consensuspb.ConsensusRoot{
   195  				DynastyRoot: []byte("43656"),
   196  			},
   197  			coinbase:  &Address{address: []byte("hello")},
   198  			timestamp: BlockInterval,
   199  			chainID:   100,
   200  		},
   201  		transactions: []*Transaction{},
   202  	}
   203  	assert.Equal(t, block1.Height(), uint64(0))
   204  	assert.Equal(t, block1.LinkParentBlock(bc, genesis), nil)
   205  	assert.Equal(t, block1.Height(), uint64(2))
   206  	assert.Equal(t, block1.ParentHash(), genesis.Hash())
   207  	block2 := &Block{
   208  		header: &BlockHeader{
   209  			hash:       []byte("124546"),
   210  			parentHash: []byte("344543"),
   211  			stateRoot:  []byte("43656"),
   212  			txsRoot:    []byte("43656"),
   213  			eventsRoot: []byte("43656"),
   214  			consensusRoot: &consensuspb.ConsensusRoot{
   215  				DynastyRoot: []byte("43656"),
   216  			},
   217  			coinbase:  &Address{address: []byte("hello")},
   218  			timestamp: BlockInterval * 2,
   219  			chainID:   100,
   220  		},
   221  		transactions: []*Transaction{},
   222  	}
   223  	assert.Equal(t, block2.LinkParentBlock(bc, genesis), ErrLinkToWrongParentBlock)
   224  	assert.Equal(t, block2.Height(), uint64(0))
   225  }
   226  
   227  func TestBlock_fetchEvents(t *testing.T) {
   228  	neb := testNeb(t)
   229  	bc := neb.chain
   230  
   231  	tail := bc.tailBlock
   232  	events := []*state.Event{
   233  		&state.Event{Topic: "chain.block", Data: "hello"},
   234  		&state.Event{Topic: "chain.tx", Data: "hello"},
   235  		&state.Event{Topic: "chain.block", Data: "hello"},
   236  		&state.Event{Topic: "chain.block", Data: "hello"},
   237  	}
   238  	err := tail.worldState.Begin()
   239  	assert.Nil(t, err)
   240  	tx := &Transaction{hash: []byte("tx")}
   241  	txWorldState, err := tail.worldState.Prepare(byteutils.Hex(tx.Hash()))
   242  	assert.Nil(t, err)
   243  	for _, event := range events {
   244  		txWorldState.RecordEvent(tx.Hash(), event)
   245  	}
   246  	_, err = txWorldState.CheckAndUpdate()
   247  	assert.Nil(t, err)
   248  	tail.worldState.Commit()
   249  
   250  	es, err := tail.FetchEvents(tx.Hash())
   251  	assert.Nil(t, err)
   252  	assert.Equal(t, len(events), len(es))
   253  	for idx, event := range es {
   254  		assert.Equal(t, events[idx], event)
   255  	}
   256  }
   257  
   258  func TestBlockSign(t *testing.T) {
   259  	neb := testNeb(t)
   260  	bc := neb.chain
   261  	block := bc.tailBlock
   262  	ks := keystore.DefaultKS
   263  	signature, _ := crypto.NewSignature(keystore.SECP256K1)
   264  	signer := mockAddress()
   265  	key, _ := ks.GetUnlocked(signer.String())
   266  	signature.InitSign(key.(keystore.PrivateKey))
   267  	assert.Nil(t, block.Sign(signature))
   268  	assert.Equal(t, block.Alg(), keystore.Algorithm(keystore.SECP256K1))
   269  	assert.Equal(t, block.Signature(), block.header.sign)
   270  }
   271  
   272  func TestGivebackInvalidTx(t *testing.T) {
   273  	neb := testNeb(t)
   274  	bc := neb.chain
   275  	from := mockAddress()
   276  	ks := keystore.DefaultKS
   277  	gasLimit, _ := util.NewUint128FromInt(200000)
   278  	tx, _ := NewTransaction(bc.ChainID(), from, from, util.NewUint128(), 2, TxPayloadBinaryType, []byte("nas"), TransactionGasPrice, gasLimit)
   279  	key, err := ks.GetUnlocked(from.String())
   280  	assert.Nil(t, err)
   281  	signature, err := crypto.NewSignature(keystore.SECP256K1)
   282  	assert.Nil(t, err)
   283  	signature.InitSign(key.(keystore.PrivateKey))
   284  	tx.Sign(signature)
   285  	assert.Nil(t, bc.txPool.Push(tx))
   286  	assert.Equal(t, len(bc.txPool.all), 1)
   287  	block, err := bc.NewBlock(from)
   288  	assert.Nil(t, err)
   289  	block.CollectTransactions(time.Now().Unix() + 1)
   290  	assert.Equal(t, len(bc.txPool.all), 1)
   291  }
   292  
   293  func TestBlockVerifyIntegrity(t *testing.T) {
   294  	neb := testNeb(t)
   295  	bc := neb.chain
   296  	ks := keystore.DefaultKS
   297  	from := mockAddress()
   298  	key, err := ks.GetUnlocked(from.String())
   299  	assert.Nil(t, err)
   300  	signature, err := crypto.NewSignature(keystore.SECP256K1)
   301  	assert.Nil(t, err)
   302  	signature.InitSign(key.(keystore.PrivateKey))
   303  	block, err := bc.NewBlock(from)
   304  	assert.Nil(t, err)
   305  	gasLimit, _ := util.NewUint128FromInt(200000)
   306  	tx1, _ := NewTransaction(bc.ChainID(), from, from, util.NewUint128(), 1, TxPayloadBinaryType, []byte("nas"), TransactionGasPrice, gasLimit)
   307  	tx1.Sign(signature)
   308  	tx2, _ := NewTransaction(bc.ChainID(), from, from, util.NewUint128(), 2, TxPayloadBinaryType, []byte("nas"), TransactionGasPrice, gasLimit)
   309  	tx2.Sign(signature)
   310  	tx2.hash[0]++
   311  	block.transactions = append(block.transactions, tx1)
   312  	block.transactions = append(block.transactions, tx2)
   313  	block.Seal()
   314  	block.Sign(signature)
   315  	assert.NotNil(t, block.VerifyIntegrity(bc.ChainID(), bc.ConsensusHandler()))
   316  }
   317  
   318  func TestBlockVerifyDupTx(t *testing.T) {
   319  	neb := testNeb(t)
   320  	bc := neb.chain
   321  	ks := keystore.DefaultKS
   322  	from := mockAddress()
   323  	key, err := ks.GetUnlocked(from.String())
   324  	assert.Nil(t, err)
   325  	signature, err := crypto.NewSignature(keystore.SECP256K1)
   326  	assert.Nil(t, err)
   327  	signature.InitSign(key.(keystore.PrivateKey))
   328  	block, err := bc.NewBlock(from)
   329  	assert.Nil(t, err)
   330  	gasLimit, _ := util.NewUint128FromInt(200000)
   331  	tx1, _ := NewTransaction(bc.ChainID(), from, from, util.NewUint128(), 1, TxPayloadBinaryType, []byte("nas"), TransactionGasPrice, gasLimit)
   332  	tx1.Sign(signature)
   333  	_, err = block.ExecuteTransaction(tx1, block.worldState)
   334  	assert.Nil(t, err)
   335  	_, err = block.ExecuteTransaction(tx1, block.worldState)
   336  	assert.Equal(t, err, ErrSmallTransactionNonce)
   337  }
   338  
   339  func TestBlockVerifyInvalidTx(t *testing.T) {
   340  	neb := testNeb(t)
   341  	bc := neb.chain
   342  	ks := keystore.DefaultKS
   343  	from := mockAddress()
   344  	key, err := ks.GetUnlocked(from.String())
   345  	assert.Nil(t, err)
   346  	signature, err := crypto.NewSignature(keystore.SECP256K1)
   347  	assert.Nil(t, err)
   348  	signature.InitSign(key.(keystore.PrivateKey))
   349  	block, err := bc.NewBlock(from)
   350  	assert.Nil(t, err)
   351  	gasLimit, _ := util.NewUint128FromInt(200000)
   352  	tx1, _ := NewTransaction(bc.ChainID(), from, from, util.NewUint128(), 1, TxPayloadBinaryType, []byte("nas"), TransactionGasPrice, gasLimit)
   353  	tx1.Sign(signature)
   354  	tx2, _ := NewTransaction(bc.ChainID(), from, from, util.NewUint128(), 3, TxPayloadBinaryType, []byte("nas"), TransactionGasPrice, gasLimit)
   355  	tx2.Sign(signature)
   356  	_, err = block.ExecuteTransaction(tx1, block.worldState)
   357  	assert.Nil(t, err)
   358  	_, err = block.ExecuteTransaction(tx2, block.worldState)
   359  	assert.Equal(t, err, ErrLargeTransactionNonce)
   360  }
   361  
   362  func TestBlockVerifyState(t *testing.T) {
   363  	neb := testNeb(t)
   364  	bc := neb.chain
   365  	ks := keystore.DefaultKS
   366  	from := mockAddress()
   367  
   368  	key, err := ks.GetUnlocked(from.String())
   369  	assert.Nil(t, err)
   370  	signature, err := crypto.NewSignature(keystore.SECP256K1)
   371  	assert.Nil(t, err)
   372  	signature.InitSign(key.(keystore.PrivateKey))
   373  
   374  	tail := bc.tailBlock
   375  	assert.Nil(t, tail.Begin())
   376  	acc, err := tail.WorldState().GetOrCreateUserAccount(from.Bytes())
   377  	assert.Nil(t, err)
   378  	balance, _ := util.NewUint128FromString("100000000000000")
   379  	acc.AddBalance(balance)
   380  	tail.Commit()
   381  
   382  	block, err := bc.NewBlockFromParent(from, tail)
   383  	assert.Nil(t, err)
   384  	acc, err = tail.WorldState().GetOrCreateUserAccount(from.Bytes())
   385  	assert.Nil(t, err)
   386  
   387  	gasLimit, _ := util.NewUint128FromInt(200000)
   388  	tx1, _ := NewTransaction(bc.ChainID(), from, from, util.NewUint128(), 1, TxPayloadBinaryType, []byte("nas"), TransactionGasPrice, gasLimit)
   389  	tx1.Sign(signature)
   390  	tx2, _ := NewTransaction(bc.ChainID(), from, from, util.NewUint128(), 2, TxPayloadBinaryType, []byte("nas"), TransactionGasPrice, gasLimit)
   391  	tx2.Sign(signature)
   392  	_, err = block.ExecuteTransaction(tx1, block.worldState)
   393  	assert.Nil(t, err)
   394  	block.transactions = append(block.transactions, tx1)
   395  	block.transactions = append(block.transactions, tx2)
   396  	_, err = block.ExecuteTransaction(tx2, block.worldState)
   397  	assert.Nil(t, err)
   398  	dependency := dag.NewDag()
   399  	dependency.AddNode(tx1.Hash().Hex())
   400  	dependency.AddNode(tx2.Hash().Hex())
   401  	dependency.AddEdge(tx1.Hash().Hex(), tx2.Hash().Hex())
   402  	block.dependency = dependency
   403  	block.Seal()
   404  	block.Sign(signature)
   405  	assert.Nil(t, block.VerifyIntegrity(bc.ChainID(), bc.ConsensusHandler()))
   406  
   407  	block.header.stateRoot[0]++
   408  	assert.NotNil(t, block.VerifyExecution())
   409  }
   410  
   411  func TestBlock_String(t *testing.T) {
   412  	neb := testNeb(t)
   413  	bc := neb.chain
   414  	assert.NotNil(t, bc.genesisBlock.String())
   415  }