Link new block after consensus into blockchain

pull/7/head
Rongjian Lan 6 years ago
parent b1d2eaa52b
commit c57fff98b8
  1. 7
      blockchain/block.go
  2. 2
      blockchain/block_test.go
  3. 11
      blockchain/blockchain.go
  4. 2
      blockchain/blockchain_test.go
  5. 2
      blockchain/utxopool.go
  6. 18
      node/node_handler.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
}

@ -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.")
}
}

@ -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 {

@ -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.")

@ -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)

@ -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
}
}

Loading…
Cancel
Save