You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

154 lines
3.5 KiB

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