|
|
|
@ -10,16 +10,19 @@ import ( |
|
|
|
|
"log" |
|
|
|
|
"net" |
|
|
|
|
"os" |
|
|
|
|
"time" |
|
|
|
|
) |
|
|
|
|
|
|
|
|
|
// A node represents a program (machine) participating in the network
|
|
|
|
|
type Node struct { |
|
|
|
|
consensus *consensus.Consensus |
|
|
|
|
consensus *consensus.Consensus |
|
|
|
|
BlockChannel chan blockchain.Block |
|
|
|
|
pendingTransactions []blockchain.Transaction |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// Start a server and process the request by a handler.
|
|
|
|
|
func (node Node) StartServer(port string) { |
|
|
|
|
func (node *Node) StartServer(port string) { |
|
|
|
|
listenOnPort(port, node.NodeHandler) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
@ -46,7 +49,7 @@ func (node *Node) NodeHandler(conn net.Conn) { |
|
|
|
|
defer conn.Close() |
|
|
|
|
|
|
|
|
|
// Read p2p message payload
|
|
|
|
|
payload, err := p2p.ReadMessageContent(conn) |
|
|
|
|
content, err := p2p.ReadMessageContent(conn) |
|
|
|
|
|
|
|
|
|
consensus := node.consensus |
|
|
|
|
if err != nil { |
|
|
|
@ -58,7 +61,7 @@ func (node *Node) NodeHandler(conn net.Conn) { |
|
|
|
|
return |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
msgCategory, err := message.GetMessageCategory(payload) |
|
|
|
|
msgCategory, err := message.GetMessageCategory(content) |
|
|
|
|
if err != nil { |
|
|
|
|
if consensus.IsLeader { |
|
|
|
|
log.Printf("[Leader] Read node type failed:%s", err) |
|
|
|
@ -68,7 +71,7 @@ func (node *Node) NodeHandler(conn net.Conn) { |
|
|
|
|
return |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
msgType, err := message.GetMessageType(payload) |
|
|
|
|
msgType, err := message.GetMessageType(content) |
|
|
|
|
if err != nil { |
|
|
|
|
if consensus.IsLeader { |
|
|
|
|
log.Printf("[Leader] Read action type failed:%s", err) |
|
|
|
@ -78,7 +81,7 @@ func (node *Node) NodeHandler(conn net.Conn) { |
|
|
|
|
return |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
msgPayload, err := message.GetMessagePayload(payload) |
|
|
|
|
msgPayload, err := message.GetMessagePayload(content) |
|
|
|
|
if err != nil { |
|
|
|
|
if consensus.IsLeader { |
|
|
|
|
log.Printf("[Leader] Read message payload failed:%s", err) |
|
|
|
@ -123,9 +126,34 @@ func (node *Node) NodeHandler(conn net.Conn) { |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
func (node *Node) WaitForConsensusReady(readySignal chan int) { |
|
|
|
|
for { // keep waiting for consensus ready
|
|
|
|
|
<-readySignal |
|
|
|
|
// create a new block
|
|
|
|
|
newBlock := new(blockchain.Block) |
|
|
|
|
for { |
|
|
|
|
if len(node.pendingTransactions) >= 10 { |
|
|
|
|
log.Println("Creating new block") |
|
|
|
|
// TODO (Minh): package actual transactions
|
|
|
|
|
// For now, just take out 10 transactions
|
|
|
|
|
var txList []*blockchain.Transaction |
|
|
|
|
for _, tx := range node.pendingTransactions[0:10] { |
|
|
|
|
txList = append(txList, &tx) |
|
|
|
|
} |
|
|
|
|
node.pendingTransactions = node.pendingTransactions[10:] |
|
|
|
|
newBlock = blockchain.NewBlock(txList, []byte{}) |
|
|
|
|
break |
|
|
|
|
} |
|
|
|
|
time.Sleep(1 * time.Second) // Periodically check whether we have enough transactions to package into block.
|
|
|
|
|
} |
|
|
|
|
node.BlockChannel <- *newBlock |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// Create a new Node
|
|
|
|
|
func NewNode(consensus *consensus.Consensus) Node { |
|
|
|
|
node := Node{} |
|
|
|
|
node.consensus = consensus |
|
|
|
|
node.BlockChannel = make(chan blockchain.Block) |
|
|
|
|
return node |
|
|
|
|
} |
|
|
|
|