diff --git a/blockchain/block.go b/blockchain/block.go index 2eb64fc31..c10ed69b5 100644 --- a/blockchain/block.go +++ b/blockchain/block.go @@ -14,7 +14,7 @@ type Block struct { Timestamp int64 Transactions []*Transaction PrevBlockHash []byte - Hash []byte + Hash [32]byte } // Serialize serializes the block @@ -64,8 +64,9 @@ func (b *Block) HashTransactions() []byte { // NewBlock creates and returns a neew block. func NewBlock(transactions []*Transaction, prevBlockHash []byte) *Block { - block := &Block{time.Now().Unix(), transactions, prevBlockHash, []byte{}} - block.Hash = block.HashTransactions() + block := &Block{time.Now().Unix(), transactions, prevBlockHash, [32]byte{}} + copy(block.Hash[:], block.HashTransactions()[:]) // TODO(Minh): the blockhash should be a hash of everything in the block + return block } diff --git a/blockchain/block_test.go b/blockchain/block_test.go index 623890e8f..72e32fffe 100644 --- a/blockchain/block_test.go +++ b/blockchain/block_test.go @@ -23,7 +23,7 @@ func TestBlockSerialize(t *testing.T) { t.Errorf("Serialize or Deserialize incorrect at PrevBlockHash.") } - if bytes.Compare(block.Hash, deserializedBlock.Hash) != 0 { + if bytes.Compare(block.Hash[:], deserializedBlock.Hash[:]) != 0 { t.Errorf("Serialize or Deserialize incorrect at Hash.") } } diff --git a/blockchain/blockchain.go b/blockchain/blockchain.go index 3fb89e0b3..2dc0cbc94 100644 --- a/blockchain/blockchain.go +++ b/blockchain/blockchain.go @@ -12,6 +12,13 @@ type Blockchain struct { const genesisCoinbaseData = "The Times 03/Jan/2009 Chancellor on brink of second bailout for banks" +func (bc *Blockchain) GetLatestBlock() *Block{ + if len(bc.Blocks) == 0 { + return nil + } + return bc.Blocks[len(bc.Blocks) - 1] +} + // FindUnspentTransactions returns a list of transactions containing unspent outputs func (bc *Blockchain) FindUnspentTransactions(address string) []Transaction { var unspentTXs []Transaction @@ -135,7 +142,7 @@ func (bc *Blockchain) NewUTXOTransaction(from, to string, amount int) *Transacti func (bc *Blockchain) AddNewUserTransfer(utxoPool *UTXOPool, from, to string, amount int) bool { tx := bc.NewUTXOTransaction(from, to, amount) if tx != nil { - newBlock := NewBlock([]*Transaction{tx}, bc.Blocks[len(bc.Blocks)-1].Hash) + newBlock := NewBlock([]*Transaction{tx}, bc.Blocks[len(bc.Blocks)-1].Hash[:]) if bc.VerifyNewBlockAndUpdate(utxoPool, newBlock) { return true } @@ -146,7 +153,7 @@ func (bc *Blockchain) AddNewUserTransfer(utxoPool *UTXOPool, from, to string, am // VerifyNewBlockAndUpdate verifies if the new coming block is valid for the current blockchain. func (bc *Blockchain) VerifyNewBlockAndUpdate(utxopool *UTXOPool, block *Block) bool { length := len(bc.Blocks) - if bytes.Compare(block.PrevBlockHash, bc.Blocks[length-1].Hash) != 0 { + if bytes.Compare(block.PrevBlockHash, bc.Blocks[length-1].Hash[:]) != 0 { return false } if block.Timestamp < bc.Blocks[length-1].Timestamp { diff --git a/blockchain/blockchain_test.go b/blockchain/blockchain_test.go index ed7c73652..d6d21b64b 100644 --- a/blockchain/blockchain_test.go +++ b/blockchain/blockchain_test.go @@ -68,7 +68,7 @@ func TestVerifyNewBlock(t *testing.T) { if tx == nil { t.Error("failed to create a new transaction.") } - newBlock := NewBlock([]*Transaction{tx}, bc.Blocks[len(bc.Blocks)-1].Hash) + newBlock := NewBlock([]*Transaction{tx}, bc.Blocks[len(bc.Blocks)-1].Hash[:]) if !bc.VerifyNewBlockAndUpdate(utxoPool, newBlock) { t.Error("failed to add a new valid block.") diff --git a/blockchain/utxopool.go b/blockchain/utxopool.go index ce3456628..6ab830546 100644 --- a/blockchain/utxopool.go +++ b/blockchain/utxopool.go @@ -212,7 +212,7 @@ func CreateUTXOPoolFromGenesisBlockChain(bc *Blockchain) *UTXOPool { func (utxoPool *UTXOPool) SelectTransactionsForNewBlock(transactions []*Transaction) ([]*Transaction, []*Transaction) { selected, unselected := []*Transaction{}, []*Transaction{} for _, tx := range transactions { - if len(selected) < MaxNumberOfTransactions && utxoPool.VerifyOneTransactionAndUpdate(tx) { + if len(selected) < MaxNumberOfTransactions && utxoPool.VerifyOneTransaction(tx) { selected = append(selected, tx) } else { unselected = append(unselected, tx) diff --git a/node/node_handler.go b/node/node_handler.go index 31e68a291..51f383844 100644 --- a/node/node_handler.go +++ b/node/node_handler.go @@ -118,19 +118,29 @@ func getFixedByteTxId(txId []byte) [32]byte { func (node *Node) WaitForConsensusReady(readySignal chan int) { node.log.Debug("Waiting for consensus ready", "node", node) + var newBlock *blockchain.Block for { // keep waiting for consensus ready <-readySignal - // create a new block - newBlock := new(blockchain.Block) + //node.log.Debug("Adding new block", "currentChainSize", len(node.blockchain.Blocks), "numTxs", len(node.blockchain.GetLatestBlock().Transactions), "PrevHash", node.blockchain.GetLatestBlock().PrevBlockHash, "Hash", node.blockchain.GetLatestBlock().Hash) + if newBlock != nil { + // Consensus is done on the previous newBlock, add it to blockchain + node.blockchain.Blocks = append(node.blockchain.Blocks, newBlock) + // Update UTXO pool + node.UtxoPool.Update(node.transactionInConsensus) + // Clear transaction in consensus slice + node.transactionInConsensus = []*blockchain.Transaction{} + } for { if len(node.pendingTransactions) >= 10 { selectedTxs := node.getTransactionsForNewBlock() + if len(selectedTxs) == 0 { node.log.Debug("No transactions is selected for consensus", "pendingTx", len(node.pendingTransactions)) } else { - node.log.Debug("Creating new block", "numTxs", len(selectedTxs), "pendingTxs", len(node.pendingTransactions)) + node.log.Debug("Creating new block", "numTxs", len(selectedTxs), "pendingTxs", len(node.pendingTransactions), "currentChainSize", len(node.blockchain.Blocks)) - newBlock = blockchain.NewBlock(selectedTxs, []byte{}) + node.transactionInConsensus = selectedTxs + newBlock = blockchain.NewBlock(selectedTxs, node.blockchain.GetLatestBlock().Hash[:]) break } }