From c358fc754d0548b96892987a32739c4f76157662 Mon Sep 17 00:00:00 2001 From: Minh Doan Date: Fri, 15 Jun 2018 22:53:14 -0700 Subject: [PATCH] add data structure for UTXOPool and update verify_new_block --- blockchain/blockchain.go | 30 +++++++++++++++++++++++++----- blockchain/blockchain_test.go | 2 +- blockchain/transaction.go | 2 +- blockchain/utxopool.go | 8 ++++++++ 4 files changed, 35 insertions(+), 7 deletions(-) create mode 100644 blockchain/utxopool.go diff --git a/blockchain/blockchain.go b/blockchain/blockchain.go index edcab3389..00b247f46 100644 --- a/blockchain/blockchain.go +++ b/blockchain/blockchain.go @@ -3,7 +3,6 @@ package blockchain import ( "bytes" "encoding/hex" - "fmt" ) // Blockchain keeps a sequence of Blocks @@ -144,17 +143,38 @@ func (bc *Blockchain) AddNewTransferAmount(from, to string, amount int) *Blockch } // VerifyNewBlock verifies if the new coming block is valid for the current blockchain. -func (bc *Blockchain) VerifyNewBlock(block *Block) bool { +func (bc *Blockchain) VerifyNewBlock(utxopool *UTXOPool, block *Block) bool { length := len(bc.blocks) if bytes.Compare(block.PrevBlockHash, bc.blocks[length-1].Hash) != 0 { - fmt.Println("MINh1") return false } if block.Timestamp < bc.blocks[length-1].Timestamp { - fmt.Println("MINh2") return false } - // TODO(minhdoan): Check Transactions parts + + if utxopool != nil { + for _, tx := range block.Transactions { + inTotal := 0 + // Calculate the sum of TxInput + for _, in := range tx.TxInput { + inTxID := hex.EncodeToString(in.TxID) + if val, ok := utxopool.utxo[in.Address][inTxID]; ok { + inTotal += val + } else { + return false + } + } + + outTotal := 0 + // Calculate the sum of TxOutput + for _, out := range tx.TxOutput { + outTotal += out.Value + } + if inTotal != outTotal { + return false + } + } + } return true } diff --git a/blockchain/blockchain_test.go b/blockchain/blockchain_test.go index 0fb2003c9..f10d4fba3 100644 --- a/blockchain/blockchain_test.go +++ b/blockchain/blockchain_test.go @@ -73,7 +73,7 @@ func TestVerifyNewBlock(t *testing.T) { } newBlock := NewBlock([]*Transaction{tx}, bc.blocks[len(bc.blocks)-1].Hash) - if !bc.VerifyNewBlock(newBlock) { + if !bc.VerifyNewBlock(nil, newBlock) { t.Error("failed to add a new valid block.") } } diff --git a/blockchain/transaction.go b/blockchain/transaction.go index ea96d595e..2ccf34a63 100644 --- a/blockchain/transaction.go +++ b/blockchain/transaction.go @@ -11,7 +11,7 @@ import ( // Transaction represents a Bitcoin transaction type Transaction struct { - ID []byte // 32 byte hash + ID []byte // 32 byte hash TxInput []TXInput TxOutput []TXOutput } diff --git a/blockchain/utxopool.go b/blockchain/utxopool.go new file mode 100644 index 000000000..0a7a13558 --- /dev/null +++ b/blockchain/utxopool.go @@ -0,0 +1,8 @@ +package blockchain + +// UTXOPool stores transactions and balance associated with each address. +type UTXOPool struct { + // Mapping from address to a map of transaction id to that balance. + // The assumption here is that one address only appears once output array in a transaction. + utxo map[string]map[string]int +}