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 }