diff --git a/benchmark.go b/benchmark.go index 35322cc1d..4f0e83014 100644 --- a/benchmark.go +++ b/benchmark.go @@ -74,6 +74,7 @@ func loggingInit(logFolder, role, ip, port string, onlyLogTps bool) { } func main() { + accountModel := flag.Bool("account_model", false, "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.") @@ -194,20 +195,34 @@ func main() { // Assign closure functions to the consensus object consensus.BlockVerifier = currentNode.VerifyNewBlock + if *accountModel { + consensus.BlockVerifier = currentNode.VerifyNewBlockAccount + } consensus.OnConsensusDone = currentNode.PostConsensusProcessing // Temporary testing code, to be removed. currentNode.AddTestingAddresses(10000) if consensus.IsLeader { - // Let consensus run - go func() { - consensus.WaitForNewBlock(currentNode.BlockChannel) - }() - // Node waiting for consensus readiness to create new block - go func() { - currentNode.WaitForConsensusReady(consensus.ReadySignal) - }() + if *accountModel { + // Let consensus run + go func() { + consensus.WaitForNewBlockAccount(currentNode.BlockChannelAccount) + }() + // Node waiting for consensus readiness to create new block + go func() { + currentNode.WaitForConsensusReadyAccount(consensus.ReadySignal) + }() + } else { + // Let consensus run + go func() { + consensus.WaitForNewBlock(currentNode.BlockChannel) + }() + // Node waiting for consensus readiness to create new block + go func() { + currentNode.WaitForConsensusReady(consensus.ReadySignal) + }() + } } currentNode.StartServer(*port) diff --git a/blockchain/block.go b/blockchain/block.go index 5e15af014..c55e06bc7 100644 --- a/blockchain/block.go +++ b/blockchain/block.go @@ -5,6 +5,7 @@ import ( "crypto/sha256" "encoding/gob" "fmt" + "github.com/harmony-one/harmony/core/types" "log" "time" @@ -27,6 +28,8 @@ type Block struct { // Signature... Bitmap []byte // Contains which validator signed the block. Signature [66]byte // Schnorr collective signature. + + AccountBlock *types.Block // Temporary piggy-back. } // State is used in Block to indicate that block is a state block. diff --git a/client/txgen/main.go b/client/txgen/main.go index 8aecfb7e5..532254b47 100644 --- a/client/txgen/main.go +++ b/client/txgen/main.go @@ -252,7 +252,7 @@ func main() { maxNumTxsPerBatch := flag.Int("max_num_txs_per_batch", 20000, "number of transactions to send per message") logFolder := flag.String("log_folder", "latest", "the folder collecting the logs of this execution") numSubset := flag.Int("numSubset", 3, "the number of subsets of utxos to process separately") - duration := flag.Int("duration", 120, "duration of the tx generation in second. If it's negative, the experiment runs forever.") + duration := flag.Int("duration", 60, "duration of the tx generation in second. If it's negative, the experiment runs forever.") versionFlag := flag.Bool("version", false, "Output version info") crossShardRatio := flag.Int("cross_shard_ratio", 30, "The percentage of cross shard transactions.") flag.Parse() @@ -392,6 +392,7 @@ func main() { msg := proto_node.ConstructStopMessage() peers := append(config.GetValidators(), clientNode.Client.GetLeaders()...) p2p.BroadcastMessage(peers, msg) + time.Sleep(3000 * time.Millisecond) } func SendTxsToLeader(leader p2p.Peer, txs []*blockchain.Transaction) { diff --git a/consensus/bft.go b/consensus/bft.go index dad81f8c4..d8fc9247a 100644 --- a/consensus/bft.go +++ b/consensus/bft.go @@ -80,7 +80,7 @@ func (bft *Bft) Finalize(chain ChainReader, header *types.Header, state *state.S // Accumulate any block and uncle rewards and commit the final state root // Header seems complete, assemble into a block and return accumulateRewards(chain.Config(), state, header) - header.Root = state.IntermediateRoot(chain.Config().IsEIP158(header.Number)) + header.Root = state.IntermediateRoot(false) return types.NewBlock(header, txs, receipts), nil } diff --git a/consensus/consensus_leader.go b/consensus/consensus_leader.go index 7df244509..f1ecd7647 100644 --- a/consensus/consensus_leader.go +++ b/consensus/consensus_leader.go @@ -6,6 +6,7 @@ import ( "encoding/gob" "encoding/hex" "errors" + "github.com/harmony-one/harmony/core/types" "time" "github.com/harmony-one/harmony/profiler" @@ -46,6 +47,22 @@ func (consensus *Consensus) WaitForNewBlock(blockChannel chan blockchain.Block) } } +// WaitForNewBlock waits for the next new block to run consensus on +func (consensus *Consensus) WaitForNewBlockAccount(blockChannel chan *types.Block) { + consensus.Log.Debug("Waiting for block", "consensus", consensus) + for { // keep waiting for new blocks + newBlock := <-blockChannel + // TODO: think about potential race condition + startTime = time.Now() + consensus.Log.Debug("STARTING CONSENSUS", "consensus", consensus, "startTime", startTime) + for consensus.state == Finished { + // time.Sleep(500 * time.Millisecond) + consensus.startConsensus(&blockchain.Block{Hash: newBlock.Hash(), AccountBlock: newBlock}) + break + } + } +} + // ProcessMessageLeader dispatches consensus message for the leader. func (consensus *Consensus) ProcessMessageLeader(message []byte) { msgType, err := proto_consensus.GetConsensusMessageType(message) diff --git a/consensus/consensus_validator.go b/consensus/consensus_validator.go index 1a5caf6c1..b34ee8384 100644 --- a/consensus/consensus_validator.go +++ b/consensus/consensus_validator.go @@ -109,11 +109,12 @@ func (consensus *Consensus) processAnnounceMessage(payload []byte) { return } + // Temporary disabling this for account model testing // check block hash - if !bytes.Equal(blockHash[:], blockHeaderObj.CalculateBlockHash()[:]) || !bytes.Equal(blockHeaderObj.Hash[:], blockHeaderObj.CalculateBlockHash()[:]) { - consensus.Log.Warn("Block hash doesn't match", "consensus", consensus) - return - } + //if !bytes.Equal(blockHash[:], blockHeaderObj.CalculateBlockHash()[:]) || !bytes.Equal(blockHeaderObj.Hash[:], blockHeaderObj.CalculateBlockHash()[:]) { + // consensus.Log.Warn("Block hash doesn't match", "consensus", consensus) + // return + //} // check block data (transactions if !consensus.BlockVerifier(&blockHeaderObj) { diff --git a/node/node_handler.go b/node/node_handler.go index c6b20c79e..afa0b1639 100644 --- a/node/node_handler.go +++ b/node/node_handler.go @@ -389,6 +389,10 @@ func (node *Node) WaitForConsensusReadyAccount(readySignal chan struct{}) { } node.worker.CommitTransactions(txs, crypto.PubkeyToAddress(node.testBankKey.PublicKey)) newBlock = node.worker.Commit() + + // If not enough transactions to run Consensus, + // periodically check whether we have enough transactions to package into block. + time.Sleep(1 * time.Second) } // Send the new block to Consensus so it can be confirmed. @@ -431,6 +435,11 @@ func (node *Node) VerifyNewBlock(newBlock *blockchain.Block) bool { return node.UtxoPool.VerifyTransactions(newBlock.Transactions) } +// VerifyNewBlock is called by consensus participants to verify the block (account model) they are running consensus on +func (node *Node) VerifyNewBlockAccount(newBlock *blockchain.Block) bool { + return true // TODO: implement the logic +} + // PostConsensusProcessing is called by consensus participants, after consensus is done, to: // 1. add the new block to blockchain // 2. [leader] move cross shard tx and proof to the list where they wait to be sent to the client diff --git a/transactions.rlp b/transactions.rlp index a929e39e8..e69de29bb 100755 Binary files a/transactions.rlp and b/transactions.rlp differ