Skip to content

Commit 4c68d5f

Browse files
authored
Merge pull request #13 from tdadadavid/feat/blockchain_db
[Feat]: blockchain db
2 parents 4630fea + 60d3484 commit 4c68d5f

File tree

5 files changed

+52
-40
lines changed

5 files changed

+52
-40
lines changed

cmd/block_functions.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package cmd
22

33
import (
4+
"context"
45
"fmt"
56

67
"github.com/tdadadavid/block/pkg/chain"
@@ -9,7 +10,7 @@ import (
910
var blockChain chain.Chain
1011

1112
func init() {
12-
blockChain = chain.New("/data/blocks")
13+
blockChain = chain.New(context.Background(), "/data/blocks")
1314
}
1415

1516
func printChain() {

pkg/chain/chain.go

Lines changed: 15 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package chain
22

33
import (
4+
"context"
45
"encoding/json"
56
"fmt"
67

@@ -10,10 +11,12 @@ import (
1011

1112
type Chain struct {
1213
// store In memory database that stores the chain's data
13-
store *BlockStore
14+
store *ChainStore
1415

1516
// currentHash the current hash for this chain
1617
currentHash string
18+
19+
chainCtx context.Context
1720
}
1821

1922
// New creates a new chain
@@ -31,7 +34,7 @@ type Chain struct {
3134
//
3235
// Returns:
3336
// - bc(Chain): The newly created chain
34-
func New(storagePath string) (bc Chain) {
37+
func New(ctx context.Context, storagePath string) (bc Chain) {
3538
// Set the in-memory store for the chain and disable storage logs
3639
options := badger.DefaultOptions("./../../data/blocks").WithLogger(nil)
3740

@@ -40,8 +43,10 @@ func New(storagePath string) (bc Chain) {
4043
panic(fmt.Errorf("failed to create chain %v", err))
4144
}
4245

43-
44-
bc = Chain{store: &BlockStore{store: store}}
46+
bc = Chain{
47+
chainCtx: ctx,
48+
store: &ChainStore{store: store},
49+
}
4550
bc.currentHash = bc.getLastHash()
4651

4752
return bc
@@ -55,7 +60,7 @@ func New(storagePath string) (bc Chain) {
5560
// Returns:
5661
// - The hash of the block at "LAST" position
5762
func (c *Chain) getLastHash() string {
58-
b := c.store.FindLastOrCreate()
63+
b := c.store.FindLastOrCreate(c.chainCtx)
5964
return b.GetHash()
6065
}
6166

@@ -71,20 +76,20 @@ func (c *Chain) getLastHash() string {
7176
// - Set the Chains hash to the new block's hash
7277
func (c *Chain) AddBlock(data string) {
7378
// get previous block
74-
prevBlock, err := c.store.FindLast()
79+
prevBlock, err := c.store.FindLast(c.chainCtx)
7580
if err != nil {
7681
fmt.Printf("error while finding previous block: %s\n", err.Error())
7782
}
7883

7984
// creates new block with previous block hash
8085
newBlock := block.New(data, prevBlock.GetHash(), block.HashDifficulty) // create new block
81-
err = c.store.Create(newBlock.GetHash(), newBlock)
86+
err = c.store.Create(c.chainCtx, newBlock.GetHash(), newBlock)
8287
if err != nil {
8388
fmt.Printf("error while creating new block %v", err)
8489
}
8590

8691
// update 'LAST' key in chain point to new block.
87-
err = c.store.UpdateLast(newBlock)
92+
err = c.store.UpdateLast(c.chainCtx, newBlock)
8893
if err != nil {
8994
fmt.Println("error while updating last block")
9095
}
@@ -118,5 +123,5 @@ func (c *Chain) iter() ChainIterator {
118123

119124
// Utility functions
120125
func (c *Chain) FindLast() (block.Block, error) {
121-
return c.store.FindLast()
122-
}
126+
return c.store.FindLast(c.chainCtx)
127+
}

pkg/chain/chain_test.go

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package chain
22

33
import (
4+
"context"
45
"os"
56
"testing"
67

@@ -19,15 +20,15 @@ func cleanUp(t *testing.T) {
1920
func TestBlockchain_New(t *testing.T) {
2021
defer cleanUp(t)
2122

22-
bc := New("./../../data/blocks")
23+
bc := New(context.Background(), "./../../data/blocks")
2324
assert.NotNil(t, bc)
2425
}
2526

2627
func TestBlockchain_AddBlock(t *testing.T) {
2728
defer cleanUp(t)
2829

2930
// create blockchain
30-
bc := New("./../../data/blocks")
31+
bc := New(context.Background(), "./../../data/blocks")
3132
assert.NotNil(t, bc)
3233

3334
// get prevHash (genesis block)
@@ -37,9 +38,11 @@ func TestBlockchain_AddBlock(t *testing.T) {
3738
// add block
3839
bc.AddBlock("test_data")
3940

41+
ctx := context.Background()
42+
4043
iter := bc.iter()
41-
for iter.HasNext() {
42-
it := iter.Next()
44+
for iter.HasNext(ctx) {
45+
it := iter.Next(ctx)
4346
if it == nil {
4447
assert.Equal(t, "", iter.currentHash)
4548
} else {

pkg/chain/iterator.go

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,15 @@
11
package chain
22

3-
import "github.com/tdadadavid/block/pkg/block"
3+
import (
4+
"context"
5+
6+
"github.com/tdadadavid/block/pkg/block"
7+
)
48

59
// Iterator captures the building block of any iterable
610
type Iterator interface {
7-
Next() *block.Block
8-
HasNext() bool
11+
Next(ctx context.Context) *block.Block
12+
HasNext(ctx context.Context) bool
913
}
1014

1115
// ChainIterator Iterator used for moving through the chain it implements the Iterator interface
@@ -26,14 +30,14 @@ type ChainIterator struct {
2630
//
2731
// Returns:
2832
// - bool: either true or false to signify if the iteration should continue
29-
func (it *ChainIterator) HasNext() bool {
33+
func (it *ChainIterator) HasNext(ctx context.Context) bool {
3034
// if the chain is empty or the current hash is empty stop iteration
3135
if it.blockchain == nil || it.currentHash == "" {
3236
return false
3337
}
3438

3539
// check if the block of the currentHash exists if it does the continue iteration else stop.
36-
_, err := it.blockchain.store.FindByHash(it.currentHash)
40+
_, err := it.blockchain.store.FindByHash(ctx, it.currentHash)
3741
if err != nil {
3842
return false
3943
}
@@ -50,15 +54,15 @@ func (it *ChainIterator) HasNext() bool {
5054
//
5155
// Returns:
5256
// - currBlock: The pointer to the current block from the database
53-
func (it *ChainIterator) Next() (curBlock *block.Block) {
57+
func (it *ChainIterator) Next(ctx context.Context) (curBlock *block.Block) {
5458
// check if there is a next block on the chain
55-
if !it.HasNext() {
59+
if !it.HasNext(ctx) {
5660
it.currentHash = ""
5761
return curBlock
5862
}
5963

6064
// find the current block using the current hash
61-
b, err := it.blockchain.store.FindByHash(it.currentHash)
65+
b, err := it.blockchain.store.FindByHash(ctx, it.currentHash)
6266
if err != nil {
6367
it.currentHash = ""
6468
return curBlock

pkg/chain/store.go

Lines changed: 16 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -14,27 +14,26 @@ var LastKey = []byte("LAST")
1414
type Storage interface {
1515
FindLastOrCreate(ctx context.Context) block.Block
1616
Create(ctx context.Context, key string, b block.Block) error
17-
FindByHash(ctx context.Context, hash string) block.Block
17+
FindByHash(ctx context.Context, hash string) (block.Block, error)
1818
FindLast(ctx context.Context) (block.Block, error)
1919
UpdateLast(ctx context.Context, b block.Block) error
2020
}
2121

22-
type BlockStore struct {
22+
type ChainStore struct {
2323
store *badger.DB
2424
}
2525

26-
27-
// findLastOrCreate used to get the last block in the chain or creates a new genesis block
26+
// FindLastOrCreate used to get the last block in the chain or creates a new genesis block
2827
//
2928
// Process:
3029
// - Queries storage to get the block at the "LAST" position
3130
// - If the block is not found then create the Genesis block for this chain, else returns the last found block
3231
//
3332
// Returns
3433
// - last: The block at the "LAST" position
35-
func (bs *BlockStore) FindLastOrCreate() (last block.Block) {
34+
func (cs *ChainStore) FindLastOrCreate(ctx context.Context) (last block.Block) {
3635
// try to findLast the block with the key 'LAST'
37-
last, err := bs.FindLast()
36+
last, err := cs.FindLast(ctx)
3837
if err != nil {
3938
//TODO: standardize logging
4039
fmt.Printf("error finding last block err: [%s]\n", err.Error())
@@ -46,7 +45,7 @@ func (bs *BlockStore) FindLastOrCreate() (last block.Block) {
4645
// if not found create the genesis block
4746
fmt.Printf("creating new genesis block\n")
4847
last = block.NewGenesisBlock()
49-
err = bs.Create(string(LastKey), last)
48+
err = cs.Create(ctx, string(LastKey), last)
5049
if err != nil {
5150
fmt.Printf("error while creating last item %s", err.Error())
5251
}
@@ -67,8 +66,8 @@ func (bs *BlockStore) FindLastOrCreate() (last block.Block) {
6766
//
6867
// Returns
6968
// - error: Returns the error during block creation process
70-
func (bs *BlockStore) Create(key string, b block.Block) error {
71-
err := bs.store.Update(func(txn *badger.Txn) (err error) {
69+
func (cs *ChainStore) Create(ctx context.Context, key string, b block.Block) error {
70+
err := cs.store.Update(func(txn *badger.Txn) (err error) {
7271
data, err := b.Serialize()
7372
if err != nil {
7473
return err
@@ -82,7 +81,7 @@ func (bs *BlockStore) Create(key string, b block.Block) error {
8281
return err
8382
}
8483

85-
// findByHash finds a block by the given hash
84+
// FindByHash finds a block by the given hash
8685
//
8786
// Parameters:
8887
// - hash(string): The hash of the block that we want to retrieve
@@ -94,9 +93,9 @@ func (bs *BlockStore) Create(key string, b block.Block) error {
9493
// Returns
9594
// - b(block): Returns the block just found
9695
// - err(error): Returns the error during block creation process
97-
func (bs *BlockStore) FindByHash(hash string) (b block.Block, err error) {
96+
func (cs *ChainStore) FindByHash(ctx context.Context, hash string) (b block.Block, err error) {
9897
b = block.Block{}
99-
err = bs.store.View(func(txn *badger.Txn) error {
98+
err = cs.store.View(func(txn *badger.Txn) error {
10099
lastBlock, err := txn.Get([]byte(hash))
101100
if err != nil {
102101
return err
@@ -110,7 +109,7 @@ func (bs *BlockStore) FindByHash(hash string) (b block.Block, err error) {
110109
return b, err
111110
}
112111

113-
// findByHash finds a block by the given hash
112+
// FindLast finds a block by the given hash
114113
//
115114
// Process:
116115
// - Retrieves the block in bytes if it exists, else returns error
@@ -119,9 +118,9 @@ func (bs *BlockStore) FindByHash(hash string) (b block.Block, err error) {
119118
// Returns
120119
// - block: Returns the block just found
121120
// - error: Returns the error during block creation process
122-
func (bs *BlockStore) FindLast() (block.Block, error) {
121+
func (cs *ChainStore) FindLast(ctx context.Context) (block.Block, error) {
123122
b := &block.Block{}
124-
err := bs.store.View(func(txn *badger.Txn) error {
123+
err := cs.store.View(func(txn *badger.Txn) error {
125124
lastBlock, err := txn.Get(LastKey)
126125
if err != nil {
127126
return err
@@ -143,8 +142,8 @@ func (bs *BlockStore) FindLast() (block.Block, error) {
143142
//
144143
// Returns
145144
// - error: Returns the error during update process
146-
func (bs *BlockStore) UpdateLast(b block.Block) (err error) {
147-
err = bs.store.Update(func(txn *badger.Txn) error {
145+
func (cs *ChainStore) UpdateLast(ctx context.Context, b block.Block) (err error) {
146+
err = cs.store.Update(func(txn *badger.Txn) error {
148147
data, err := b.Serialize()
149148
if err != nil {
150149
return err

0 commit comments

Comments
 (0)