decouple CreateBlockchain and UTXOPool into different methods

pull/5/merge
Minh Doan 7 years ago
parent c45ed9439f
commit 6a48a4d810
  1. 4
      blockchain/block_test.go
  2. 6
      blockchain/blockchain.go
  3. 13
      blockchain/blockchain_test.go
  4. 11
      blockchain/transaction.go
  5. 2
      blockchain/transaction_test.go
  6. 31
      blockchain/utxopool.go
  7. 2
      blockchain/utxopool_test.go

@ -6,8 +6,8 @@ import (
)
func TestBlockSerialize(t *testing.T) {
cbtx, utxoPool := NewCoinbaseTX("minh", genesisCoinbaseData)
if cbtx == nil || utxoPool == nil {
cbtx := NewCoinbaseTX("minh", genesisCoinbaseData)
if cbtx == nil {
t.Errorf("Failed to create a coinbase transaction.")
}
block := NewGenesisBlock(cbtx)

@ -161,13 +161,13 @@ func (bc *Blockchain) VerifyNewBlockAndUpdate(utxopool *UTXOPool, block *Block)
}
// CreateBlockchain creates a new blockchain DB
func CreateBlockchain(address string) (*Blockchain, *UTXOPool) {
func CreateBlockchain(address string) *Blockchain {
// TODO: We assume we have not created any blockchain before.
// In current bitcoin, we can check if we created a blockchain before accessing local db.
cbtx, utxoPool := NewCoinbaseTX(address, genesisCoinbaseData)
cbtx := NewCoinbaseTX(address, genesisCoinbaseData)
genesis := NewGenesisBlock(cbtx)
bc := Blockchain{[]*Block{genesis}}
return &bc, utxoPool
return &bc
}

@ -5,14 +5,14 @@ import (
)
func TestCreateBlockchain(t *testing.T) {
if bc, _ := CreateBlockchain("minh"); bc == nil {
if bc := CreateBlockchain("minh"); bc == nil {
t.Errorf("failed to create a blockchain")
}
}
func TestFindSpendableOutputs(t *testing.T) {
requestAmount := 3
bc, _ := CreateBlockchain("minh")
bc := CreateBlockchain("minh")
accumulated, unspentOutputs := bc.FindSpendableOutputs("minh", requestAmount)
if accumulated < DefaultCoinbaseValue {
t.Error("Failed to find enough unspent ouptuts")
@ -24,7 +24,7 @@ func TestFindSpendableOutputs(t *testing.T) {
}
func TestFindUTXO(t *testing.T) {
bc, _ := CreateBlockchain("minh")
bc := CreateBlockchain("minh")
utxo := bc.FindUTXO("minh")
total := 0
@ -41,7 +41,8 @@ func TestFindUTXO(t *testing.T) {
}
func TestAddNewUserTransfer(t *testing.T) {
bc, utxoPool := CreateBlockchain("minh")
bc := CreateBlockchain("minh")
utxoPool := CreateUTXOPoolFromGenesisBlockChain(bc)
if !bc.AddNewUserTransfer(utxoPool, "minh", "alok", 3) {
t.Error("Failed to add new transfer to alok.")
@ -57,7 +58,9 @@ func TestAddNewUserTransfer(t *testing.T) {
}
func TestVerifyNewBlock(t *testing.T) {
bc, utxoPool := CreateBlockchain("minh")
bc := CreateBlockchain("minh")
utxoPool := CreateUTXOPoolFromGenesisBlockChain(bc)
bc.AddNewUserTransfer(utxoPool, "minh", "alok", 3)
bc.AddNewUserTransfer(utxoPool, "minh", "rj", 100)

@ -47,7 +47,7 @@ func (tx *Transaction) SetID() {
}
// NewCoinbaseTX creates a new coinbase transaction
func NewCoinbaseTX(to, data string) (*Transaction, *UTXOPool) {
func NewCoinbaseTX(to, data string) *Transaction {
if data == "" {
data = fmt.Sprintf("Reward to '%s'", to)
}
@ -56,14 +56,7 @@ func NewCoinbaseTX(to, data string) (*Transaction, *UTXOPool) {
txout := TXOutput{DefaultCoinbaseValue, to}
tx := Transaction{nil, []TXInput{txin}, []TXOutput{txout}}
tx.SetID()
txID := hex.EncodeToString(tx.ID)
var utxoPool UTXOPool
utxoPool.utxo = make(map[string]map[string]int)
utxoPool.utxo[to] = make(map[string]int)
utxoPool.utxo[to][txID] = DefaultCoinbaseValue
return &tx, &utxoPool
return &tx
}
// Used for debuging.

@ -5,7 +5,7 @@ import (
)
func TestNewCoinbaseTX(t *testing.T) {
if cbtx, utxoPool := NewCoinbaseTX("minh", genesisCoinbaseData); cbtx == nil || utxoPool == nil {
if cbtx := NewCoinbaseTX("minh", genesisCoinbaseData); cbtx == nil {
t.Errorf("failed to create a coinbase transaction.")
}
}

@ -6,9 +6,9 @@ import (
// 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]map[int]int
// Mapping from address to a map of transaction id to a map of the index of output
// array in that transaction to that balance.
utxo map[string]map[string]int
}
// VerifyTransactions verifies if a list of transactions valid.
@ -88,3 +88,28 @@ func (utxopool *UTXOPool) Update(transactions []*Transaction) {
}
}
}
// CreateUTXOPoolFromTransaction a utxo pool from a genesis transaction.
func CreateUTXOPoolFromTransaction(tx *Transaction) *UTXOPool {
var utxoPool UTXOPool
txID := hex.EncodeToString(tx.ID)
utxoPool.utxo = make(map[string]map[string]int)
for _, out := range tx.TxOutput {
utxoPool.utxo[out.Address] = make(map[string]int)
utxoPool.utxo[out.Address][txID] = DefaultCoinbaseValue
}
return &utxoPool
}
// CreateUTXOPoolFromGenesisBlockChain a utxo pool from a genesis blockchain.
func CreateUTXOPoolFromGenesisBlockChain(bc *Blockchain) *UTXOPool {
tx := bc.blocks[0].Transactions[0]
var utxoPool UTXOPool
txID := hex.EncodeToString(tx.ID)
utxoPool.utxo = make(map[string]map[string]int)
for _, out := range tx.TxOutput {
utxoPool.utxo[out.Address] = make(map[string]int)
utxoPool.utxo[out.Address][txID] = DefaultCoinbaseValue
}
return &utxoPool
}

@ -5,7 +5,7 @@ import (
)
func TestVerifyTransactions(t *testing.T) {
if cbtx, utxoPool := NewCoinbaseTX("minh", genesisCoinbaseData); cbtx == nil || utxoPool == nil {
if cbtx := NewCoinbaseTX("minh", genesisCoinbaseData); cbtx == nil {
t.Errorf("failed to create a coinbase transaction.")
}
}

Loading…
Cancel
Save