Add transactions num and Ids list to block

pull/8/head
Rongjian Lan 7 years ago
parent ca404d2d71
commit cb983ce484
  1. 2
      aws-code/transaction_generator.go
  2. 25
      blockchain/block.go
  3. 6
      blockchain/blockchain.go
  4. 8
      blockchain/transaction.go
  5. 8
      blockchain/utxopool.go
  6. 18
      node/node_handler.go

@ -53,7 +53,7 @@ func getNewFakeTransactions(dataNode *node.Node, numTxs int) []*blockchain.Trans
// Spend the money of current UTXO to a random address in [1 - 1000] // Spend the money of current UTXO to a random address in [1 - 1000]
txin := blockchain.TXInput{txId, index, address} txin := blockchain.TXInput{txId, index, address}
txout := blockchain.TXOutput{value, strconv.Itoa(rand.Intn(1000))} txout := blockchain.TXOutput{value, strconv.Itoa(rand.Intn(1000))}
tx := blockchain.Transaction{nil, []blockchain.TXInput{txin}, []blockchain.TXOutput{txout}} tx := blockchain.Transaction{[32]byte{}, []blockchain.TXInput{txin}, []blockchain.TXOutput{txout}}
tx.SetID() tx.SetID()
if count >= numTxs { if count >= numTxs {

@ -9,12 +9,19 @@ import (
"time" "time"
) )
// Block keeps block headers. // Block keeps block headers, transactions and signature.
type Block struct { type Block struct {
Timestamp int64 // Header
Timestamp int64
PrevBlockHash [32]byte
Hash [32]byte
NumTransactions int32
TransactionIds [][32]byte
// Transactions
Transactions []*Transaction Transactions []*Transaction
PrevBlockHash [32]byte
Hash [32]byte // Signature...
} }
// Serialize serializes the block // Serialize serializes the block
@ -56,7 +63,7 @@ func (b *Block) HashTransactions() []byte {
var txHash [32]byte var txHash [32]byte
for _, tx := range b.Transactions { for _, tx := range b.Transactions {
txHashes = append(txHashes, tx.ID) txHashes = append(txHashes, tx.ID[:])
} }
txHash = sha256.Sum256(bytes.Join(txHashes, []byte{})) txHash = sha256.Sum256(bytes.Join(txHashes, []byte{}))
return txHash[:] return txHash[:]
@ -64,7 +71,13 @@ func (b *Block) HashTransactions() []byte {
// NewBlock creates and returns a neew block. // NewBlock creates and returns a neew block.
func NewBlock(transactions []*Transaction, prevBlockHash [32]byte) *Block { func NewBlock(transactions []*Transaction, prevBlockHash [32]byte) *Block {
block := &Block{time.Now().Unix(), transactions, prevBlockHash, [32]byte{}} numTxs := int32(len(transactions))
var txIds [][32]byte
for _, tx := range transactions {
txIds = append(txIds, tx.ID)
}
block := &Block{time.Now().Unix(), prevBlockHash, [32]byte{},numTxs, txIds,transactions}
copy(block.Hash[:], block.HashTransactions()[:]) // TODO(Minh): the blockhash should be a hash of everything in the block copy(block.Hash[:], block.HashTransactions()[:]) // TODO(Minh): the blockhash should be a hash of everything in the block
return block return block

@ -29,7 +29,7 @@ func (bc *Blockchain) FindUnspentTransactions(address string) []Transaction {
block := bc.Blocks[index] block := bc.Blocks[index]
for _, tx := range block.Transactions { for _, tx := range block.Transactions {
txID := hex.EncodeToString(tx.ID) txID := hex.EncodeToString(tx.ID[:])
idx := -1 idx := -1
// TODO(minhdoan): Optimize this. // TODO(minhdoan): Optimize this.
@ -85,7 +85,7 @@ func (bc *Blockchain) FindSpendableOutputs(address string, amount int) (int, map
Work: Work:
for _, tx := range unspentTXs { for _, tx := range unspentTXs {
txID := hex.EncodeToString(tx.ID) txID := hex.EncodeToString(tx.ID[:])
for outIdx, txOutput := range tx.TxOutput { for outIdx, txOutput := range tx.TxOutput {
if txOutput.Address == address && accumulated < amount { if txOutput.Address == address && accumulated < amount {
@ -132,7 +132,7 @@ func (bc *Blockchain) NewUTXOTransaction(from, to string, amount int) *Transacti
outputs = append(outputs, TXOutput{acc - amount, from}) // a change outputs = append(outputs, TXOutput{acc - amount, from}) // a change
} }
tx := Transaction{nil, inputs, outputs} tx := Transaction{[32]byte{}, inputs, outputs}
tx.SetID() tx.SetID()
return &tx return &tx

@ -11,7 +11,7 @@ import (
// Transaction represents a Bitcoin transaction // Transaction represents a Bitcoin transaction
type Transaction struct { type Transaction struct {
ID []byte // 32 byte hash ID [32]byte // 32 byte hash
TxInput []TXInput TxInput []TXInput
TxOutput []TXOutput TxOutput []TXOutput
} }
@ -43,7 +43,7 @@ func (tx *Transaction) SetID() {
log.Panic(err) log.Panic(err)
} }
hash = sha256.Sum256(encoded.Bytes()) hash = sha256.Sum256(encoded.Bytes())
tx.ID = hash[:] tx.ID = hash
} }
// NewCoinbaseTX creates a new coinbase transaction // NewCoinbaseTX creates a new coinbase transaction
@ -54,7 +54,7 @@ func NewCoinbaseTX(to, data string) *Transaction {
txin := TXInput{[]byte{}, -1, data} txin := TXInput{[]byte{}, -1, data}
txout := TXOutput{DefaultCoinbaseValue, to} txout := TXOutput{DefaultCoinbaseValue, to}
tx := Transaction{nil, []TXInput{txin}, []TXOutput{txout}} tx := Transaction{[32]byte{}, []TXInput{txin}, []TXOutput{txout}}
tx.SetID() tx.SetID()
return &tx return &tx
} }
@ -76,7 +76,7 @@ func (txOutput *TXOutput) String() string {
// Used for debuging. // Used for debuging.
func (tx *Transaction) String() string { func (tx *Transaction) String() string {
res := fmt.Sprintf("ID: %v\n", hex.EncodeToString(tx.ID)) res := fmt.Sprintf("ID: %v\n", hex.EncodeToString(tx.ID[:]))
res += fmt.Sprintf("TxInput:\n") res += fmt.Sprintf("TxInput:\n")
for id, value := range tx.TxInput { for id, value := range tx.TxInput {
res += fmt.Sprintf("%v: %v\n", id, value.String()) res += fmt.Sprintf("%v: %v\n", id, value.String())

@ -79,7 +79,7 @@ func (utxoPool *UTXOPool) VerifyTransactions(transactions []*Transaction) bool {
// VerifyOneTransaction verifies if a list of transactions valid. // VerifyOneTransaction verifies if a list of transactions valid.
func (utxoPool *UTXOPool) VerifyOneTransaction(tx *Transaction) bool { func (utxoPool *UTXOPool) VerifyOneTransaction(tx *Transaction) bool {
spentTXOs := make(map[string]map[string]map[int]bool) spentTXOs := make(map[string]map[string]map[int]bool)
txID := hex.EncodeToString(tx.ID) txID := hex.EncodeToString(tx.ID[:])
inTotal := 0 inTotal := 0
// Calculate the sum of TxInput // Calculate the sum of TxInput
for _, in := range tx.TxInput { for _, in := range tx.TxInput {
@ -121,7 +121,7 @@ func (utxoPool *UTXOPool) VerifyOneTransaction(tx *Transaction) bool {
// UpdateOneTransaction updates utxoPool in respect to the new Transaction. // UpdateOneTransaction updates utxoPool in respect to the new Transaction.
func (utxoPool *UTXOPool) UpdateOneTransaction(tx *Transaction) { func (utxoPool *UTXOPool) UpdateOneTransaction(tx *Transaction) {
if utxoPool != nil { if utxoPool != nil {
txID := hex.EncodeToString(tx.ID) txID := hex.EncodeToString(tx.ID[:])
// Remove // Remove
for _, in := range tx.TxInput { for _, in := range tx.TxInput {
@ -166,7 +166,7 @@ func (utxoPool *UTXOPool) VerifyAndUpdate(transactions []*Transaction) bool {
func (utxoPool *UTXOPool) Update(transactions []*Transaction) { func (utxoPool *UTXOPool) Update(transactions []*Transaction) {
if utxoPool != nil { if utxoPool != nil {
for _, tx := range transactions { for _, tx := range transactions {
curTxID := hex.EncodeToString(tx.ID) curTxID := hex.EncodeToString(tx.ID[:])
// Remove // Remove
for _, in := range tx.TxInput { for _, in := range tx.TxInput {
@ -192,7 +192,7 @@ func (utxoPool *UTXOPool) Update(transactions []*Transaction) {
// CreateUTXOPoolFromTransaction a Utxo pool from a genesis transaction. // CreateUTXOPoolFromTransaction a Utxo pool from a genesis transaction.
func CreateUTXOPoolFromTransaction(tx *Transaction) *UTXOPool { func CreateUTXOPoolFromTransaction(tx *Transaction) *UTXOPool {
var utxoPool UTXOPool var utxoPool UTXOPool
txID := hex.EncodeToString(tx.ID) txID := hex.EncodeToString(tx.ID[:])
utxoPool.UtxoMap = make(map[string]map[string]map[int]int) utxoPool.UtxoMap = make(map[string]map[string]map[int]int)
for index, out := range tx.TxOutput { for index, out := range tx.TxOutput {
utxoPool.UtxoMap[out.Address] = make(map[string]map[int]int) utxoPool.UtxoMap[out.Address] = make(map[string]map[int]int)

@ -85,19 +85,21 @@ func (node *Node) transactionMessageHandler(msgPayload []byte) {
case REQUEST: case REQUEST:
reader := bytes.NewBuffer(msgPayload[1:]) reader := bytes.NewBuffer(msgPayload[1:])
var txIds map[[32]byte]bool var txIds map[[32]byte]bool
txId := make([]byte, 32) // 32 byte hash Id buf := make([]byte, 32) // 32 byte hash Id
for { for {
_, err := reader.Read(txId) _, err := reader.Read(buf)
if err != nil { if err != nil {
break break
} }
txIds[getFixedByteTxId(txId)] = true var txId [32]byte
copy(txId[:], buf)
txIds[txId] = true
} }
var txToReturn []*blockchain.Transaction var txToReturn []*blockchain.Transaction
for _, tx := range node.pendingTransactions { for _, tx := range node.pendingTransactions {
if txIds[getFixedByteTxId(tx.ID)] { if txIds[tx.ID] {
txToReturn = append(txToReturn, tx) txToReturn = append(txToReturn, tx)
} }
} }
@ -106,14 +108,6 @@ func (node *Node) transactionMessageHandler(msgPayload []byte) {
} }
} }
// Copy the txId byte slice over to 32 byte array so the map can key on it
func getFixedByteTxId(txId []byte) [32]byte {
var id [32]byte
for i := range id {
id[i] = txId[i]
}
return id
}
func (node *Node) WaitForConsensusReady(readySignal chan int) { func (node *Node) WaitForConsensusReady(readySignal chan int) {
node.log.Debug("Waiting for consensus ready", "node", node) node.log.Debug("Waiting for consensus ready", "node", node)

Loading…
Cancel
Save