forked from febe19/bazo-miner
-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathblockchain.go
164 lines (143 loc) · 6.06 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
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
package miner
import (
"crypto/ecdsa"
"crypto/rsa"
"github.com/julwil/bazo-miner/crypto"
"github.com/julwil/bazo-miner/p2p"
"github.com/julwil/bazo-miner/protocol"
"github.com/julwil/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
)
//Miner entry point
func Init(
validatorWallet *ecdsa.PublicKey,
multisigWallet,
rootWallet *ecdsa.PublicKey,
validatorCommitment,
rootCommitment *rsa.PrivateKey,
rootChamHashParams *crypto.ChameleonHashParameters,
) {
var err error
validatorAccAddress = crypto.GetAddressFromPubKey(validatorWallet)
multisigPubKey = multisigWallet
commPrivKey = validatorCommitment
rootCommPrivKey = rootCommitment
//Set up logger.
logger = storage.InitLogger()
logger.Printf("\n\n\n" +
"BBBBBBBBBBBBBBBBB AAA ZZZZZZZZZZZZZZZZZZZ OOOOOOOOO\n" +
"B::::::::::::::::B A:::A Z:::::::::::::::::Z OO:::::::::OO\n" +
"B::::::BBBBBB:::::B A:::::A Z:::::::::::::::::Z OO:::::::::::::OO\n" +
"BB:::::B B:::::B A:::::::A Z:::ZZZZZZZZ:::::Z O:::::::OOO:::::::O\n" +
" B::::B B:::::B A:::::::::A ZZZZZ Z:::::Z O::::::O O::::::O\n" +
" B::::B B:::::B A:::::A:::::A Z:::::Z O:::::O O:::::O\n" +
" B::::BBBBBB:::::B A:::::A A:::::A Z:::::Z O:::::O O:::::O\n" +
" B:::::::::::::BB A:::::A A:::::A Z:::::Z O:::::O O:::::O\n" +
" B::::BBBBBB:::::B A:::::A A:::::A Z:::::Z O:::::O O:::::O\n" +
" B::::B B:::::B A:::::AAAAAAAAA:::::A Z:::::Z O:::::O O:::::O\n" +
" B::::B B:::::B A:::::::::::::::::::::A Z:::::Z O:::::O O:::::O\n" +
" B::::B B:::::B A:::::AAAAAAAAAAAAA:::::A ZZZ:::::Z ZZZZZO::::::O O::::::O\n" +
"BB:::::BBBBBB::::::BA:::::A A:::::A Z::::::ZZZZZZZZ:::ZO:::::::OOO:::::::O\n" +
"B:::::::::::::::::BA:::::A A:::::A Z:::::::::::::::::Z OO:::::::::::::OO\n" +
"B::::::::::::::::BA:::::A A:::::A Z:::::::::::::::::Z OO:::::::::OO\n" +
"BBBBBBBBBBBBBBBBBAAAAAAA AAAAAAAZZZZZZZZZZZZZZZZZZZ OOOOOOOOO\n\n\n")
logger.Printf("\n\n\n-------------------- START MINER ---------------------")
logger.Printf("This Miners IP-Address: %v\n\n", p2p.Ipport)
parameterSlice = append(parameterSlice, NewDefaultParameters())
activeParameters = ¶meterSlice[0]
//Initialize root key.
initRootKey(rootWallet, rootChamHashParams)
if err != nil {
logger.Printf("Could not create a root account.\n")
}
currentTargetTime = new(timerange)
target = append(target, 13)
initialBlock, err := initState()
if err != nil {
logger.Printf("Could not set up initial state: %v.\n", err)
return
}
logger.Printf("ActiveConfigParams: \n%v\n------------------------------------------------------------------------\n\nBAZO is Running\n\n", activeParameters)
//this is used to generate the state with aggregated transactions.
for _, tx := range storage.ReadAllBootstrapReceivedTransactions() {
if tx != nil {
storage.DeleteOpenTx(tx)
storage.WriteClosedTx(tx)
}
}
storage.DeleteBootstrapReceivedMempool()
//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, initialBlock.HashWithoutTx, [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.
go broadcastBlock(currentBlock)
logger.Printf("Validated block (mined): %vState:\n%v", currentBlock, getState())
} else {
logger.Printf("Mined block (%x) could not be validated: %v\n", currentBlock.Hash[0:8], err)
}
}
//Prints miner connections
p2p.EmptyingiplistChan()
p2p.PrintMinerConns()
//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.
logger.Printf("\n\n __________________________________________________ New Mining Round __________________________________________________")
blockValidation.Lock()
logger.Printf("Create Next Block")
nextBlock := newBlock(lastBlock.Hash, lastBlock.HashWithoutTx, [crypto.COMM_PROOF_LENGTH]byte{}, lastBlock.Height+1)
currentBlock = nextBlock
logger.Printf("Prepare Next Block")
prepareBlock(currentBlock)
logger.Printf("Prepare Next Block --> Done")
blockValidation.Unlock()
}
}
// At least one root key needs to be set which is allowed to create new accounts.
func initRootKey(rootKey *ecdsa.PublicKey, rootChamHashParams *crypto.ChameleonHashParameters) error {
rootAddress := crypto.GetAddressFromPubKey(rootKey)
rootAddressHash := protocol.SerializeHashContent(rootAddress)
var commPubKey [crypto.COMM_KEY_LENGTH]byte
copy(commPubKey[:], rootCommPrivKey.N.Bytes())
rootAcc := protocol.NewAccount(
rootAddress,
[32]byte{},
activeParameters.StakingMinimum,
true,
commPubKey,
nil,
nil,
rootChamHashParams,
)
storage.State[rootAddressHash] = &rootAcc
storage.RootKeys[rootAddressHash] = &rootAcc
crypto.ChameleonHashParametersMap[rootAddressHash] = rootAcc.Parameters
return nil
}