slowlorisdb/node/node.go
node/node.goRaw
1package node
2
3import (
4 "crypto/ecdsa"
5 "time"
6
7 "github.com/arnaucube/slowlorisdb/core"
8)
9
10type Node struct {
11 PrivK *ecdsa.PrivateKey
12 Addr core.Address
13 Bc *core.Blockchain
14 Miner bool // indicates if the node is running as a miner
15 PendingTxs []core.Tx
16}
17
18func NewNode(privK *ecdsa.PrivateKey, bc *core.Blockchain, isMiner bool) (*Node, error) {
19 addr := core.AddressFromPrivK(privK)
20
21 node := &Node{
22 PrivK: privK,
23 Addr: addr,
24 Bc: bc,
25 Miner: isMiner,
26 PendingTxs: []core.Tx{},
27 }
28 return node, nil
29}
30
31func (node *Node) Sign(m []byte) (*core.Signature, error) {
32 return core.Sign(node.PrivK, m)
33}
34
35func (node *Node) SignBlock(block *core.Block) error {
36 block.CalculateHash()
37 sig, err := core.Sign(node.PrivK, block.Hash[:])
38 if err != nil {
39 return err
40 }
41 block.Signature = sig.Bytes()
42 return nil
43}
44
45func (node *Node) AddToPendingTxs(tx core.Tx) {
46 node.PendingTxs = append(node.PendingTxs, tx)
47}
48
49func (node *Node) BlockFromPendingTxs() (*core.Block, error) {
50 block, err := node.NewBlock(node.PendingTxs)
51 if err != nil {
52 return nil, err
53 }
54 block.PrevHash = node.Bc.LastBlock.Hash
55 err = block.CalculatePoW(node.Bc.Difficulty)
56 if err != nil {
57 return nil, err
58 }
59 err = node.SignBlock(block)
60 if err != nil {
61 return nil, err
62 }
63 block.CalculateHash()
64
65 return block, nil
66}
67
68func (node *Node) NewBlock(txs []core.Tx) (*core.Block, error) {
69 block := &core.Block{
70 Height: node.Bc.GetHeight() + 1,
71 PrevHash: node.Bc.LastBlock.Hash,
72 Txs: txs,
73 Miner: core.Address{},
74 MinerPubK: &node.PrivK.PublicKey,
75 Timestamp: time.Now(),
76 Nonce: 0,
77 Hash: core.Hash{},
78 Signature: []byte{},
79 }
80 block.CalculateHash()
81 err := node.SignBlock(block)
82 if err != nil {
83 return nil, err
84 }
85 return block, nil
86}
87
88func (node *Node) CreateGenesis(pubK *ecdsa.PublicKey, amount uint64) (*core.Block, error) {
89 // pubK is the wallet where the first coins will be created
90 // amount is the amount of coins that will be created
91
92 in := core.Input{
93 TxId: core.GenesisHashTxInput,
94 Vout: 0,
95 Value: amount,
96 }
97 var ins []core.Input
98 ins = append(ins, in)
99
100 out := core.Output{
101 Value: amount,
102 }
103 var outs []core.Output
104 outs = append(outs, out)
105
106 tx := core.Tx{
107 From: &ecdsa.PublicKey{},
108 To: pubK,
109 InputCount: uint64(0),
110 Inputs: []core.Input{},
111 Outputs: outs,
112 Signature: []byte{},
113 }
114
115 // calculate TxId
116 // tx.CalculateTxId()
117 tx.TxId = core.GenesisHashTxInput
118 // sign transaction
119
120 var txs []core.Tx
121 txs = append(txs, tx)
122
123 block := &core.Block{
124 Height: node.Bc.LastBlock.Height + 1,
125 PrevHash: node.Bc.LastBlock.Hash,
126 Txs: txs,
127 Miner: node.Addr,
128 MinerPubK: &node.PrivK.PublicKey,
129 Timestamp: time.Now(),
130 Nonce: uint64(0),
131 Hash: core.Hash{},
132 Signature: []byte{},
133 }
134
135 block.CalculateHash()
136 err := node.SignBlock(block)
137 if err != nil {
138 return nil, err
139 }
140 return block, nil
141}