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) Start() error {
32 return nil
33}
34
35func (node *Node) Sign(m []byte) (*core.Signature, error) {
36 return core.Sign(node.PrivK, m)
37}
38
39func (node *Node) SignBlock(block *core.Block) error {
40 block.CalculateHash()
41 sig, err := core.Sign(node.PrivK, block.Hash[:])
42 if err != nil {
43 return err
44 }
45 block.Signature = sig.Bytes()
46 return nil
47}
48
49func (node *Node) AddToPendingTxs(tx core.Tx) {
50 node.PendingTxs = append(node.PendingTxs, tx)
51}
52
53func (node *Node) BlockFromPendingTxs() (*core.Block, error) {
54 block, err := node.NewBlock(node.PendingTxs)
55 if err != nil {
56 return nil, err
57 }
58 block.PrevHash = node.Bc.LastBlock.Hash
59 err = block.CalculatePoW(node.Bc.Difficulty)
60 if err != nil {
61 return nil, err
62 }
63 err = node.SignBlock(block)
64 if err != nil {
65 return nil, err
66 }
67 block.CalculateHash()
68
69 return block, nil
70}
71
72func (node *Node) NewBlock(txs []core.Tx) (*core.Block, error) {
73 block := &core.Block{
74 Height: node.Bc.GetHeight() + 1,
75 PrevHash: node.Bc.LastBlock.Hash,
76 Txs: txs,
77 Miner: core.Address{},
78 MinerPubK: &node.PrivK.PublicKey,
79 Timestamp: time.Now(),
80 Nonce: 0,
81 Hash: core.Hash{},
82 Signature: []byte{},
83 }
84 block.CalculateHash()
85 err := node.SignBlock(block)
86 if err != nil {
87 return nil, err
88 }
89 return block, nil
90}
91
92func (node *Node) CreateGenesis(pubK *ecdsa.PublicKey, amount uint64) (*core.Block, error) {
93 // pubK is the wallet where the first coins will be created
94 // amount is the amount of coins that will be created
95
96 in := core.Input{
97 TxId: core.GenesisHashTxInput,
98 Vout: 0,
99 Value: amount,
100 }
101 var ins []core.Input
102 ins = append(ins, in)
103
104 out := core.Output{
105 Value: amount,
106 }
107 var outs []core.Output
108 outs = append(outs, out)
109
110 tx := core.Tx{
111 From: &ecdsa.PublicKey{},
112 To: pubK,
113 InputCount: uint64(0),
114 Inputs: []core.Input{},
115 Outputs: outs,
116 Signature: []byte{},
117 }
118
119 // calculate TxId
120 // tx.CalculateTxId()
121 tx.TxId = core.GenesisHashTxInput
122 // sign transaction
123
124 var txs []core.Tx
125 txs = append(txs, tx)
126
127 block := &core.Block{
128 Height: node.Bc.LastBlock.Height + 1,
129 PrevHash: node.Bc.LastBlock.Hash,
130 Txs: txs,
131 Miner: node.Addr,
132 MinerPubK: &node.PrivK.PublicKey,
133 Timestamp: time.Now(),
134 Nonce: uint64(0),
135 Hash: core.Hash{},
136 Signature: []byte{},
137 }
138
139 block.CalculateHash()
140 err := node.SignBlock(block)
141 if err != nil {
142 return nil, err
143 }
144 return block, nil
145}