-
Notifications
You must be signed in to change notification settings - Fork 0
/
database.go
77 lines (57 loc) · 1.78 KB
/
database.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
package kcoin
import "github.com/boltdb/bolt"
const dbFilePath = "./assets/blockchain.db"
const dbFileMode = 0600
const blocksBucketName = "blocks"
const lastHashKey = "l"
func createDBIfNotExist(address []byte) (*bolt.DB, []byte) {
var tip []byte
db, outErr := bolt.Open(dbFilePath, dbFileMode, nil)
outErr = db.Update(func(tx *bolt.Tx) error {
blocksBucket := tx.Bucket([]byte(blocksBucketName))
var inErr error
if blocksBucket == nil {
coinbaseTx := NewCoinbaseTransaction(address, genesisCoinbaseData)
genesis := NewGenesisBlock(coinbaseTx)
blocksBucket, inErr = tx.CreateBucket([]byte(blocksBucketName))
inErr = blocksBucket.Put(genesis.Hash, SerializeBlock(genesis))
inErr = blocksBucket.Put([]byte(lastHashKey), genesis.Hash)
tip = genesis.Hash
} else {
tip = blocksBucket.Get([]byte(lastHashKey))
}
return inErr
})
panicIfErrNotNil(outErr)
return db, tip
}
func getBlock(db *bolt.DB, hash []byte) *Block {
var block *Block
err := db.View(func(tx *bolt.Tx) error {
blocksBucket := tx.Bucket([]byte(blocksBucketName))
encodedBlock := blocksBucket.Get(hash)
block = DeserializeBlock(encodedBlock)
return nil
})
panicIfErrNotNil(err)
return block
}
func getLastBlockHash(db *bolt.DB) []byte {
var lastHash []byte
err := db.View(func(tx *bolt.Tx) error {
blocksBucket := tx.Bucket([]byte(blocksBucketName))
lastHash = blocksBucket.Get([]byte(lastHashKey))
return nil
})
panicIfErrNotNil(err)
return lastHash
}
func addBlockToDB(db *bolt.DB, newBlock *Block) {
outErr := db.Update(func(tx *bolt.Tx) error {
blocksBucket := tx.Bucket([]byte(blocksBucketName))
inErr := blocksBucket.Put(newBlock.Hash, SerializeBlock(newBlock))
inErr = blocksBucket.Put([]byte(lastHashKey), newBlock.Hash)
return inErr
})
panicIfErrNotNil(outErr)
}