diff options
author | bojie <bojie@dexon.org> | 2019-01-14 20:42:15 +0800 |
---|---|---|
committer | Wei-Ning Huang <w@dexon.org> | 2019-04-09 21:32:56 +0800 |
commit | 2155bbd85373a8527e3b565f4316bc4f1517650a (patch) | |
tree | 2f64cbc5a6810aa496524c7509a4998847526123 /dex | |
parent | 3fcb8b6825b3c62c9890a5ca59594f1503e66893 (diff) | |
download | dexon-2155bbd85373a8527e3b565f4316bc4f1517650a.tar dexon-2155bbd85373a8527e3b565f4316bc4f1517650a.tar.gz dexon-2155bbd85373a8527e3b565f4316bc4f1517650a.tar.bz2 dexon-2155bbd85373a8527e3b565f4316bc4f1517650a.tar.lz dexon-2155bbd85373a8527e3b565f4316bc4f1517650a.tar.xz dexon-2155bbd85373a8527e3b565f4316bc4f1517650a.tar.zst dexon-2155bbd85373a8527e3b565f4316bc4f1517650a.zip |
app: remove pending block logic (#149)
Diffstat (limited to 'dex')
-rw-r--r-- | dex/api_backend.go | 6 | ||||
-rw-r--r-- | dex/app.go | 72 | ||||
-rw-r--r-- | dex/app_test.go | 224 | ||||
-rw-r--r-- | dex/backend.go | 2 |
4 files changed, 142 insertions, 162 deletions
diff --git a/dex/api_backend.go b/dex/api_backend.go index 80fe1e39b..957f4d886 100644 --- a/dex/api_backend.go +++ b/dex/api_backend.go @@ -60,7 +60,7 @@ func (b *DexAPIBackend) SetHead(number uint64) { func (b *DexAPIBackend) HeaderByNumber(ctx context.Context, blockNr rpc.BlockNumber) (*types.Header, error) { // Otherwise resolve and return the block - if blockNr == rpc.LatestBlockNumber { + if blockNr == rpc.LatestBlockNumber || blockNr == rpc.PendingBlockNumber { return b.dex.blockchain.CurrentBlock().Header(), nil } return b.dex.blockchain.GetHeaderByNumber(uint64(blockNr)), nil @@ -79,10 +79,6 @@ func (b *DexAPIBackend) BlockByNumber(ctx context.Context, blockNr rpc.BlockNumb } func (b *DexAPIBackend) StateAndHeaderByNumber(ctx context.Context, blockNr rpc.BlockNumber) (*state.StateDB, *types.Header, error) { - if blockNr == rpc.PendingBlockNumber { - block, state := b.dex.BlockChain().GetPending() - return state, block.Header(), nil - } header, err := b.HeaderByNumber(ctx, blockNr) if header == nil || err != nil { return nil, nil, err diff --git a/dex/app.go b/dex/app.go index b1a0b4548..c40371254 100644 --- a/dex/app.go +++ b/dex/app.go @@ -49,6 +49,7 @@ type DexconApp struct { scope event.SubscriptionScope chainLocks sync.Map + chainRoot sync.Map } func NewDexconApp(txPool *core.TxPool, blockchain *core.BlockChain, gov *DexconGovernance, @@ -202,8 +203,16 @@ func (d *DexconApp) preparePayload(ctx context.Context, position coreTypes.Posit } } - b, latestState := d.blockchain.GetPending() - log.Debug("Prepare payload", "chain", position.ChainID, "height", position.Height, "state", b.Root().String()) + root, exist := d.chainRoot.Load(position.ChainID) + if !exist { + return nil, nil + } + + currentState, err := d.blockchain.StateAt(*root.(*common.Hash)) + if err != nil { + return nil, err + } + log.Debug("Prepare payload", "chain", position.ChainID, "height", position.Height) txsMap, err := d.txPool.Pending() if err != nil { @@ -228,7 +237,7 @@ addressMap: continue } - balance := latestState.GetBalance(address) + balance := currentState.GetBalance(address) cost, exist := d.blockchain.GetCostInConfirmedBlocks(position.ChainID, address) if exist { balance = new(big.Int).Sub(balance, cost) @@ -237,7 +246,7 @@ addressMap: var expectNonce uint64 lastConfirmedNonce, exist := d.blockchain.GetLastNonceInConfirmedBlocks(position.ChainID, address) if !exist { - expectNonce = latestState.GetNonce(address) + expectNonce = currentState.GetNonce(address) } else { expectNonce = lastConfirmedNonce + 1 } @@ -249,7 +258,8 @@ addressMap: firstNonce := txs[0].Nonce() startIndex := int(expectNonce - firstNonce) - for i := startIndex; i < len(txs); i++ { + // Warning: the pending tx will also affect by syncing, so startIndex maybe negative + for i := startIndex; i >= 0 && i < len(txs); i++ { tx := txs[i] intrGas, err := core.IntrinsicGas(tx.Data(), tx.To() == nil, true) if err != nil { @@ -282,15 +292,12 @@ addressMap: // PrepareWitness will return the witness data no lower than consensusHeight. func (d *DexconApp) PrepareWitness(consensusHeight uint64) (witness coreTypes.Witness, err error) { var witnessBlock *types.Block - lastPendingHeight := d.blockchain.GetPendingHeight() - if lastPendingHeight == 0 && consensusHeight == 0 { + if d.blockchain.CurrentBlock().NumberU64() >= consensusHeight { witnessBlock = d.blockchain.CurrentBlock() - } else if lastPendingHeight >= consensusHeight { - witnessBlock = d.blockchain.PendingBlock() } else { - log.Error("last pending height too low", "lastPendingHeight", lastPendingHeight, + log.Error("Current height too low", "lastPendingHeight", d.blockchain.CurrentBlock().NumberU64(), "consensusHeight", consensusHeight) - return witness, fmt.Errorf("last pending height < consensus height") + return witness, fmt.Errorf("current height < consensus height") } witnessData, err := rlp.EncodeToBytes(&types.WitnessData{ @@ -312,23 +319,20 @@ func (d *DexconApp) VerifyBlock(block *coreTypes.Block) coreTypes.BlockVerifySta var witnessData types.WitnessData err := rlp.DecodeBytes(block.Witness.Data, &witnessData) if err != nil { - log.Error("failed to RLP decode witness data", "error", err) + log.Error("Failed to RLP decode witness data", "error", err) return coreTypes.VerifyInvalidBlock } // Validate witness height. - if d.blockchain.GetPendingHeight() < block.Witness.Height { - log.Debug("Pending height < witness height") + if d.blockchain.CurrentBlock().NumberU64() < block.Witness.Height { + log.Debug("Current height < witness height") return coreTypes.VerifyRetryLater } - b := d.blockchain.GetPendingBlockByNumber(block.Witness.Height) + b := d.blockchain.GetBlockByNumber(block.Witness.Height) if b == nil { - b = d.blockchain.GetBlockByNumber(block.Witness.Height) - if b == nil { - log.Error("Can not get block by height %v", block.Witness.Height) - return coreTypes.VerifyInvalidBlock - } + log.Error("Can not get block by height %v", block.Witness.Height) + return coreTypes.VerifyInvalidBlock } if b.Root() != witnessData.Root { @@ -381,10 +385,18 @@ func (d *DexconApp) VerifyBlock(block *coreTypes.Block) coreTypes.BlockVerifySta } } - // Get latest pending state. - b, latestState := d.blockchain.GetPending() - log.Debug("Verify block", "chain", block.Position.ChainID, "height", block.Position.Height, "state", - b.Root().String()) + // Get latest state with current chain. + root, exist := d.chainRoot.Load(block.Position.ChainID) + if !exist { + return coreTypes.VerifyRetryLater + } + + currentState, err := d.blockchain.StateAt(*root.(*common.Hash)) + log.Debug("Verify block", "chain", block.Position.ChainID, "height", block.Position.Height) + if err != nil { + log.Debug("Invalid state root", "root", *root.(*common.Hash), "err", err) + return coreTypes.VerifyInvalidBlock + } var transactions types.Transactions if len(block.Payload) == 0 { @@ -423,7 +435,7 @@ func (d *DexconApp) VerifyBlock(block *coreTypes.Block) coreTypes.BlockVerifySta if exist { expectNonce = lastConfirmedNonce + 1 } else { - expectNonce = latestState.GetNonce(address) + expectNonce = currentState.GetNonce(address) } if expectNonce != firstNonce { @@ -437,9 +449,9 @@ func (d *DexconApp) VerifyBlock(block *coreTypes.Block) coreTypes.BlockVerifySta for address := range addressNonce { cost, exist := d.blockchain.GetCostInConfirmedBlocks(block.Position.ChainID, address) if exist { - addressesBalance[address] = new(big.Int).Sub(latestState.GetBalance(address), cost) + addressesBalance[address] = new(big.Int).Sub(currentState.GetBalance(address), cost) } else { - addressesBalance[address] = latestState.GetBalance(address) + addressesBalance[address] = currentState.GetBalance(address) } } @@ -518,19 +530,21 @@ func (d *DexconApp) BlockDelivered( }, txs, nil, nil) h := d.blockchain.CurrentBlock().NumberU64() + 1 + var root *common.Hash if block.IsEmpty() { - err = d.blockchain.ProcessEmptyBlock(newBlock) + root, err = d.blockchain.ProcessEmptyBlock(newBlock) if err != nil { log.Error("Failed to process empty block", "error", err) panic(err) } } else { - _, err = d.blockchain.ProcessPendingBlock(newBlock, &block.Witness) + root, err = d.blockchain.ProcessBlock(newBlock, &block.Witness) if err != nil { log.Error("Failed to process pending block", "error", err) panic(err) } } + d.chainRoot.Store(chainID, root) d.blockchain.RemoveConfirmedBlock(chainID, blockHash) diff --git a/dex/app_test.go b/dex/app_test.go index c79dbc42c..7d665a0af 100644 --- a/dex/app_test.go +++ b/dex/app_test.go @@ -26,12 +26,12 @@ import ( func TestPreparePayload(t *testing.T) { key, err := crypto.GenerateKey() if err != nil { - t.Errorf("hex to ecdsa error: %v", err) + t.Fatalf("hex to ecdsa error: %v", err) } dex, err := newTestDexonWithGenesis(key) if err != nil { - t.Errorf("new test dexon error: %v", err) + t.Fatalf("new test dexon error: %v", err) } signer := types.NewEIP155Signer(dex.chainConfig.ChainID) @@ -40,7 +40,7 @@ func TestPreparePayload(t *testing.T) { for i := 0; i < 5; i++ { tx, err := addTx(dex, i, signer, key) if err != nil { - t.Errorf("add tx error: %v", err) + t.Fatalf("add tx error: %v", err) } expectTx = append(expectTx, tx) } @@ -48,7 +48,7 @@ func TestPreparePayload(t *testing.T) { // This transaction will not be included. _, err = addTx(dex, 100, signer, key) if err != nil { - t.Errorf("add tx error: %v", err) + t.Fatalf("add tx error: %v", err) } chainID := new(big.Int).Mod(crypto.PubkeyToAddress(key.PublicKey).Big(), @@ -56,39 +56,41 @@ func TestPreparePayload(t *testing.T) { var chainNum uint32 for chainNum = 0; chainNum < dex.chainConfig.Dexcon.NumChains; chainNum++ { + root := dex.blockchain.CurrentBlock().Root() + dex.app.chainRoot.Store(chainNum, &root) payload, err := dex.app.PreparePayload(coreTypes.Position{ChainID: chainNum}) if err != nil { - t.Errorf("prepare payload error: %v", err) + t.Fatalf("prepare payload error: %v", err) } var transactions types.Transactions err = rlp.DecodeBytes(payload, &transactions) if err != nil { - t.Errorf("rlp decode error: %v", err) + t.Fatalf("rlp decode error: %v", err) } // Only one chain id allow prepare transactions. if chainID.Uint64() == uint64(chainNum) && len(transactions) != 5 { - t.Errorf("incorrect transaction num expect %v but %v", 5, len(transactions)) + t.Fatalf("incorrect transaction num expect %v but %v", 5, len(transactions)) } else if chainID.Uint64() != uint64(chainNum) && len(transactions) != 0 { - t.Errorf("expect empty slice but %v", len(transactions)) + t.Fatalf("expect empty slice but %v", len(transactions)) } for i, tx := range transactions { if expectTx[i].Gas() != tx.Gas() { - t.Errorf("unexpected gas expect %v but %v", expectTx[i].Gas(), tx.Gas()) + t.Fatalf("unexpected gas expect %v but %v", expectTx[i].Gas(), tx.Gas()) } if expectTx[i].Hash() != tx.Hash() { - t.Errorf("unexpected hash expect %v but %v", expectTx[i].Hash(), tx.Hash()) + t.Fatalf("unexpected hash expect %v but %v", expectTx[i].Hash(), tx.Hash()) } if expectTx[i].Nonce() != tx.Nonce() { - t.Errorf("unexpected nonce expect %v but %v", expectTx[i].Nonce(), tx.Nonce()) + t.Fatalf("unexpected nonce expect %v but %v", expectTx[i].Nonce(), tx.Nonce()) } if expectTx[i].GasPrice().Uint64() != tx.GasPrice().Uint64() { - t.Errorf("unexpected gas price expect %v but %v", + t.Fatalf("unexpected gas price expect %v but %v", expectTx[i].GasPrice().Uint64(), tx.GasPrice().Uint64()) } } @@ -98,41 +100,41 @@ func TestPreparePayload(t *testing.T) { func TestPrepareWitness(t *testing.T) { key, err := crypto.GenerateKey() if err != nil { - t.Errorf("hex to ecdsa error: %v", err) + t.Fatalf("hex to ecdsa error: %v", err) } dex, err := newTestDexonWithGenesis(key) if err != nil { - t.Errorf("new test dexon error: %v", err) + t.Fatalf("new test dexon error: %v", err) } currentBlock := dex.blockchain.CurrentBlock() witness, err := dex.app.PrepareWitness(0) if err != nil { - t.Errorf("prepare witness error: %v", err) + t.Fatalf("prepare witness error: %v", err) } if witness.Height != currentBlock.NumberU64() { - t.Errorf("unexpeted witness height %v", witness.Height) + t.Fatalf("unexpeted witness height %v", witness.Height) } var witnessData types.WitnessData err = rlp.DecodeBytes(witness.Data, &witnessData) if err != nil { - t.Errorf("rlp decode error: %v", err) + t.Fatalf("rlp decode error: %v", err) } if witnessData.Root != currentBlock.Root() { - t.Errorf("expect root %v but %v", currentBlock.Root(), witnessData.Root) + t.Fatalf("expect root %v but %v", currentBlock.Root(), witnessData.Root) } if witnessData.ReceiptHash != currentBlock.ReceiptHash() { - t.Errorf("expect receipt hash %v but %v", currentBlock.ReceiptHash(), witnessData.ReceiptHash) + t.Fatalf("expect receipt hash %v but %v", currentBlock.ReceiptHash(), witnessData.ReceiptHash) } if _, err := dex.app.PrepareWitness(999); err == nil { - t.Errorf("it must be get error from prepare") + t.Fatalf("it must be get error from prepare") } else { t.Logf("Nice error: %v", err) } @@ -141,20 +143,26 @@ func TestPrepareWitness(t *testing.T) { func TestVerifyBlock(t *testing.T) { key, err := crypto.GenerateKey() if err != nil { - t.Errorf("hex to ecdsa error: %v", err) + t.Fatalf("hex to ecdsa error: %v", err) } dex, err := newTestDexonWithGenesis(key) if err != nil { - t.Errorf("new test dexon error: %v", err) + t.Fatalf("new test dexon error: %v", err) } - // Prepare first confirmed block. - prepareConfirmedBlocks(dex, []*ecdsa.PrivateKey{key}, 0) - chainID := new(big.Int).Mod(crypto.PubkeyToAddress(key.PublicKey).Big(), big.NewInt(int64(dex.chainConfig.Dexcon.NumChains))) + root := dex.blockchain.CurrentBlock().Root() + dex.app.chainRoot.Store(uint32(chainID.Uint64()), &root) + + // Prepare first confirmed block. + _, err = prepareConfirmedBlocks(dex, []*ecdsa.PrivateKey{key}, 0) + if err != nil { + t.Fatalf("prepare confirmed blocks error: %v", err) + } + // Prepare normal block. block := &coreTypes.Block{} block.Hash = coreCommon.NewRandomHash() @@ -163,13 +171,13 @@ func TestVerifyBlock(t *testing.T) { block.ProposerID = coreTypes.NodeID{coreCommon.Hash{1, 2, 3}} block.Payload, block.Witness, err = prepareDataWithoutTxPool(dex, key, 0, 100) if err != nil { - t.Errorf("prepare data error: %v", err) + t.Fatalf("prepare data error: %v", err) } // Expect ok. status := dex.app.VerifyBlock(block) if status != coreTypes.VerifyOK { - t.Errorf("verify fail: %v", status) + t.Fatalf("verify fail: %v", status) } // Prepare invalid nonce tx. @@ -180,13 +188,13 @@ func TestVerifyBlock(t *testing.T) { block.ProposerID = coreTypes.NodeID{coreCommon.Hash{1, 2, 3}} block.Payload, block.Witness, err = prepareDataWithoutTxPool(dex, key, 1, 100) if err != nil { - t.Errorf("prepare data error: %v", err) + t.Fatalf("prepare data error: %v", err) } // Expect invalid block. status = dex.app.VerifyBlock(block) if status != coreTypes.VerifyInvalidBlock { - t.Errorf("verify fail: %v", status) + t.Fatalf("verify fail: %v", status) } // Prepare invalid block height. @@ -197,13 +205,13 @@ func TestVerifyBlock(t *testing.T) { block.ProposerID = coreTypes.NodeID{coreCommon.Hash{1, 2, 3}} block.Payload, block.Witness, err = prepareDataWithoutTxPool(dex, key, 0, 100) if err != nil { - t.Errorf("prepare data error: %v", err) + t.Fatalf("prepare data error: %v", err) } // Expect retry later. status = dex.app.VerifyBlock(block) if status != coreTypes.VerifyRetryLater { - t.Errorf("verify fail expect retry later but get %v", status) + t.Fatalf("verify fail expect retry later but get %v", status) } // Prepare reach block limit. @@ -214,13 +222,13 @@ func TestVerifyBlock(t *testing.T) { block.ProposerID = coreTypes.NodeID{coreCommon.Hash{1, 2, 3}} block.Payload, block.Witness, err = prepareDataWithoutTxPool(dex, key, 0, 10000) if err != nil { - t.Errorf("prepare data error: %v", err) + t.Fatalf("prepare data error: %v", err) } // Expect invalid block. status = dex.app.VerifyBlock(block) if status != coreTypes.VerifyInvalidBlock { - t.Errorf("verify fail expect invalid block but get %v", status) + t.Fatalf("verify fail expect invalid block but get %v", status) } // Prepare insufficient funds. @@ -231,7 +239,7 @@ func TestVerifyBlock(t *testing.T) { block.ProposerID = coreTypes.NodeID{coreCommon.Hash{1, 2, 3}} _, block.Witness, err = prepareDataWithoutTxPool(dex, key, 0, 0) if err != nil { - t.Errorf("prepare data error: %v", err) + t.Fatalf("prepare data error: %v", err) } signer := types.NewEIP155Signer(dex.chainConfig.ChainID) @@ -255,7 +263,7 @@ func TestVerifyBlock(t *testing.T) { // expect invalid block status = dex.app.VerifyBlock(block) if status != coreTypes.VerifyInvalidBlock { - t.Errorf("verify fail expect invalid block but get %v", status) + t.Fatalf("verify fail expect invalid block but get %v", status) } // Prepare invalid intrinsic gas. @@ -266,7 +274,7 @@ func TestVerifyBlock(t *testing.T) { block.ProposerID = coreTypes.NodeID{coreCommon.Hash{1, 2, 3}} _, block.Witness, err = prepareDataWithoutTxPool(dex, key, 0, 0) if err != nil { - t.Errorf("prepare data error: %v", err) + t.Fatalf("prepare data error: %v", err) } signer = types.NewEIP155Signer(dex.chainConfig.ChainID) @@ -290,7 +298,7 @@ func TestVerifyBlock(t *testing.T) { // Expect invalid block. status = dex.app.VerifyBlock(block) if status != coreTypes.VerifyInvalidBlock { - t.Errorf("verify fail expect invalid block but get %v", status) + t.Fatalf("verify fail expect invalid block but get %v", status) } // Prepare invalid transactions with nonce. @@ -301,7 +309,7 @@ func TestVerifyBlock(t *testing.T) { block.ProposerID = coreTypes.NodeID{coreCommon.Hash{1, 2, 3}} _, block.Witness, err = prepareDataWithoutTxPool(dex, key, 0, 0) if err != nil { - t.Errorf("prepare data error: %v", err) + t.Fatalf("prepare data error: %v", err) } signer = types.NewEIP155Signer(dex.chainConfig.ChainID) @@ -338,24 +346,27 @@ func TestVerifyBlock(t *testing.T) { // Expect invalid block. status = dex.app.VerifyBlock(block) if status != coreTypes.VerifyInvalidBlock { - t.Errorf("verify fail expect invalid block but get %v", status) + t.Fatalf("verify fail expect invalid block but get %v", status) } } func TestBlockConfirmed(t *testing.T) { key, err := crypto.GenerateKey() if err != nil { - t.Errorf("hex to ecdsa error: %v", err) + t.Fatalf("hex to ecdsa error: %v", err) } dex, err := newTestDexonWithGenesis(key) if err != nil { - t.Errorf("new test dexon error: %v", err) + t.Fatalf("new test dexon error: %v", err) } chainID := new(big.Int).Mod(crypto.PubkeyToAddress(key.PublicKey).Big(), big.NewInt(int64(dex.chainConfig.Dexcon.NumChains))) + root := dex.blockchain.CurrentBlock().Root() + dex.app.chainRoot.Store(uint32(chainID.Uint64()), &root) + var ( expectCost big.Int expectNonce uint64 @@ -368,7 +379,7 @@ func TestBlockConfirmed(t *testing.T) { } payload, witness, cost, nonce, err := prepareData(dex, key, startNonce, 50) if err != nil { - t.Errorf("prepare data error: %v", err) + t.Fatalf("prepare data error: %v", err) } expectCost.Add(&expectCost, &cost) expectNonce = nonce @@ -388,33 +399,39 @@ func TestBlockConfirmed(t *testing.T) { crypto.PubkeyToAddress(key.PublicKey)) if info.Counter != expectCounter { - t.Errorf("expect address counter is %v but %v", expectCounter, info.Counter) + t.Fatalf("expect address counter is %v but %v", expectCounter, info.Counter) } if info.Cost.Cmp(&expectCost) != 0 { - t.Errorf("expect address cost is %v but %v", expectCost.Uint64(), info.Cost.Uint64()) + t.Fatalf("expect address cost is %v but %v", expectCost.Uint64(), info.Cost.Uint64()) } if info.Nonce != expectNonce { - t.Errorf("expect address nonce is %v but %v", expectNonce, info.Nonce) + t.Fatalf("expect address nonce is %v but %v", expectNonce, info.Nonce) } } func TestBlockDelivered(t *testing.T) { key, err := crypto.GenerateKey() if err != nil { - t.Errorf("hex to ecdsa error: %v", err) + t.Fatalf("hex to ecdsa error: %v", err) } dex, err := newTestDexonWithGenesis(key) if err != nil { - t.Errorf("new test dexon error: %v", err) + t.Fatalf("new test dexon error: %v", err) } + chainID := new(big.Int).Mod(crypto.PubkeyToAddress(key.PublicKey).Big(), + big.NewInt(int64(dex.chainConfig.Dexcon.NumChains))) + + root := dex.blockchain.CurrentBlock().Root() + dex.app.chainRoot.Store(uint32(chainID.Uint64()), &root) + address := crypto.PubkeyToAddress(key.PublicKey) firstBlocksInfo, err := prepareConfirmedBlocks(dex, []*ecdsa.PrivateKey{key}, 50) if err != nil { - t.Errorf("preapare confirmed block error: %v", err) + t.Fatalf("preapare confirmed block error: %v", err) } dex.app.BlockDelivered(firstBlocksInfo[0].Block.Hash, firstBlocksInfo[0].Block.Position, @@ -423,72 +440,48 @@ func TestBlockDelivered(t *testing.T) { Height: 1, }) - _, pendingState := dex.blockchain.GetPending() - currentBlock := dex.blockchain.CurrentBlock() - if currentBlock.NumberU64() != 0 { - t.Errorf("unexpected current block number %v", currentBlock.NumberU64()) - } - - pendingNonce := pendingState.GetNonce(address) - if pendingNonce != firstBlocksInfo[0].Nonce+1 { - t.Errorf("unexpected pending state nonce %v", pendingNonce) - } - - balance := pendingState.GetBalance(address) - if new(big.Int).Add(balance, &firstBlocksInfo[0].Cost).Cmp(big.NewInt(50000000000000000)) != 0 { - t.Errorf("unexpected pending state balance %v", balance) - } - - // prepare second block to witness first block - secondBlocksInfo, err := prepareConfirmedBlocks(dex, []*ecdsa.PrivateKey{key}, 25) + currentState, err := dex.blockchain.State() if err != nil { - t.Errorf("preapare confirmed block error: %v", err) + t.Fatalf("get state error: %v", err) } - - dex.app.BlockDelivered(secondBlocksInfo[0].Block.Hash, secondBlocksInfo[0].Block.Position, - coreTypes.FinalizationResult{ - Timestamp: time.Now(), - Height: 2, - }) - - // second block witness first block, so current block number should be 1 - currentBlock = dex.blockchain.CurrentBlock() + currentBlock := dex.blockchain.CurrentBlock() if currentBlock.NumberU64() != 1 { - t.Errorf("unexpected current block number %v", currentBlock.NumberU64()) - } - - currentState, err := dex.blockchain.State() - if err != nil { - t.Errorf("current state error: %v", err) + t.Fatalf("unexpected current block number %v", currentBlock.NumberU64()) } currentNonce := currentState.GetNonce(address) if currentNonce != firstBlocksInfo[0].Nonce+1 { - t.Errorf("unexpected current state nonce %v", currentNonce) + t.Fatalf("unexpected pending state nonce %v", currentNonce) } - balance = currentState.GetBalance(address) + balance := currentState.GetBalance(address) if new(big.Int).Add(balance, &firstBlocksInfo[0].Cost).Cmp(big.NewInt(50000000000000000)) != 0 { - t.Errorf("unexpected current state balance %v", balance) + t.Fatalf("unexpected pending state balance %v", balance) } } func TestNumChainsChange(t *testing.T) { key, err := crypto.GenerateKey() if err != nil { - t.Errorf("hex to ecdsa error: %v", err) + t.Fatalf("hex to ecdsa error: %v", err) } params.TestnetChainConfig.Dexcon.Owner = crypto.PubkeyToAddress(key.PublicKey) dex, err := newTestDexonWithGenesis(key) if err != nil { - t.Errorf("new test dexon error: %v", err) + t.Fatalf("new test dexon error: %v", err) } + chainID := new(big.Int).Mod(crypto.PubkeyToAddress(key.PublicKey).Big(), + big.NewInt(int64(dex.chainConfig.Dexcon.NumChains))) + + root := dex.blockchain.CurrentBlock().Root() + dex.app.chainRoot.Store(uint32(chainID.Uint64()), &root) + abiObject, err := abi.JSON(strings.NewReader(vm.GovernanceABIJSON)) if err != nil { - t.Errorf("get abi object fail: %v", err) + t.Fatalf("get abi object fail: %v", err) } // Update config in round 1 and height 1. @@ -511,12 +504,12 @@ func TestNumChainsChange(t *testing.T) { big.NewInt(1000), []*big.Int{big.NewInt(1), big.NewInt(1), big.NewInt(1)}) if err != nil { - t.Errorf("updateConfiguration abiObject pack error: %v", err) + t.Fatalf("updateConfiguration abiObject pack error: %v", err) } block, err := prepareConfirmedBlockWithTxAndData(dex, key, [][]byte{input}, 1) if err != nil { - t.Errorf("prepare block error: %v", err) + t.Fatalf("prepare block error: %v", err) } dex.app.BlockDelivered(block.Hash, block.Position, coreTypes.FinalizationResult{ @@ -527,12 +520,12 @@ func TestNumChainsChange(t *testing.T) { // Snapshot round on round 1 and height 2. input, err = abiObject.Pack("snapshotRound", big.NewInt(1), big.NewInt(1)) if err != nil { - t.Errorf("abiObject pack error: %v", err) + t.Fatalf("abiObject pack error: %v", err) } block, err = prepareConfirmedBlockWithTxAndData(dex, key, [][]byte{input}, 1) if err != nil { - t.Errorf("prepare block error: %v", err) + t.Fatalf("prepare block error: %v", err) } dex.app.BlockDelivered(block.Hash, block.Position, coreTypes.FinalizationResult{ @@ -543,7 +536,7 @@ func TestNumChainsChange(t *testing.T) { // Make round 1 height 2 block write into chain. block, err = prepareConfirmedBlockWithTxAndData(dex, key, nil, 1) if err != nil { - t.Errorf("prepare block error: %v", err) + t.Fatalf("prepare block error: %v", err) } dex.app.BlockDelivered(block.Hash, block.Position, coreTypes.FinalizationResult{ @@ -554,10 +547,10 @@ func TestNumChainsChange(t *testing.T) { // Round 2 will keep prepare tx as usual. block, err = prepareConfirmedBlockWithTxAndData(dex, key, [][]byte{{1}}, 2) if err != nil { - t.Errorf("prepare block error: %v", err) + t.Fatalf("prepare block error: %v", err) } if block.Payload == nil { - t.Errorf("payload should not be nil") + t.Fatalf("payload should not be nil") } dex.app.BlockDelivered(block.Hash, block.Position, coreTypes.FinalizationResult{ @@ -568,16 +561,16 @@ func TestNumChainsChange(t *testing.T) { // It will prepare empty payload until witness any block in round 3. block, err = prepareConfirmedBlockWithTxAndData(dex, key, [][]byte{{1}}, 3) if err != nil { - t.Errorf("prepare block error: %v", err) + t.Fatalf("prepare block error: %v", err) } if block.Payload != nil { - t.Errorf("payload should be nil but %v", block.Payload) + t.Fatalf("payload should be nil but %v", block.Payload) } // Test non-empty payload. block.Payload = []byte{1} if status := dex.app.VerifyBlock(block); status != coreTypes.VerifyInvalidBlock { - t.Errorf("unexpected verify status %v", status) + t.Fatalf("unexpected verify status %v", status) } block.Payload = nil @@ -587,62 +580,39 @@ func TestNumChainsChange(t *testing.T) { Height: 5, }) - // Still empty payload because round 3 is not witness yet. - // This block just for witness round 3 height 5. - block, err = prepareConfirmedBlockWithTxAndData(dex, key, [][]byte{{1}}, 3) - if err != nil { - t.Errorf("prepare block error: %v", err) - } - if block.Payload != nil { - t.Errorf("payload should be nil but %v", block.Payload) - } - - // Test non-empty payload. - block.Payload = []byte{1} - if status := dex.app.VerifyBlock(block); status != coreTypes.VerifyInvalidBlock { - t.Errorf("unexpected verify status %v", status) - } - block.Payload = nil - - dex.app.BlockDelivered(block.Hash, block.Position, - coreTypes.FinalizationResult{ - Timestamp: time.Now(), - Height: 6, - }) - // Empty block in round 3 has been delivered. // Now can prepare payload as usual. block, err = prepareConfirmedBlockWithTxAndData(dex, key, [][]byte{{1}}, 3) if err != nil { - t.Errorf("prepare block error: %v", err) + t.Fatalf("prepare block error: %v", err) } if block.Payload == nil { - t.Errorf("payload should not be nil") + t.Fatalf("payload should not be nil") } dex.app.BlockDelivered(block.Hash, block.Position, coreTypes.FinalizationResult{ Timestamp: time.Now(), - Height: 7, + Height: 6, }) } func BenchmarkBlockDeliveredFlow(b *testing.B) { key, err := crypto.GenerateKey() if err != nil { - b.Errorf("hex to ecdsa error: %v", err) + b.Fatalf("hex to ecdsa error: %v", err) return } dex, err := newTestDexonWithGenesis(key) if err != nil { - b.Errorf("new test dexon error: %v", err) + b.Fatalf("new test dexon error: %v", err) } b.ResetTimer() for i := 1; i <= b.N; i++ { blocksInfo, err := prepareConfirmedBlocks(dex, []*ecdsa.PrivateKey{key}, 100) if err != nil { - b.Errorf("preapare confirmed block error: %v", err) + b.Fatalf("preapare confirmed block error: %v", err) return } diff --git a/dex/backend.go b/dex/backend.go index c75fdfa29..a000d5fbc 100644 --- a/dex/backend.go +++ b/dex/backend.go @@ -146,7 +146,7 @@ func New(ctx *node.ServiceContext, config *Config) (*Dexon, error) { if config.TxPool.Journal != "" { config.TxPool.Journal = ctx.ResolvePath(config.TxPool.Journal) } - dex.txPool = core.NewTxPool(config.TxPool, dex.chainConfig, dex.blockchain, config.BlockProposerEnabled) + dex.txPool = core.NewTxPool(config.TxPool, dex.chainConfig, dex.blockchain) dex.APIBackend = &DexAPIBackend{dex, nil} gpoParams := config.GPO |