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
 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}