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