From 2784e137667233bc0b2060e07a570bc796405730 Mon Sep 17 00:00:00 2001 From: Rongjian Lan Date: Sat, 24 Nov 2018 22:56:37 -0800 Subject: [PATCH] add valid transactions and make consensus fully verify each block --- benchmark.go | 2 +- core/blockchain.go | 4 ---- core/genesis.go | 1 - node/node.go | 4 ---- node/node_handler.go | 32 +++++++++++++++++++++++--------- node/worker/worker.go | 28 +++++++++++++++++++++++++--- 6 files changed, 49 insertions(+), 22 deletions(-) diff --git a/benchmark.go b/benchmark.go index 25db29d70..ddac32fb5 100644 --- a/benchmark.go +++ b/benchmark.go @@ -74,7 +74,7 @@ func loggingInit(logFolder, role, ip, port string, onlyLogTps bool) { } func main() { - accountModel := flag.Bool("account_model", false, "Whether to use account model") + accountModel := flag.Bool("account_model", true, "Whether to use account model") // TODO: use http://getmyipaddress.org/ or http://www.get-myip.com/ to retrieve my IP address ip := flag.String("ip", "127.0.0.1", "IP of the node") port := flag.String("port", "9000", "port of the node.") diff --git a/core/blockchain.go b/core/blockchain.go index f1cfe310f..2b6677a81 100644 --- a/core/blockchain.go +++ b/core/blockchain.go @@ -191,12 +191,10 @@ func NewBlockChain(db hdb.Database, cacheConfig *CacheConfig, chainConfig *param func (bc *BlockChain) ValidateNewBlock(block *types.Block, address common.Address) bool { state, err := state.New(bc.CurrentBlock().Root(), bc.stateCache) - fmt.Println("WITHIN NNNNNNNNNNNNNN", err) if err != nil { return false } - fmt.Println("Balance 3 ", state.GetBalance(address)) // Process block using the parent state as reference point. receipts, _, usedGas, err := bc.processor.Process(block, state, bc.vmConfig) if err != nil { @@ -204,13 +202,11 @@ func (bc *BlockChain) ValidateNewBlock(block *types.Block, address common.Addres return false } - fmt.Println("WITHIN NNNNNNNNNNNNNN2", err) err = bc.Validator().ValidateState(block, bc.CurrentBlock(), state, receipts, usedGas) if err != nil { bc.reportBlock(block, receipts, err) return false } - fmt.Println("WITHIN NNNNNNNNNNNNNN3", err) return true } diff --git a/core/genesis.go b/core/genesis.go index e03323a6f..9a604cf9c 100644 --- a/core/genesis.go +++ b/core/genesis.go @@ -115,7 +115,6 @@ func (h *storageJSON) UnmarshalText(text []byte) error { } offset := len(h) - len(text)/2 // pad on the left if _, err := hex.Decode(h[offset:], text); err != nil { - fmt.Println(err) return fmt.Errorf("invalid hex storage key/value %q", text) } return nil diff --git a/node/node.go b/node/node.go index dcfffd462..0813bdc3d 100644 --- a/node/node.go +++ b/node/node.go @@ -242,10 +242,6 @@ func New(consensus *bft.Consensus, db *hdb.LDBDatabase) *Node { node.TxPool = core.NewTxPool(core.DefaultTxPoolConfig, params.TestChainConfig, chain) node.BlockChannelAccount = make(chan *types.Block) node.worker = worker.New(params.TestChainConfig, chain, bft.NewFaker()) - - fmt.Println("BALANCE") - fmt.Println(node.worker.GetCurrentState().GetBalance(testBankAddress)) - } // Logger node.log = log.New() diff --git a/node/node_handler.go b/node/node_handler.go index e39d5a711..1d7c7164b 100644 --- a/node/node_handler.go +++ b/node/node_handler.go @@ -382,15 +382,20 @@ func (node *Node) WaitForConsensusReadyAccount(readySignal chan struct{}) { if !retry { // Normal tx block consensus // TODO: add new block generation logic - txs := make([]*types.Transaction, 100) + txs := make([]*types.Transaction, 10) + baseNonce := node.worker.GetCurrentState().GetNonce(crypto.PubkeyToAddress(node.testBankKey.PublicKey)) + node.worker.UpdateCurrent() for i, _ := range txs { randomUserKey, _ := crypto.GenerateKey() randomUserAddress := crypto.PubkeyToAddress(randomUserKey.PublicKey) - tx, _ := types.SignTx(types.NewTransaction(node.worker.GetCurrentState().GetNonce(crypto.PubkeyToAddress(node.testBankKey.PublicKey)), randomUserAddress, big.NewInt(1000), params.TxGas, nil, nil), types.HomesteadSigner{}, node.testBankKey) + tx, _ := types.SignTx(types.NewTransaction(baseNonce+uint64(i), randomUserAddress, big.NewInt(1000), params.TxGas, nil, nil), types.HomesteadSigner{}, node.testBankKey) txs[i] = tx } - node.worker.CommitTransactions(txs, crypto.PubkeyToAddress(node.testBankKey.PublicKey)) - newBlock = node.worker.Commit() + if node.worker.CommitTransactions(txs, crypto.PubkeyToAddress(node.testBankKey.PublicKey)) { + newBlock = node.worker.Commit() + } else { + node.log.Debug("Failed to create new block") + } // If not enough transactions to run Consensus, // periodically check whether we have enough transactions to package into block. @@ -447,10 +452,6 @@ func (node *Node) VerifyNewBlock(newBlock *blockchain.Block) bool { // VerifyNewBlock is called by consensus participants to verify the block (account model) they are running consensus on func (node *Node) VerifyNewBlockAccount(newBlock *types.Block) bool { - fmt.Println("VerifyingNNNNNNNNNNNNNN") - - fmt.Println("BALANCE 1") - fmt.Println(node.worker.GetCurrentState().GetBalance(crypto.PubkeyToAddress(node.testBankKey.PublicKey))) return node.Chain.ValidateNewBlock(newBlock, crypto.PubkeyToAddress(node.testBankKey.PublicKey)) } @@ -484,11 +485,24 @@ func (node *Node) PostConsensusProcessing(newBlock *blockchain.Block) { node.BroadcastNewBlock(newBlock) } + accountBlock := new(types.Block) + err := rlp.DecodeBytes(newBlock.AccountBlock, accountBlock) + if err != nil { + node.log.Error("Failed decoding the block with RLP") + } + node.AddNewBlockAccount(accountBlock) + // For utxo model only node.AddNewBlock(newBlock) node.UpdateUtxoAndState(newBlock) + +} + +// AddNewBlockAccount is usedd to add new block into the blockchain. +func (node *Node) AddNewBlockAccount(newBlock *types.Block) { + node.Chain.InsertChain([]*types.Block{newBlock}) } -// AddNewBlock is usedd to add new block into the blockchain. +// AddNewBlock is usedd to add new block into the utxo-based blockchain. func (node *Node) AddNewBlock(newBlock *blockchain.Block) { // Add it to blockchain node.blockchain.Blocks = append(node.blockchain.Blocks, newBlock) diff --git a/node/worker/worker.go b/node/worker/worker.go index 87b0a32c6..0f4a7519f 100644 --- a/node/worker/worker.go +++ b/node/worker/worker.go @@ -1,6 +1,7 @@ package worker import ( + "fmt" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/params" "github.com/harmony-one/harmony/consensus" @@ -49,14 +50,35 @@ func (w *Worker) commitTransaction(tx *types.Transaction, coinbase common.Addres return receipt.Logs, nil } -func (w *Worker) CommitTransactions(txs []*types.Transaction, coinbase common.Address) { +func (w *Worker) CommitTransactions(txs []*types.Transaction, coinbase common.Address) bool { + snap := w.current.state.Snapshot() + if w.current.gasPool == nil { w.current.gasPool = new(core.GasPool).AddGas(w.current.header.GasLimit) } - for _, tx := range txs { - w.commitTransaction(tx, coinbase) + _, err := w.commitTransaction(tx, coinbase) + if err != nil { + fmt.Println(err) + w.current.state.RevertToSnapshot(snap) + return false + + } + } + return true +} + +func (w *Worker) UpdateCurrent() error { + parent := w.chain.CurrentBlock() + num := parent.Number() + timestamp := time.Now().Unix() + header := &types.Header{ + ParentHash: parent.Hash(), + Number: num.Add(num, common.Big1), + GasLimit: core.CalcGasLimit(parent, w.gasFloor, w.gasCeil), + Time: big.NewInt(timestamp), } + return w.makeCurrent(parent, header) } // makeCurrent creates a new environment for the current cycle.