The core protocol of WoopChain
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.
 
 
 
woop/node/node.go

110 lines
3.4 KiB

package node
import (
"harmony-benchmark/blockchain"
"harmony-benchmark/consensus"
"harmony-benchmark/log"
"net"
"os"
"sync"
"strconv"
)
var pendingTxMutex = &sync.Mutex{}
// A node represents a program (machine) participating in the network
type Node struct {
// Consensus object containing all consensus related data (e.g. committee members, signatures, commits)
consensus *consensus.Consensus
// The channel to receive new blocks from Node
BlockChannel chan blockchain.Block
// All the transactions received but not yet processed for consensus
pendingTransactions []*blockchain.Transaction
// The transactions selected into the new block and under consensus process
transactionInConsensus []*blockchain.Transaction
// The blockchain for the shard where this node belongs
blockchain *blockchain.Blockchain
// The corresponding UTXO pool of the current blockchain
UtxoPool *blockchain.UTXOPool
// Log utility
log log.Logger
}
// Add new transactions to the pending transaction list
func (node *Node) addPendingTransactions(newTxs []*blockchain.Transaction) {
pendingTxMutex.Lock()
node.pendingTransactions = append(node.pendingTransactions, newTxs...)
pendingTxMutex.Unlock()
}
// Take out a subset of valid transactions from the pending transaction list
// Note the pending transaction list will then contain the rest of the txs
func (node *Node) getTransactionsForNewBlock() []*blockchain.Transaction {
pendingTxMutex.Lock()
selected, unselected := node.UtxoPool.SelectTransactionsForNewBlock(node.pendingTransactions)
node.pendingTransactions = unselected
pendingTxMutex.Unlock()
return selected
}
// Start a server and process the request by a handler.
func (node *Node) StartServer(port string) {
node.log.Debug("Starting server", "node", node)
node.listenOnPort(port)
}
func (node *Node) listenOnPort(port string) {
listen, err := net.Listen("tcp4", ":"+port)
defer listen.Close()
if err != nil {
node.log.Crit("Socket listen port failed", "port", port, "err", err)
os.Exit(1)
}
for {
conn, err := listen.Accept()
if err != nil {
node.log.Crit("Error listening on port. Exiting.", "port", port)
continue
}
go node.NodeHandler(conn)
}
}
func (node *Node) String() string {
return node.consensus.String()
}
// [Testing code] Should be deleted for production
// Create in genesis block 1000 transactions which assign 1000 token to each address in [1 - 1000]
func (node *Node) AddMoreFakeTransactions() {
txs := make([]*blockchain.Transaction, 1000)
for i := range txs {
txs[i] = blockchain.NewCoinbaseTX(strconv.Itoa(i), "")
}
node.blockchain.Blocks[0].Transactions = append(node.blockchain.Blocks[0].Transactions, txs...)
node.UtxoPool.Update(txs)
}
// Create a new Node
func NewNode(consensus *consensus.Consensus) Node {
node := Node{}
// Consensus and associated channel to communicate blocks
node.consensus = consensus
node.BlockChannel = make(chan blockchain.Block)
// Genesis Block
genesisBlock := &blockchain.Blockchain{}
genesisBlock.Blocks = make([]*blockchain.Block, 0)
coinbaseTx := blockchain.NewCoinbaseTX("harmony", "1")
genesisBlock.Blocks = append(genesisBlock.Blocks, blockchain.NewGenesisBlock(coinbaseTx))
node.blockchain = genesisBlock
// UTXO pool from Genesis block
node.UtxoPool = blockchain.CreateUTXOPoolFromGenesisBlockChain(node.blockchain)
// Logger
node.log = node.consensus.Log
return node
}