/
blockchain.go
121 lines (101 loc) · 3.85 KB
/
blockchain.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
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
package miner
import (
"crypto/ecdsa"
"crypto/rsa"
"github.com/bazo-blockchain/bazo-miner/crypto"
"github.com/bazo-blockchain/bazo-miner/protocol"
"github.com/bazo-blockchain/bazo-miner/storage"
"log"
"sync"
)
var (
logger *log.Logger
blockValidation = &sync.Mutex{}
parameterSlice []Parameters
activeParameters *Parameters
uptodate bool
slashingDict = make(map[[32]byte]SlashingProof)
validatorAccAddress [64]byte
multisigPubKey *ecdsa.PublicKey
commPrivKey, rootCommPrivKey *rsa.PrivateKey
blockchainSize uint64 = 0
)
//Miner entry point
func Init(validatorWallet, multisigWallet, rootWallet *ecdsa.PublicKey, validatorCommitment, rootCommitment *rsa.PrivateKey) {
var err error
validatorAccAddress = crypto.GetAddressFromPubKey(validatorWallet)
multisigPubKey = multisigWallet
commPrivKey = validatorCommitment
rootCommPrivKey = rootCommitment
//Set up logger.
logger = storage.InitLogger()
parameterSlice = append(parameterSlice, NewDefaultParameters())
activeParameters = ¶meterSlice[0]
//Initialize root key.
initRootKey(rootWallet)
if err != nil {
logger.Printf("Could not create a root account.\n")
}
currentTargetTime = new(timerange)
target = append(target, 15)
initialBlock, err := initState()
if err != nil {
logger.Printf("Could not set up initial state: %v.\n", err)
return
}
logger.Printf("Active config params:%v", activeParameters)
//Start to listen to network inputs (txs and blocks).
go incomingData()
mining(initialBlock)
}
//Mining is a constant process, trying to come up with a successful PoW.
func mining(initialBlock *protocol.Block) {
currentBlock := newBlock(initialBlock.Hash, [crypto.COMM_PROOF_LENGTH]byte{}, initialBlock.Height+1)
for {
err := finalizeBlock(currentBlock)
if err != nil {
logger.Printf("%v\n", err)
} else {
logger.Printf("Block mined (%x)\n", currentBlock.Hash[0:8])
}
if err == nil {
err := validate(currentBlock, false)
if err == nil {
//Only broadcast the block if it is valid.
broadcastBlock(currentBlock)
logger.Printf("Validated block (mined): %vState:\n%v", currentBlock, getState())
logger.Printf("Size of Block %x: %v Bytes. --> Header: %v Bytes, Body: %v Bytes " +
"--> Body includes %v Bytes of TxData\n",
currentBlock.Hash[0:8], currentBlock.GetSize(), currentBlock.GetHeaderSize(),
currentBlock.GetBodySize(), currentBlock.GetTxDataSize())
CalculateBlockchainSize(currentBlock.GetSize())
} else {
logger.Printf("Mined block (%x) could not be validated: %v\n", currentBlock.Hash[0:8], err)
}
}
//This is the same mutex that is claimed at the beginning of a block validation. The reason we do this is
//that before start mining a new block we empty the mempool which contains tx data that is likely to be
//validated with block validation, so we wait in order to not work on tx data that is already validated
//when we finish the block.
blockValidation.Lock()
nextBlock := newBlock(lastBlock.Hash, [crypto.COMM_PROOF_LENGTH]byte{}, lastBlock.Height+1)
currentBlock = nextBlock
prepareBlock(currentBlock)
blockValidation.Unlock()
}
}
//At least one root key needs to be set which is allowed to create new accounts.
func initRootKey(rootKey *ecdsa.PublicKey) error {
address := crypto.GetAddressFromPubKey(rootKey)
addressHash := protocol.SerializeHashContent(address)
var commPubKey [crypto.COMM_KEY_LENGTH]byte
copy(commPubKey[:], rootCommPrivKey.N.Bytes())
rootAcc := protocol.NewAccount(address, [32]byte{}, activeParameters.Staking_minimum, true, commPubKey, nil, nil)
storage.State[addressHash] = &rootAcc
storage.RootKeys[addressHash] = &rootAcc
return nil
}
func CalculateBlockchainSize(currentBlockSize uint64) {
blockchainSize = blockchainSize + currentBlockSize
logger.Printf("Blockchain size is: %v bytes\n", blockchainSize)
}