github.com/igggame/nebulas-go@v2.1.0+incompatible/consensus/dpos/dpos_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 dpos 20 21 import ( 22 "os" 23 "runtime" 24 "testing" 25 26 "github.com/gogo/protobuf/proto" 27 28 "github.com/nebulasio/go-nebulas/util" 29 30 "time" 31 32 "github.com/nebulasio/go-nebulas/account" 33 "github.com/nebulasio/go-nebulas/core" 34 "github.com/nebulasio/go-nebulas/crypto/keystore" 35 "github.com/stretchr/testify/assert" 36 ) 37 38 var ( 39 DefaultOpenDynasty = core.NewMockNeb(nil, nil, nil).Genesis().Consensus.Dpos.Dynasty 40 ) 41 42 func mockBlockFromNetwork(block *core.Block) (*core.Block, error) { 43 pbBlock, err := block.ToProto() 44 if err != nil { 45 return nil, err 46 } 47 bytes, err := proto.Marshal(pbBlock) 48 if err := proto.Unmarshal(bytes, pbBlock); err != nil { 49 return nil, err 50 } 51 block = new(core.Block) 52 block.FromProto(pbBlock) 53 return block, nil 54 } 55 56 func mockNeb(t *testing.T) *core.MockNeb { 57 consensus := NewDpos() 58 am, err := account.NewManager(nil) 59 assert.Nil(t, err) 60 neb := core.NewMockNeb(am, consensus, nil) 61 return neb 62 } 63 64 func TestDpos_New(t *testing.T) { 65 neb := mockNeb(t) 66 coinbase := neb.Config().Chain.Coinbase 67 neb.Config().Chain.Coinbase += "0" 68 assert.NotNil(t, neb.Consensus().Setup(neb)) 69 neb.Config().Chain.Coinbase = coinbase 70 neb.Config().Chain.Miner += "0" 71 assert.NotNil(t, neb.Consensus().Setup(neb)) 72 } 73 74 func TestDpos_VerifySign(t *testing.T) { 75 neb := mockNeb(t) 76 tail := neb.BlockChain().TailBlock() 77 78 elapsedSecondInMs := int64(DynastySize*BlockIntervalInMs + DynastyIntervalInMs) 79 consensusState, err := tail.WorldState().NextConsensusState(elapsedSecondInMs / SecondInMs) 80 assert.Nil(t, err) 81 coinbase, err := core.AddressParse("n1FF1nz6tarkDVwWQkMnnwFPuPKUaQTdptE") 82 assert.Nil(t, err) 83 block, err := core.NewBlock(neb.BlockChain().ChainID(), coinbase, tail) 84 assert.Nil(t, err) 85 block.SetTimestamp((DynastySize*BlockIntervalInMs + DynastyIntervalInMs) / SecondInMs) 86 block.WorldState().SetConsensusState(consensusState) 87 block.Seal() 88 manager, _ := account.NewManager(nil) 89 miner, err := core.AddressParse("n1GmkKH6nBMw4rrjt16RrJ9WcgvKUtAZP1s") 90 assert.Nil(t, err) 91 assert.Nil(t, manager.Unlock(miner, []byte("passphrase"), keystore.DefaultUnlockDuration)) 92 assert.Nil(t, manager.SignBlock(miner, block)) 93 assert.Equal(t, neb.Consensus().VerifyBlock(block), ErrInvalidBlockProposer) 94 } 95 96 func GetUnlockAddress(t *testing.T, am core.AccountManager, addr string) *core.Address { 97 address, err := core.AddressParse(addr) 98 assert.Nil(t, err) 99 assert.Nil(t, am.Unlock(address, []byte("passphrase"), time.Second*60*60*24*365)) 100 return address 101 } 102 103 func TestForkChoice(t *testing.T) { 104 neb := mockNeb(t) 105 am, _ := account.NewManager(neb) 106 107 /* 108 genesis -- 0 -- 11 -- 111 -- 1111 109 \_ 12 -- 221 110 */ 111 112 addr0 := GetUnlockAddress(t, am, "n1GmkKH6nBMw4rrjt16RrJ9WcgvKUtAZP1s") 113 block0, _ := neb.BlockChain().NewBlock(addr0) 114 block0.SetTimestamp(BlockIntervalInMs / SecondInMs) 115 consensusState, err := neb.BlockChain().TailBlock().WorldState().NextConsensusState(BlockIntervalInMs / SecondInMs) 116 assert.Nil(t, err) 117 block0.WorldState().SetConsensusState(consensusState) 118 block0.Seal() 119 am.SignBlock(addr0, block0) 120 assert.Nil(t, neb.BlockChain().BlockPool().Push(block0)) 121 assert.Equal(t, len(neb.BlockChain().DetachedTailBlocks()), 1) 122 assert.Equal(t, block0.Hash(), neb.BlockChain().TailBlock().Hash()) 123 124 addr1 := GetUnlockAddress(t, am, "n1H4MYms9F55ehcvygwWE71J8tJC4CRr2so") 125 block11, err := neb.BlockChain().NewBlock(addr1) 126 assert.Nil(t, err) 127 consensusState, err = neb.BlockChain().TailBlock().WorldState().NextConsensusState(BlockIntervalInMs / SecondInMs) 128 assert.Nil(t, err) 129 block11.WorldState().SetConsensusState(consensusState) 130 block11.SetTimestamp((BlockIntervalInMs * 2) / SecondInMs) 131 block11.Seal() 132 am.SignBlock(addr1, block11) 133 134 addr2 := GetUnlockAddress(t, am, "n1JAy4X6KKLCNiTd7MWMRsVBjgdVq5WCCpf") 135 block12, err := neb.BlockChain().NewBlock(addr2) 136 assert.Nil(t, err) 137 consensusState, err = neb.BlockChain().TailBlock().WorldState().NextConsensusState(BlockIntervalInMs * 2 / SecondInMs) 138 assert.Nil(t, err) 139 block12.WorldState().SetConsensusState(consensusState) 140 block12.SetTimestamp(BlockIntervalInMs * 3 / SecondInMs) 141 block12.Seal() 142 am.SignBlock(addr2, block12) 143 144 assert.Nil(t, neb.BlockChain().BlockPool().Push(block11)) 145 assert.Equal(t, len(neb.BlockChain().DetachedTailBlocks()), 1) 146 assert.Equal(t, block11.Hash(), neb.BlockChain().TailBlock().Hash()) 147 148 assert.Nil(t, neb.BlockChain().BlockPool().Push(block12)) 149 assert.Equal(t, len(neb.BlockChain().DetachedTailBlocks()), 2) 150 tail := block11.Hash() 151 if less(block11, block12) { 152 tail = block12.Hash() 153 } 154 assert.Equal(t, neb.BlockChain().TailBlock().Hash(), tail) 155 156 addr3 := GetUnlockAddress(t, am, "n1LkDi2gGMqPrjYcczUiweyP4RxTB6Go1qS") 157 block111, err := neb.BlockChain().NewBlock(addr3) 158 assert.Nil(t, err) 159 consensusState, err = neb.BlockChain().TailBlock().WorldState().NextConsensusState(BlockIntervalInMs * 2 / SecondInMs) 160 assert.Nil(t, err) 161 block111.WorldState().SetConsensusState(consensusState) 162 block111.SetTimestamp(BlockIntervalInMs * 4 / SecondInMs) 163 block111.Seal() 164 am.SignBlock(addr3, block111) 165 assert.Equal(t, len(neb.BlockChain().DetachedTailBlocks()), 2) 166 assert.Nil(t, neb.BlockChain().BlockPool().Push(block111)) 167 168 } 169 170 func TestCanMining(t *testing.T) { 171 neb := mockNeb(t) 172 assert.Equal(t, neb.Consensus().Pending(), true) 173 neb.Consensus().SuspendMining() 174 assert.Equal(t, neb.Consensus().Pending(), true) 175 neb.Consensus().ResumeMining() 176 assert.Equal(t, neb.Consensus().Pending(), false) 177 } 178 179 func TestVerifyBlock(t *testing.T) { 180 neb := mockNeb(t) 181 dpos := neb.Consensus() 182 tail := neb.BlockChain().TailBlock() 183 184 coinbase, err := core.AddressParse("n1FF1nz6tarkDVwWQkMnnwFPuPKUaQTdptE") 185 assert.Nil(t, err) 186 manager, _ := account.NewManager(neb) 187 assert.Nil(t, dpos.EnableMining("passphrase")) 188 189 elapsedSecond := DynastyIntervalInMs / SecondInMs 190 consensusState, err := tail.WorldState().NextConsensusState(elapsedSecond) 191 assert.Nil(t, err) 192 block, err := core.NewBlock(neb.BlockChain().ChainID(), coinbase, tail) 193 block.SetTimestamp(tail.Timestamp() + 1) 194 assert.Nil(t, err) 195 block.WorldState().SetConsensusState(consensusState) 196 block.Seal() 197 assert.Nil(t, manager.Unlock(coinbase, []byte("passphrase"), keystore.DefaultUnlockDuration)) 198 assert.Nil(t, manager.SignBlock(coinbase, block)) 199 200 assert.NotNil(t, dpos.VerifyBlock(block), ErrInvalidBlockInterval) 201 202 elapsedSecond = DynastyIntervalInMs / SecondInMs 203 consensusState, err = tail.WorldState().NextConsensusState(elapsedSecond) 204 block, err = core.NewBlock(neb.BlockChain().ChainID(), coinbase, tail) 205 assert.Nil(t, err) 206 block.WorldState().SetConsensusState(consensusState) 207 block.SetTimestamp(tail.Timestamp() + elapsedSecond) 208 block.Seal() 209 assert.Nil(t, manager.SignBlock(coinbase, block)) 210 assert.Nil(t, dpos.VerifyBlock(block)) 211 212 elapsedSecond = (DynastySize*BlockIntervalInMs + DynastyIntervalInMs) / SecondInMs 213 consensusState, err = tail.WorldState().NextConsensusState(elapsedSecond) 214 block, err = core.NewBlock(neb.BlockChain().ChainID(), coinbase, tail) 215 assert.Nil(t, err) 216 block.WorldState().SetConsensusState(consensusState) 217 block.SetTimestamp(tail.Timestamp() + elapsedSecond) 218 block.Seal() 219 assert.Nil(t, manager.SignBlock(coinbase, block)) 220 assert.Nil(t, dpos.VerifyBlock(block)) 221 } 222 223 func TestDpos_MintBlock(t *testing.T) { 224 neb := mockNeb(t) 225 dpos := neb.Consensus().(*Dpos) 226 227 assert.Equal(t, dpos.mintBlock(0), ErrCannotMintWhenDisable) 228 229 assert.Nil(t, dpos.EnableMining("passphrase")) 230 dpos.SuspendMining() 231 assert.Equal(t, dpos.mintBlock(0), ErrCannotMintWhenPending) 232 dpos.ResumeMining() 233 assert.Equal(t, dpos.mintBlock(BlockIntervalInMs/SecondInMs), ErrInvalidBlockProposer) 234 235 //received := []byte{} 236 assert.Equal(t, dpos.mintBlock(DynastyIntervalInMs/SecondInMs), nil) 237 //assert.NotEqual(t, received, []byte{}) 238 } 239 240 func TestDposContracts(t *testing.T) { 241 // change cwd make lib accessible. 242 os.Chdir("../../") 243 runtime.GOMAXPROCS(runtime.NumCPU()) 244 neb := mockNeb(t) 245 tail := neb.BlockChain().TailBlock() 246 dpos := neb.Consensus() 247 248 manager, _ := account.NewManager(neb) 249 assert.Nil(t, dpos.EnableMining("passphrase")) 250 251 a, _ := core.AddressParse("n1FF1nz6tarkDVwWQkMnnwFPuPKUaQTdptE") 252 assert.Nil(t, manager.Unlock(a, []byte("passphrase"), keystore.YearUnlockDuration)) 253 b, _ := core.AddressParse("n1GmkKH6nBMw4rrjt16RrJ9WcgvKUtAZP1s") 254 assert.Nil(t, manager.Unlock(b, []byte("passphrase"), keystore.YearUnlockDuration)) 255 c, _ := core.AddressParse("n1H4MYms9F55ehcvygwWE71J8tJC4CRr2so") 256 assert.Nil(t, manager.Unlock(c, []byte("passphrase"), keystore.YearUnlockDuration)) 257 d, _ := core.AddressParse("n1JAy4X6KKLCNiTd7MWMRsVBjgdVq5WCCpf") 258 assert.Nil(t, manager.Unlock(d, []byte("passphrase"), keystore.YearUnlockDuration)) 259 e, _ := core.AddressParse("n1LkDi2gGMqPrjYcczUiweyP4RxTB6Go1qS") 260 assert.Nil(t, manager.Unlock(e, []byte("passphrase"), keystore.YearUnlockDuration)) 261 f, _ := core.AddressParse("n1LmP9K8pFF33fgdgHZonFEMsqZinJ4EUqk") 262 assert.Nil(t, manager.Unlock(f, []byte("passphrase"), keystore.YearUnlockDuration)) 263 264 elapsedSecond := BlockIntervalInMs / SecondInMs 265 consensusState, err := tail.WorldState().NextConsensusState(elapsedSecond) 266 assert.Nil(t, err) 267 block, err := core.NewBlock(neb.BlockChain().ChainID(), b, tail) 268 assert.Nil(t, err) 269 block.WorldState().SetConsensusState(consensusState) 270 block.SetTimestamp(consensusState.TimeStamp()) 271 272 source := `"use strict";var DepositeContent=function(text){if(text){var o=JSON.parse(text);this.balance=new BigNumber(o.balance);this.expiryHeight=new BigNumber(o.expiryHeight)}else{this.balance=new BigNumber(0);this.expiryHeight=new BigNumber(0)}};DepositeContent.prototype={toString:function(){return JSON.stringify(this)}};var BankVaultContract=function(){LocalContractStorage.defineMapProperty(this,"bankVault",{parse:function(text){return new DepositeContent(text)},stringify:function(o){return o.toString()}})};BankVaultContract.prototype={init:function(){},save:function(height){var from=Blockchain.transaction.from;var value=Blockchain.transaction.value;var bk_height=new BigNumber(Blockchain.block.height);var orig_deposit=this.bankVault.get(from);if(orig_deposit){value=value.plus(orig_deposit.balance)}var deposit=new DepositeContent();deposit.balance=value;deposit.expiryHeight=bk_height.plus(height);this.bankVault.put(from,deposit)},takeout:function(value){var from=Blockchain.transaction.from;var bk_height=new BigNumber(Blockchain.block.height);var amount=new BigNumber(value);var deposit=this.bankVault.get(from);if(!deposit){throw new Error("No deposit before.")}if(bk_height.lt(deposit.expiryHeight)){throw new Error("Can not takeout before expiryHeight.")}if(amount.gt(deposit.balance)){throw new Error("Insufficient balance.")}var result=Blockchain.transfer(from,amount);if(result!=0){throw new Error("transfer failed.")}Event.Trigger("BankVault",{Transfer:{from:Blockchain.transaction.to,to:from,value:amount.toString()}});deposit.balance=deposit.balance.sub(amount);this.bankVault.put(from,deposit)},balanceOf:function(){var from=Blockchain.transaction.from;return this.bankVault.get(from)}};module.exports=BankVaultContract;` 273 sourceType := "js" 274 argsDeploy := "" 275 deploy, _ := core.NewDeployPayload(source, sourceType, argsDeploy) 276 payloadDeploy, _ := deploy.ToBytes() 277 278 j := 2 279 280 for i := 1; i < j; i++ { 281 value, _ := util.NewUint128FromInt(1) 282 gasLimit, _ := util.NewUint128FromInt(200000) 283 txDeploy, _ := core.NewTransaction(neb.BlockChain().ChainID(), a, a, value, uint64(i), core.TxPayloadDeployType, payloadDeploy, core.TransactionGasPrice, gasLimit) 284 assert.Nil(t, manager.SignTransaction(a, txDeploy)) 285 assert.Nil(t, neb.BlockChain().TransactionPool().Push(txDeploy)) 286 287 txDeploy, _ = core.NewTransaction(neb.BlockChain().ChainID(), b, b, value, uint64(i), core.TxPayloadDeployType, payloadDeploy, core.TransactionGasPrice, gasLimit) 288 assert.Nil(t, manager.SignTransaction(b, txDeploy)) 289 assert.Nil(t, neb.BlockChain().TransactionPool().Push(txDeploy)) 290 291 txDeploy, _ = core.NewTransaction(neb.BlockChain().ChainID(), c, c, value, uint64(i), core.TxPayloadDeployType, payloadDeploy, core.TransactionGasPrice, gasLimit) 292 assert.Nil(t, manager.SignTransaction(c, txDeploy)) 293 assert.Nil(t, neb.BlockChain().TransactionPool().Push(txDeploy)) 294 295 txDeploy, _ = core.NewTransaction(neb.BlockChain().ChainID(), d, d, value, uint64(i), core.TxPayloadDeployType, payloadDeploy, core.TransactionGasPrice, gasLimit) 296 assert.Nil(t, manager.SignTransaction(d, txDeploy)) 297 assert.Nil(t, neb.BlockChain().TransactionPool().Push(txDeploy)) 298 } 299 300 block.CollectTransactions((time.Now().Unix() + 1) * SecondInMs) 301 assert.Equal(t, 4*(j-1), len(block.Transactions())) 302 assert.Nil(t, block.Seal()) 303 assert.Nil(t, manager.SignBlock(b, block)) 304 assert.Nil(t, neb.BlockChain().BlockPool().Push(block)) 305 306 assert.Equal(t, block.Hash(), neb.BlockChain().TailBlock().Hash()) 307 } 308 309 func testMintBlock(t *testing.T, round int, neb core.Neblet, num int) { 310 manager, _ := account.NewManager(neb) 311 312 a, _ := core.AddressParse("n1FF1nz6tarkDVwWQkMnnwFPuPKUaQTdptE") 313 assert.Nil(t, manager.Unlock(a, []byte("passphrase"), keystore.YearUnlockDuration)) 314 b, _ := core.AddressParse("n1GmkKH6nBMw4rrjt16RrJ9WcgvKUtAZP1s") 315 assert.Nil(t, manager.Unlock(b, []byte("passphrase"), keystore.YearUnlockDuration)) 316 c, _ := core.AddressParse("n1H4MYms9F55ehcvygwWE71J8tJC4CRr2so") 317 assert.Nil(t, manager.Unlock(c, []byte("passphrase"), keystore.YearUnlockDuration)) 318 d, _ := core.AddressParse("n1JAy4X6KKLCNiTd7MWMRsVBjgdVq5WCCpf") 319 assert.Nil(t, manager.Unlock(d, []byte("passphrase"), keystore.YearUnlockDuration)) 320 e, _ := core.AddressParse("n1LkDi2gGMqPrjYcczUiweyP4RxTB6Go1qS") 321 assert.Nil(t, manager.Unlock(e, []byte("passphrase"), keystore.YearUnlockDuration)) 322 f, _ := core.AddressParse("n1LmP9K8pFF33fgdgHZonFEMsqZinJ4EUqk") 323 assert.Nil(t, manager.Unlock(f, []byte("passphrase"), keystore.YearUnlockDuration)) 324 325 elapsedSecond := int64(BlockIntervalInMs / SecondInMs) 326 consensusState, err := neb.BlockChain().TailBlock().WorldState().NextConsensusState(elapsedSecond) 327 assert.Nil(t, err) 328 329 coinbases := []*core.Address{a, b, c, d, e, f} 330 coinbase := coinbases[(round+1)%len(coinbases)] 331 block, err := core.NewBlock(neb.BlockChain().ChainID(), coinbase, neb.BlockChain().TailBlock()) 332 assert.Nil(t, err) 333 block.WorldState().SetConsensusState(consensusState) 334 block.SetTimestamp(consensusState.TimeStamp()) 335 acc, _ := block.WorldState().GetOrCreateUserAccount(a.Bytes()) 336 nonce := int(acc.Nonce()) 337 338 for i := 1; i < num; i++ { 339 gas, _ := util.NewUint128FromInt(1000000) 340 limit, _ := util.NewUint128FromInt(200000) 341 tx, _ := core.NewTransaction(neb.BlockChain().ChainID(), a, b, util.NewUint128(), uint64(nonce+4*i-3), core.TxPayloadBinaryType, []byte("nas"), gas, limit) 342 assert.Nil(t, manager.SignTransaction(a, tx)) 343 assert.Nil(t, neb.BlockChain().TransactionPool().Push(tx)) 344 345 tx, _ = core.NewTransaction(neb.BlockChain().ChainID(), a, c, util.NewUint128(), uint64(nonce+4*i-2), core.TxPayloadBinaryType, []byte("nas"), gas, limit) 346 assert.Nil(t, manager.SignTransaction(a, tx)) 347 assert.Nil(t, neb.BlockChain().TransactionPool().Push(tx)) 348 349 tx, _ = core.NewTransaction(neb.BlockChain().ChainID(), a, d, util.NewUint128(), uint64(nonce+4*i-1), core.TxPayloadBinaryType, []byte("nas"), gas, limit) 350 assert.Nil(t, manager.SignTransaction(a, tx)) 351 assert.Nil(t, neb.BlockChain().TransactionPool().Push(tx)) 352 353 tx, _ = core.NewTransaction(neb.BlockChain().ChainID(), a, e, util.NewUint128(), uint64(nonce+4*i), core.TxPayloadBinaryType, []byte("nas"), gas, limit) 354 assert.Nil(t, manager.SignTransaction(a, tx)) 355 assert.Nil(t, neb.BlockChain().TransactionPool().Push(tx)) 356 357 tx, _ = core.NewTransaction(neb.BlockChain().ChainID(), b, f, util.NewUint128(), uint64(i), core.TxPayloadBinaryType, []byte("nas"), gas, limit) 358 assert.Nil(t, manager.SignTransaction(b, tx)) 359 assert.Nil(t, neb.BlockChain().TransactionPool().Push(tx)) 360 361 tx, _ = core.NewTransaction(neb.BlockChain().ChainID(), c, f, util.NewUint128(), uint64(i), core.TxPayloadBinaryType, []byte("nas"), gas, limit) 362 assert.Nil(t, manager.SignTransaction(c, tx)) 363 assert.Nil(t, neb.BlockChain().TransactionPool().Push(tx)) 364 365 tx, _ = core.NewTransaction(neb.BlockChain().ChainID(), d, f, util.NewUint128(), uint64(i), core.TxPayloadBinaryType, []byte("nas"), gas, limit) 366 assert.Nil(t, manager.SignTransaction(d, tx)) 367 assert.Nil(t, neb.BlockChain().TransactionPool().Push(tx)) 368 } 369 370 block.CollectTransactions((time.Now().Unix() + 1) * SecondInMs) 371 assert.Equal(t, 7*(num-1), len(block.Transactions())) 372 assert.Nil(t, block.Seal()) 373 assert.Nil(t, manager.SignBlock(coinbase, block)) 374 assert.Nil(t, neb.BlockChain().BlockPool().Push(block)) 375 376 assert.Equal(t, block.Hash(), neb.BlockChain().TailBlock().Hash()) 377 } 378 379 func TestDposTxBinary(t *testing.T) { 380 runtime.GOMAXPROCS(runtime.NumCPU()) 381 382 neb := mockNeb(t) 383 384 for i := 0; i < 1; i++ { 385 testMintBlock(t, i, neb, 5) 386 } 387 388 return 389 } 390 391 func TestDoubleMint(t *testing.T) { 392 neb := mockNeb(t) 393 chain := neb.BlockChain() 394 am := neb.AccountManager() 395 396 addr0 := GetUnlockAddress(t, am, "n1GmkKH6nBMw4rrjt16RrJ9WcgvKUtAZP1s") 397 398 block0, _ := chain.NewBlock(addr0) 399 consensusState, err := chain.TailBlock().WorldState().NextConsensusState(BlockIntervalInMs / SecondInMs) 400 assert.Nil(t, err) 401 block0.SetTimestamp(chain.TailBlock().Timestamp() + BlockIntervalInMs/SecondInMs) 402 block0.WorldState().SetConsensusState(consensusState) 403 block0.Seal() 404 am.SignBlock(addr0, block0) 405 406 assert.Nil(t, chain.BlockPool().Push(block0)) 407 assert.Equal(t, block0.Hash(), chain.TailBlock().Hash()) 408 409 consensusState, err = chain.TailBlock().WorldState().NextConsensusState(0) 410 assert.Equal(t, err, ErrNotBlockForgTime) 411 }