Merge branch 'master' into add_generic_utxo

pull/5/merge
Minh Doan 7 years ago
commit 2844d1d55b
  1. 2
      .travis.yml
  2. 2
      README.md
  3. 47
      aws-code/transaction_generator.go
  4. 2
      aws-scripts/parse_json.py
  5. 2
      aws-scripts/run_instances.sh
  6. 60
      benchmark_main.go
  7. 10
      common/message.go
  8. 20
      consensus/consensus.go
  9. 62
      consensus/consensus_leader.go
  10. 34
      consensus/consensus_leader_test.go
  11. 36
      consensus/consensus_test.go
  12. 16
      consensus/consensus_validator.go
  13. 30
      consensus/consensus_validator_test.go
  14. 10
      deploy.sh
  15. 10
      deploy_linux.sh
  16. 101
      local_config.txt
  17. 11
      local_config2.txt
  18. 22
      local_config_shards.txt
  19. 101
      local_iplist.txt
  20. 11
      local_iplist2.txt
  21. 26
      node/message.go
  22. 74
      node/node.go
  23. 1
      p2p/message.go

@ -9,4 +9,4 @@ install: |
cd $HOME/gopath/src/harmony-benchmark cd $HOME/gopath/src/harmony-benchmark
notifications: notifications:
slack: slack:
secure: F6PRLJ7fIVpvZAEAIikE9u53CwklytznkNSJPuzB7cxLttAejls8ou3jsFFUkdTyyyy+QKFP9Bj+IFcAI9dq3CDYp7MnTQx/ajn8TC0xBwKW3gEKYoptIQJkXzvdwp9OanpU78QynRe1oRLefkN8qrL0zWLvoqcaHSYwjh1kzDCbO9G13aiI5CiFdW7jKwBKEPlleze4so0UdAaaGxyXUiSsmvHrOwF72ElnahKLy9DzmIgT8PdQkf1BmV3yaH3VQoU4fyu8t5P/jy8NYIXomcpo+pavgUBfXwd3mPf1KkAoB2RXdGCkORzHNZ6h+63ZVDzi1t8FWAbuNmvJ/Hq07IScGcsjZCEdy+79NSSBHThUejnHnqD4QdcXdhr30PoWBX85+phwPEVehAtddzgLyzivGByKHQMfWcetvPRww7Im+MpJW3OssgHlPxbRCE0uFtSDYgD9UoKevuZzFnME3U1rT9xqTweqOzxdsGRpvU/fLbh0PQCJnDQJjOB054l6ZTu9mtt+ogbYpOhB2PO6qLJZ64cn7M5/wLMiswRWooT9DeN+5a7n5MRo1i/TWFDFWBFYQVWTYdiTaU+oZdSZsu25TMboVraHPw3HE5tKIGgqOBLLd187HbE5ZeR62bzUnlN1wK1tphfgVa4ztmL+NY9nTgHMKki7LiNIL1p7M68= secure: RPB3ThYIGuDUidvaWfOA7Hc9x1bDfd5+Y10r7xwY+NGCN3zW86s/GNLpLutI0MWTV9e2CJupHvz5clp8Ktle/tVjLhs6jHQnNV7U8PTWKkL5By6IFVAHN12unMQn/m0RPwqMfdubajXoV51XhbFA/iow/0fqwsd61VdPIuBrlQjy9z7kyVnRLNoGvYjDqKEkJfYVb3qFNFLzD0F7Y2AgxnezIRjsTLgHzR4owLJYqVMhvTYIV9/vSf1w4UUPzhHyZRESl6bri+a1+g7GxE32OtNwq68xxVeeJcrO/MbjAHHW9V6BW1MjJfYzD5T+7JHIfZOjV2WgzJ7uCkVYztfq+02yOCSWsLNxFVojIDhVFEhhJ6Vd2Zf1otolS7j0svK/qNmShID9q9NAasaI105GsQgtaSPAUGd88J/vyX2ndG1nDOvxmgOo10tZFOnPHW7JnWMybk3PLza8o1ujA7X3JFdvDA8BPP9h6MVP4N7doCQ/n4Crts53HvEWlvcv5sBNu61WYlSTBzf1qNwBKMyN2E0rNubsxKmW8B6jLdWYdlx57nyTRPraNKGE1fnUW5nWRZGax3F1tQRwEfpQMk22qgeUK0RYWsPgHFaPciKCA3dJX7t1k/ib9pyR4nc9SZnYw54KMhkAXPIVQ0iy0EpTAH1DNYV6v8zXCwjl+BdkhlY=

@ -16,7 +16,7 @@ git clone git@github.com:simple-rules/harmony-benchmark.git
## Usage ## Usage
``` ```
./deploy.sh local_iplist.txt ./deploy.sh local_config.txt
./send_txn.sh ./send_txn.sh
``` ```

@ -7,6 +7,7 @@ import (
"harmony-benchmark/blockchain" "harmony-benchmark/blockchain"
"harmony-benchmark/node" "harmony-benchmark/node"
"harmony-benchmark/p2p" "harmony-benchmark/p2p"
"log"
"math/rand" "math/rand"
"os" "os"
"strings" "strings"
@ -22,14 +23,14 @@ func newRandTransaction() blockchain.Transaction {
return tx return tx
} }
func getPeers(Ip, Port, iplist string) []p2p.Peer { func getValidators(config string) []p2p.Peer {
file, _ := os.Open(iplist) file, _ := os.Open(config)
fscanner := bufio.NewScanner(file) fscanner := bufio.NewScanner(file)
var peerList []p2p.Peer var peerList []p2p.Peer
for fscanner.Scan() { for fscanner.Scan() {
p := strings.Split(fscanner.Text(), " ") p := strings.Split(fscanner.Text(), " ")
ip, port, status := p[0], p[1], p[2] ip, port, status := p[0], p[1], p[2]
if status == "leader" || ip == Ip && port == Port { if status == "leader" {
continue continue
} }
peer := p2p.Peer{Port: port, Ip: ip} peer := p2p.Peer{Port: port, Ip: ip}
@ -37,15 +38,39 @@ func getPeers(Ip, Port, iplist string) []p2p.Peer {
} }
return peerList return peerList
} }
func getLeaders(config *[][]string) []p2p.Peer {
var peerList []p2p.Peer
for _, node := range *config {
ip, port, status := node[0], node[1], node[2]
if status == "leader" {
peerList = append(peerList, p2p.Peer{Ip: ip, Port: port})
}
}
return peerList
}
func readConfigFile(configFile string) [][]string {
file, _ := os.Open(configFile)
fscanner := bufio.NewScanner(file)
result := [][]string{}
for fscanner.Scan() {
p := strings.Split(fscanner.Text(), " ")
result = append(result, p)
}
return result
}
func main() { func main() {
configFile := flag.String("config_file", "local_config.txt", "file containing all ip addresses and config")
flag.Parse()
config := readConfigFile(*configFile)
ip := flag.String("ip", "127.0.0.1", "IP of the leader")
port := flag.String("port", "9000", "port of the leader.")
ipfile := flag.String("ipfile", "local_iplist.txt", "file containing all ip addresses")
//getLeader to get ip,port and get totaltime I want to run
start := time.Now() start := time.Now()
totalTime := 60.0 totalTime := 60.0
txs := make([]blockchain.Transaction, 10) txs := make([]blockchain.Transaction, 10)
leaders := getLeaders(&config)
for true { for true {
t := time.Now() t := time.Now()
if t.Sub(start).Seconds() >= totalTime { if t.Sub(start).Seconds() >= totalTime {
@ -57,13 +82,11 @@ func main() {
} }
msg := node.ConstructTransactionListMessage(txs) msg := node.ConstructTransactionListMessage(txs)
p2p.SendMessage(p2p.Peer{*ip, *port, "n/a"}, msg) log.Printf("[Generator] Sending txs to %d leader[s]\n", len(leaders))
p2p.BroadcastMessage(leaders, msg)
time.Sleep(1 * time.Second) // 10 transactions per second time.Sleep(1 * time.Second) // 10 transactions per second
} }
msg := node.ConstructStopMessage() msg := node.ConstructStopMessage()
var leaderPeer p2p.Peer peers := append(getValidators(*configFile), leaders...)
leaderPeer.Ip = *ip
leaderPeer.Port = *port
peers := append(getPeers(*ip, *port, *ipfile), leaderPeer)
p2p.BroadcastMessage(peers, msg) p2p.BroadcastMessage(peers, msg)
} }

@ -9,7 +9,7 @@ def get_public_ip(all_reservations):
all_public_ip_addresses.append(instance_information['PublicIpAddress']) all_public_ip_addresses.append(instance_information['PublicIpAddress'])
return all_public_ip_addresses return all_public_ip_addresses
def make_peers_list(all_reservations,port="9001",filename="ipList.txt"): def make_peers_list(all_reservations,port="9001",filename="config.txt"):
p = get_public_ip(all_reservations) p = get_public_ip(all_reservations)
f = open(filename,"w") f = open(filename,"w")
for i in range(len(p)): for i in range(len(p)):

@ -1,3 +1,3 @@
#!/bin/bash -x #!/bin/bash -x
cd /home/ec2-user/projects/src/harmony-benchmark cd /home/ec2-user/projects/src/harmony-benchmark
./deploy_linux.sh local_iplist2.txt ./deploy_linux.sh local_config2.txt

@ -1,24 +1,31 @@
package main package main
import ( import (
"bufio"
"flag" "flag"
"harmony-benchmark/consensus" "harmony-benchmark/consensus"
"harmony-benchmark/p2p"
"harmony-benchmark/node" "harmony-benchmark/node"
"harmony-benchmark/p2p"
"log" "log"
"os" "os"
"bufio"
"strings" "strings"
) )
func getLeader(iplist string) p2p.Peer { func getShardId(myIp, myPort string, config *[][]string) string {
file, _ := os.Open(iplist) for _, node := range *config {
fscanner := bufio.NewScanner(file) ip, port, shardId := node[0], node[1], node[3]
if ip == myIp && port == myPort {
return shardId
}
}
return "N/A"
}
func getLeader(myShardId string, config *[][]string) p2p.Peer {
var leaderPeer p2p.Peer var leaderPeer p2p.Peer
for fscanner.Scan() { for _, node := range *config {
p := strings.Split(fscanner.Text(), " ") ip, port, status, shardId := node[0], node[1], node[2], node[3]
ip, port, status := p[0], p[1], p[2] if status == "leader" && myShardId == shardId {
if status == "leader" {
leaderPeer.Ip = ip leaderPeer.Ip = ip
leaderPeer.Port = port leaderPeer.Port = port
} }
@ -26,14 +33,11 @@ func getLeader(iplist string) p2p.Peer {
return leaderPeer return leaderPeer
} }
func getPeers(Ip, Port, iplist string) []p2p.Peer { func getPeers(myIp, myPort, myShardId string, config *[][]string) []p2p.Peer {
file, _ := os.Open(iplist)
fscanner := bufio.NewScanner(file)
var peerList []p2p.Peer var peerList []p2p.Peer
for fscanner.Scan() { for _, node := range *config {
p := strings.Split(fscanner.Text(), " ") ip, port, status, shardId := node[0], node[1], node[2], node[3]
ip, port, status := p[0], p[1], p[2] if status == "leader" || ip == myIp && port == myPort || myShardId != shardId {
if status == "leader" || ip == Ip && port == Port {
continue continue
} }
peer := p2p.Peer{Port: port, Ip: ip} peer := p2p.Peer{Port: port, Ip: ip}
@ -42,13 +46,31 @@ func getPeers(Ip, Port, iplist string) []p2p.Peer {
return peerList return peerList
} }
func readConfigFile(configFile string) [][]string {
file, _ := os.Open(configFile)
fscanner := bufio.NewScanner(file)
result := [][]string{}
for fscanner.Scan() {
p := strings.Split(fscanner.Text(), " ")
result = append(result, p)
}
return result
}
func main() { func main() {
ip := flag.String("ip", "127.0.0.1", "IP of the node") ip := flag.String("ip", "127.0.0.1", "IP of the node")
port := flag.String("port", "9000", "port of the node.") port := flag.String("port", "9000", "port of the node.")
ipfile := flag.String("ipfile", "iplist.txt", "file containing all ip addresses") configFile := flag.String("config_file", "config.txt", "file containing all ip addresses")
flag.Parse() flag.Parse()
consensus := consensus.NewConsensus(*ip, *port, getPeers(*ip, *port, *ipfile), getLeader(*ipfile)) config := readConfigFile(*configFile)
shardId := getShardId(*ip, *port, &config)
peers := getPeers(*ip, *port, shardId, &config)
leader := getLeader(shardId, &config)
consensus := consensus.NewConsensus(*ip, *port, shardId, peers, leader)
var nodeStatus string var nodeStatus string
if consensus.IsLeader { if consensus.IsLeader {
nodeStatus = "leader" nodeStatus = "leader"
@ -57,7 +79,7 @@ func main() {
} }
log.Println("======================================") log.Println("======================================")
log.Printf("This node is a %s node listening on ip: %s and port: %s\n", nodeStatus, *ip, *port) log.Printf("This node is a %s node in shard %s listening on ip: %s and port: %s\n", nodeStatus, shardId, *ip, *port)
log.Println("======================================") log.Println("======================================")
node := node.NewNode(&consensus) node := node.NewNode(&consensus)

@ -1,4 +1,4 @@
package message package common
import ( import (
"errors" "errors"
@ -26,7 +26,7 @@ n - 2 bytes - actual message payload
const NODE_TYPE_BYTES = 1 const NODE_TYPE_BYTES = 1
const ACTION_TYPE_BYTES = 1 const ACTION_TYPE_BYTES = 1
// The category of messages // The CATEGORY of messages
type MessageCategory byte type MessageCategory byte
const ( const (
@ -35,7 +35,8 @@ const (
// TODO: add more types // TODO: add more types
) )
// The specific types of message under committee category
// The specific types of message under COMMITTEE category
type CommitteeMessageType byte type CommitteeMessageType byte
const ( const (
@ -43,7 +44,7 @@ const (
// TODO: add more types // TODO: add more types
) )
// The specific types of message under node category // The specific types of message under NODE category
type NodeMessageType byte type NodeMessageType byte
const ( const (
@ -52,6 +53,7 @@ const (
// TODO: add more types // TODO: add more types
) )
// Get the message category from the p2p message content // Get the message category from the p2p message content
func GetMessageCategory(message []byte) (MessageCategory, error) { func GetMessageCategory(message []byte) (MessageCategory, error) {
if len(message) < NODE_TYPE_BYTES { if len(message) < NODE_TYPE_BYTES {

@ -2,11 +2,11 @@
package consensus // consensus package consensus // consensus
import ( import (
"harmony-benchmark/common"
"harmony-benchmark/p2p" "harmony-benchmark/p2p"
"regexp"
"log" "log"
"regexp"
"strconv" "strconv"
"harmony-benchmark/message"
) )
// Consensus data containing all info related to one consensus process // Consensus data containing all info related to one consensus process
@ -31,9 +31,11 @@ type Consensus struct {
// Consensus Id (View Id) - 4 byte // Consensus Id (View Id) - 4 byte
consensusId uint32 consensusId uint32
// Blockhash - 32 byte // Blockhash - 32 byte
blockHash []byte blockHash [32]byte
// BlockHeader to run consensus on // BlockHeader to run consensus on
blockHeader []byte blockHeader []byte
// Shard Id which this node belongs to
ShardId uint32
// Signal channel for starting a new consensus process // Signal channel for starting a new consensus process
ReadySignal chan int ReadySignal chan int
@ -76,7 +78,7 @@ func (state ConsensusState) String() string {
} }
// Create a new Consensus object // Create a new Consensus object
func NewConsensus(ip, port string, peers []p2p.Peer, leader p2p.Peer) Consensus { func NewConsensus(ip, port, shardId string, peers []p2p.Peer, leader p2p.Peer) Consensus {
// The first Ip, port passed will be leader. // The first Ip, port passed will be leader.
consensus := Consensus{} consensus := Consensus{}
peer := p2p.Peer{Port: port, Ip: ip} peer := p2p.Peer{Port: port, Ip: ip}
@ -99,6 +101,11 @@ func NewConsensus(ip, port string, peers []p2p.Peer, leader p2p.Peer) Consensus
log.Fatal(err) log.Fatal(err)
} }
consensus.consensusId = 0 consensus.consensusId = 0
myShardId, err := strconv.Atoi(shardId)
if err != nil {
panic("Unparseable shard Id" + shardId)
}
consensus.ShardId = uint32(myShardId)
// For now use socket address as 16 byte Id // For now use socket address as 16 byte Id
// TODO: populate with correct Id // TODO: populate with correct Id
@ -114,12 +121,11 @@ func NewConsensus(ip, port string, peers []p2p.Peer, leader p2p.Peer) Consensus
}() }()
} }
consensus.msgCategory = byte(message.COMMITTEE) consensus.msgCategory = byte(common.COMMITTEE)
consensus.actionType = byte(message.CONSENSUS) consensus.actionType = byte(common.CONSENSUS)
return consensus return consensus
} }
// Reset the state of the consensus // Reset the state of the consensus
func (consensus *Consensus) ResetState() { func (consensus *Consensus) ResetState() {
consensus.state = READY consensus.state = READY

@ -10,10 +10,13 @@ import (
"fmt" "fmt"
"harmony-benchmark/blockchain" "harmony-benchmark/blockchain"
"harmony-benchmark/p2p" "harmony-benchmark/p2p"
"crypto/sha256"
"strings"
) )
var mutex = &sync.Mutex{} var mutex = &sync.Mutex{}
// WaitForNewBlock waits for a new block.
func (consensus *Consensus) WaitForNewBlock(blockChannel chan blockchain.Block) { func (consensus *Consensus) WaitForNewBlock(blockChannel chan blockchain.Block) {
for { // keep waiting for new blocks for { // keep waiting for new blocks
newBlock := <-blockChannel newBlock := <-blockChannel
@ -24,7 +27,7 @@ func (consensus *Consensus) WaitForNewBlock(blockChannel chan blockchain.Block)
} }
} }
// Leader's consensus message dispatcher // ProcessMessageLeader is the leader's consensus message dispatcher
func (consensus *Consensus) ProcessMessageLeader(message []byte) { func (consensus *Consensus) ProcessMessageLeader(message []byte) {
msgType, err := GetConsensusMessageType(message) msgType, err := GetConsensusMessageType(message)
if err != nil { if err != nil {
@ -36,7 +39,7 @@ func (consensus *Consensus) ProcessMessageLeader(message []byte) {
log.Print(err) log.Print(err)
} }
log.Printf("[Leader] Received and processing message: %s\n", msgType) log.Printf("[Leader-%d] Received and processing message: %s\n", consensus.ShardId, msgType)
switch msgType { switch msgType {
case ANNOUNCE: case ANNOUNCE:
log.Printf("Unexpected message type: %s", msgType) log.Printf("Unexpected message type: %s", msgType)
@ -63,7 +66,7 @@ func (consensus *Consensus) startConsensus(newBlock *blockchain.Block) {
// prepare message and broadcast to validators // prepare message and broadcast to validators
// Construct new block // Construct new block
//newBlock := constructNewBlock() //newBlock := constructNewBlock()
consensus.blockHash = newBlock.Hash copy(newBlock.Hash[:32], consensus.blockHash[:])
msgToSend, err := consensus.constructAnnounceMessage() msgToSend, err := consensus.constructAnnounceMessage()
if err != nil { if err != nil {
@ -87,7 +90,7 @@ func (consensus Consensus) constructAnnounceMessage() ([]byte, error) {
if len(consensus.blockHash) != 32 { if len(consensus.blockHash) != 32 {
return buffer.Bytes(), errors.New(fmt.Sprintf("Block Hash size is %d bytes", len(consensus.blockHash))) return buffer.Bytes(), errors.New(fmt.Sprintf("Block Hash size is %d bytes", len(consensus.blockHash)))
} }
buffer.Write(consensus.blockHash) buffer.Write(consensus.blockHash[:])
// 2 byte leader id // 2 byte leader id
twoBytes := make([]byte, 2) twoBytes := make([]byte, 2)
@ -110,14 +113,9 @@ func (consensus Consensus) constructAnnounceMessage() ([]byte, error) {
return consensus.ConstructConsensusMessage(ANNOUNCE, buffer.Bytes()), nil return consensus.ConstructConsensusMessage(ANNOUNCE, buffer.Bytes()), nil
} }
// TODO: fill in this function // Get the hash of a block's byte stream
func constructNewBlock() []byte { func getBlockHash(block []byte) [32]byte {
return make([]byte, 200) return sha256.Sum256(block)
}
// TODO: fill in this function
func getBlockHash(block []byte) []byte {
return make([]byte, 32)
} }
// TODO: fill in this function // TODO: fill in this function
@ -125,9 +123,10 @@ func getBlockHeader() []byte {
return make([]byte, 200) return make([]byte, 200)
} }
// TODO: fill in this function
func signMessage(message []byte) []byte { func signMessage(message []byte) []byte {
return make([]byte, 64) // TODO: implement real ECC signature
mockSignature := sha256.Sum256(message)
return append(mockSignature[:], mockSignature[:]...)
} }
func (consensus *Consensus) processCommitMessage(payload []byte) { func (consensus *Consensus) processCommitMessage(payload []byte) {
@ -198,7 +197,7 @@ func (consensus Consensus) constructChallengeMessage() []byte {
buffer.Write(fourBytes) buffer.Write(fourBytes)
// 32 byte block hash // 32 byte block hash
buffer.Write(consensus.blockHash) buffer.Write(consensus.blockHash[:])
// 2 byte leader id // 2 byte leader id
twoBytes := make([]byte, 2) twoBytes := make([]byte, 2)
@ -206,10 +205,10 @@ func (consensus Consensus) constructChallengeMessage() []byte {
buffer.Write(twoBytes) buffer.Write(twoBytes)
// 33 byte aggregated commit // 33 byte aggregated commit
buffer.Write(getAggregatedCommit()) buffer.Write(getAggregatedCommit(consensus.commits))
// 33 byte aggregated key // 33 byte aggregated key
buffer.Write(getAggregatedKey()) buffer.Write(getAggregatedKey(consensus.commits))
// 32 byte challenge // 32 byte challenge
buffer.Write(getChallenge()) buffer.Write(getChallenge())
@ -221,18 +220,30 @@ func (consensus Consensus) constructChallengeMessage() []byte {
return consensus.ConstructConsensusMessage(CHALLENGE, buffer.Bytes()) return consensus.ConstructConsensusMessage(CHALLENGE, buffer.Bytes())
} }
// TODO: fill in this function func getAggregatedCommit(commits map[string]string) []byte {
func getAggregatedCommit() []byte { // TODO: implement actual commit aggregation
return make([]byte, 33) var commitArray []string
for _, val := range commits {
commitArray = append(commitArray, val)
}
var commit [32]byte
commit = sha256.Sum256([]byte(strings.Join(commitArray, "")))
return append(commit[:], byte(0))
} }
// TODO: fill in this function func getAggregatedKey(commits map[string]string) []byte {
func getAggregatedKey() []byte { // TODO: implement actual key aggregation
return make([]byte, 33) var commitArray []string
for key := range commits {
commitArray = append(commitArray, key)
}
var commit [32]byte
commit = sha256.Sum256([]byte(strings.Join(commitArray, "")))
return append(commit[:], byte(0))
} }
// TODO: fill in this function
func getChallenge() []byte { func getChallenge() []byte {
// TODO: implement actual challenge data
return make([]byte, 32) return make([]byte, 32)
} }
@ -286,8 +297,9 @@ func (consensus *Consensus) processResponseMessage(payload []byte) {
// Set state to FINISHED // Set state to FINISHED
consensus.state = FINISHED consensus.state = FINISHED
// TODO: do followups on the consensus // TODO: do followups on the consensus
log.Printf("HOORAY!!! CONSENSUS REACHED AMONG %d NODES!!!\n", len(consensus.validators)) log.Printf("[Shard %d] HOORAY!!! CONSENSUS REACHED AMONG %d NODES WITH CONSENSUS ID %d!!!\n", consensus.ShardId, len(consensus.validators), consensus.consensusId)
consensus.ResetState() consensus.ResetState()
consensus.consensusId++
consensus.ReadySignal <- 1 consensus.ReadySignal <- 1
} }
// TODO: composes new block and broadcast the new block to validators // TODO: composes new block and broadcast the new block to validators

@ -0,0 +1,34 @@
package consensus
import (
"harmony-benchmark/p2p"
"testing"
)
func TestConstructAnnounceMessage(test *testing.T) {
header := getBlockHeader()
leader := p2p.Peer{Ip: "1", Port: "2"}
validator := p2p.Peer{Ip: "3", Port: "5"}
consensus := NewConsensus("1", "2", "0", []p2p.Peer{leader, validator}, leader)
consensus.blockHash = getBlockHash(make([]byte, 10))
msg, err := consensus.constructAnnounceMessage()
if err != nil {
test.Error("Annouce message is not constructed successfully")
}
if len(msg) != 1+1+1+4+32+2+4+64+len(header) {
test.Errorf("Annouce message is not constructed in the correct size: %d", len(msg))
}
}
func TestConstructChallengeMessage(test *testing.T) {
leader := p2p.Peer{Ip: "1", Port: "2"}
validator := p2p.Peer{Ip: "3", Port: "5"}
consensus := NewConsensus("1", "2", "0", []p2p.Peer{leader, validator}, leader)
consensus.blockHash = getBlockHash(make([]byte, 10))
msg := consensus.constructChallengeMessage()
if len(msg) != 1+1+1+4+32+2+33+33+32+64 {
test.Errorf("Annouce message is not constructed in the correct size: %d", len(msg))
}
}

@ -0,0 +1,36 @@
package consensus
import (
"harmony-benchmark/common"
"harmony-benchmark/p2p"
"testing"
)
func TestNewConsensus(test *testing.T) {
leader := p2p.Peer{Ip: "1", Port: "2"}
validator := p2p.Peer{Ip: "3", Port: "5"}
consensus := NewConsensus("1", "2", "0", []p2p.Peer{leader, validator}, leader)
if consensus.consensusId != 0 {
test.Errorf("Consensus Id is initialized to the wrong value: %d", consensus.consensusId)
}
if consensus.IsLeader != true {
test.Error("Consensus should belong to a leader")
}
if consensus.ReadySignal == nil {
test.Error("Consensus ReadySignal should be initialized")
}
if consensus.actionType != byte(common.CONSENSUS) {
test.Error("Consensus actionType should be CONSENSUS")
}
if consensus.msgCategory != byte(common.COMMITTEE) {
test.Error("Consensus msgCategory should be COMMITTEE")
}
if consensus.leader != leader {
test.Error("Consensus Leader is set to wrong Peer")
}
}

@ -71,9 +71,12 @@ func (consensus *Consensus) processAnnounceMessage(payload []byte) {
_ = blockHeaderSize _ = blockHeaderSize
_ = signature _ = signature
consensus.blockHash = blockHash copy(blockHash[:32], consensus.blockHash[:])
// verify block data // verify block data
if consensusId != consensus.consensusId {
log.Printf("Received message with consensus Id: %d. My consensus Id: %d\n", consensusId, consensus.consensusId)
return
}
// sign block // sign block
// TODO: return the signature(commit) to leader // TODO: return the signature(commit) to leader
@ -95,7 +98,7 @@ func (consensus Consensus) constructCommitMessage() []byte {
buffer.Write(fourBytes) buffer.Write(fourBytes)
// 32 byte block hash // 32 byte block hash
buffer.Write(consensus.blockHash) buffer.Write(consensus.blockHash[:])
// 2 byte validator id // 2 byte validator id
twoBytes := make([]byte, 2) twoBytes := make([]byte, 2)
@ -160,6 +163,10 @@ func (consensus *Consensus) processChallengeMessage(payload []byte) {
_ = signature _ = signature
// verify block data and the aggregated signatures // verify block data and the aggregated signatures
if consensusId != consensus.consensusId {
log.Printf("Received message with consensus Id: %d. My consensus Id: %d\n", consensusId, consensus.consensusId)
return
}
// sign the message // sign the message
@ -170,6 +177,7 @@ func (consensus *Consensus) processChallengeMessage(payload []byte) {
// Set state to RESPONSE_DONE // Set state to RESPONSE_DONE
consensus.state = RESPONSE_DONE consensus.state = RESPONSE_DONE
consensus.consensusId++
} }
// Construct the response message to send to leader (assumption the consensus data is already verified) // Construct the response message to send to leader (assumption the consensus data is already verified)
@ -182,7 +190,7 @@ func (consensus Consensus) constructResponseMessage() []byte {
buffer.Write(fourBytes) buffer.Write(fourBytes)
// 32 byte block hash // 32 byte block hash
buffer.Write(consensus.blockHash) buffer.Write(consensus.blockHash[:32])
// 2 byte validator id // 2 byte validator id
twoBytes := make([]byte, 2) twoBytes := make([]byte, 2)

@ -0,0 +1,30 @@
package consensus
import (
"harmony-benchmark/p2p"
"testing"
)
func TestConstructCommitMessage(test *testing.T) {
leader := p2p.Peer{Ip: "1", Port: "2"}
validator := p2p.Peer{Ip: "3", Port: "5"}
consensus := NewConsensus("1", "2", "0", []p2p.Peer{leader, validator}, leader)
consensus.blockHash = getBlockHash(make([]byte, 10))
msg := consensus.constructCommitMessage()
if len(msg) != 1+1+1+4+32+2+33+64 {
test.Errorf("Commit message is not constructed in the correct size: %d", len(msg))
}
}
func TestConstructResponseMessage(test *testing.T) {
leader := p2p.Peer{Ip: "1", Port: "2"}
validator := p2p.Peer{Ip: "3", Port: "5"}
consensus := NewConsensus("1", "2", "0", []p2p.Peer{leader, validator}, leader)
consensus.blockHash = getBlockHash(make([]byte, 10))
msg := consensus.constructResponseMessage()
if len(msg) != 1+1+1+4+32+2+32+64 {
test.Errorf("Response message is not constructed in the correct size: %d", len(msg))
}
}

@ -1,9 +1,9 @@
./kill_node.sh ./kill_node.sh
ipfile=$1 config=$1
while IFS='' read -r line || [[ -n "$line" ]]; do while IFS='' read -r line || [[ -n "$line" ]]; do
IFS=' ' read ip port mode <<< $line IFS=' ' read ip port mode <<< $line
#echo $ip $port $mode $ipfile #echo $ip $port $mode $config
go run ./benchmark_main.go -ip $ip -port $port -ipfile $ipfile& go run ./benchmark_main.go -ip $ip -port $port -config_file $config&
done < $ipfile done < $config
go run ./aws-code/transaction_generator.go -ipfile $ipfile go run ./aws-code/transaction_generator.go -config_file $config

@ -14,9 +14,9 @@ echo "Inside deploy linux"
echo $GOPATH echo $GOPATH
echo "Inside deploy linux line 2" echo "Inside deploy linux line 2"
ipfile=$1 config=$1
while read ip port mode; do while read ip port mode; do
#echo $ip $port $mode $ipfile #echo $ip $port $mode $config
go run ./benchmark_main.go -ip $ip -port $port -ipfile $ipfile& go run ./benchmark_main.go -ip $ip -port $port -config_file $config&
done < $ipfile done < $config
go run ./aws-code/transaction_generator.go -ipfile $ipfile go run ./aws-code/transaction_generator.go -config_file $config

@ -0,0 +1,101 @@
127.0.0.1 9001 validator 0
127.0.0.1 9002 validator 0
127.0.0.1 9003 validator 0
127.0.0.1 9004 validator 0
127.0.0.1 9005 validator 0
127.0.0.1 9006 validator 0
127.0.0.1 9007 validator 0
127.0.0.1 9008 validator 0
127.0.0.1 9009 validator 0
127.0.0.1 9010 validator 0
127.0.0.1 9011 validator 0
127.0.0.1 9012 validator 0
127.0.0.1 9013 validator 0
127.0.0.1 9014 validator 0
127.0.0.1 9015 validator 0
127.0.0.1 9016 validator 0
127.0.0.1 9017 validator 0
127.0.0.1 9018 validator 0
127.0.0.1 9019 validator 0
127.0.0.1 9020 validator 0
127.0.0.1 9021 validator 0
127.0.0.1 9022 validator 0
127.0.0.1 9023 validator 0
127.0.0.1 9024 validator 0
127.0.0.1 9025 validator 0
127.0.0.1 9026 validator 0
127.0.0.1 9027 validator 0
127.0.0.1 9028 validator 0
127.0.0.1 9029 validator 0
127.0.0.1 9030 validator 0
127.0.0.1 9031 validator 0
127.0.0.1 9032 validator 0
127.0.0.1 9033 validator 0
127.0.0.1 9034 validator 0
127.0.0.1 9035 validator 0
127.0.0.1 9036 validator 0
127.0.0.1 9037 validator 0
127.0.0.1 9038 validator 0
127.0.0.1 9039 validator 0
127.0.0.1 9040 validator 0
127.0.0.1 9041 validator 0
127.0.0.1 9042 validator 0
127.0.0.1 9043 validator 0
127.0.0.1 9044 validator 0
127.0.0.1 9045 validator 0
127.0.0.1 9046 validator 0
127.0.0.1 9047 validator 0
127.0.0.1 9048 validator 0
127.0.0.1 9049 validator 0
127.0.0.1 9050 validator 0
127.0.0.1 9051 validator 0
127.0.0.1 9052 validator 0
127.0.0.1 9053 validator 0
127.0.0.1 9054 validator 0
127.0.0.1 9055 validator 0
127.0.0.1 9056 validator 0
127.0.0.1 9057 validator 0
127.0.0.1 9058 validator 0
127.0.0.1 9059 validator 0
127.0.0.1 9060 validator 0
127.0.0.1 9061 validator 0
127.0.0.1 9062 validator 0
127.0.0.1 9063 validator 0
127.0.0.1 9064 validator 0
127.0.0.1 9065 validator 0
127.0.0.1 9066 validator 0
127.0.0.1 9067 validator 0
127.0.0.1 9068 validator 0
127.0.0.1 9069 validator 0
127.0.0.1 9070 validator 0
127.0.0.1 9071 validator 0
127.0.0.1 9072 validator 0
127.0.0.1 9073 validator 0
127.0.0.1 9074 validator 0
127.0.0.1 9075 validator 0
127.0.0.1 9076 validator 0
127.0.0.1 9077 validator 0
127.0.0.1 9078 validator 0
127.0.0.1 9079 validator 0
127.0.0.1 9080 validator 0
127.0.0.1 9081 validator 0
127.0.0.1 9082 validator 0
127.0.0.1 9083 validator 0
127.0.0.1 9084 validator 0
127.0.0.1 9085 validator 0
127.0.0.1 9086 validator 0
127.0.0.1 9087 validator 0
127.0.0.1 9088 validator 0
127.0.0.1 9089 validator 0
127.0.0.1 9090 validator 0
127.0.0.1 9091 validator 0
127.0.0.1 9092 validator 0
127.0.0.1 9093 validator 0
127.0.0.1 9094 validator 0
127.0.0.1 9095 validator 0
127.0.0.1 9096 validator 0
127.0.0.1 9097 validator 0
127.0.0.1 9098 validator 0
127.0.0.1 9099 validator 0
127.0.0.1 9100 validator 0
127.0.0.1 9000 leader 0

@ -0,0 +1,11 @@
127.0.0.1 9001 validator 0
127.0.0.1 9002 validator 0
127.0.0.1 9003 validator 0
127.0.0.1 9004 validator 0
127.0.0.1 9005 validator 0
127.0.0.1 9006 validator 0
127.0.0.1 9007 validator 0
127.0.0.1 9008 validator 0
127.0.0.1 9009 validator 0
127.0.0.1 9010 validator 0
127.0.0.1 9000 leader 0

@ -0,0 +1,22 @@
127.0.0.1 9010 validator 0
127.0.0.1 9011 validator 0
127.0.0.1 9012 validator 0
127.0.0.1 9013 validator 0
127.0.0.1 9014 validator 0
127.0.0.1 9015 validator 0
127.0.0.1 9016 validator 0
127.0.0.1 9017 validator 0
127.0.0.1 9018 validator 0
127.0.0.1 9019 validator 0
127.0.0.1 9020 validator 1
127.0.0.1 9021 validator 1
127.0.0.1 9022 validator 1
127.0.0.1 9023 validator 1
127.0.0.1 9024 validator 1
127.0.0.1 9025 validator 1
127.0.0.1 9026 validator 1
127.0.0.1 9027 validator 1
127.0.0.1 9028 validator 1
127.0.0.1 9029 validator 1
127.0.0.1 9000 leader 0
127.0.0.1 9001 leader 1

@ -1,101 +0,0 @@
127.0.0.1 9001 validator
127.0.0.1 9002 validator
127.0.0.1 9003 validator
127.0.0.1 9004 validator
127.0.0.1 9005 validator
127.0.0.1 9006 validator
127.0.0.1 9007 validator
127.0.0.1 9008 validator
127.0.0.1 9009 validator
127.0.0.1 9010 validator
127.0.0.1 9011 validator
127.0.0.1 9012 validator
127.0.0.1 9013 validator
127.0.0.1 9014 validator
127.0.0.1 9015 validator
127.0.0.1 9016 validator
127.0.0.1 9017 validator
127.0.0.1 9018 validator
127.0.0.1 9019 validator
127.0.0.1 9020 validator
127.0.0.1 9021 validator
127.0.0.1 9022 validator
127.0.0.1 9023 validator
127.0.0.1 9024 validator
127.0.0.1 9025 validator
127.0.0.1 9026 validator
127.0.0.1 9027 validator
127.0.0.1 9028 validator
127.0.0.1 9029 validator
127.0.0.1 9030 validator
127.0.0.1 9031 validator
127.0.0.1 9032 validator
127.0.0.1 9033 validator
127.0.0.1 9034 validator
127.0.0.1 9035 validator
127.0.0.1 9036 validator
127.0.0.1 9037 validator
127.0.0.1 9038 validator
127.0.0.1 9039 validator
127.0.0.1 9040 validator
127.0.0.1 9041 validator
127.0.0.1 9042 validator
127.0.0.1 9043 validator
127.0.0.1 9044 validator
127.0.0.1 9045 validator
127.0.0.1 9046 validator
127.0.0.1 9047 validator
127.0.0.1 9048 validator
127.0.0.1 9049 validator
127.0.0.1 9050 validator
127.0.0.1 9051 validator
127.0.0.1 9052 validator
127.0.0.1 9053 validator
127.0.0.1 9054 validator
127.0.0.1 9055 validator
127.0.0.1 9056 validator
127.0.0.1 9057 validator
127.0.0.1 9058 validator
127.0.0.1 9059 validator
127.0.0.1 9060 validator
127.0.0.1 9061 validator
127.0.0.1 9062 validator
127.0.0.1 9063 validator
127.0.0.1 9064 validator
127.0.0.1 9065 validator
127.0.0.1 9066 validator
127.0.0.1 9067 validator
127.0.0.1 9068 validator
127.0.0.1 9069 validator
127.0.0.1 9070 validator
127.0.0.1 9071 validator
127.0.0.1 9072 validator
127.0.0.1 9073 validator
127.0.0.1 9074 validator
127.0.0.1 9075 validator
127.0.0.1 9076 validator
127.0.0.1 9077 validator
127.0.0.1 9078 validator
127.0.0.1 9079 validator
127.0.0.1 9080 validator
127.0.0.1 9081 validator
127.0.0.1 9082 validator
127.0.0.1 9083 validator
127.0.0.1 9084 validator
127.0.0.1 9085 validator
127.0.0.1 9086 validator
127.0.0.1 9087 validator
127.0.0.1 9088 validator
127.0.0.1 9089 validator
127.0.0.1 9090 validator
127.0.0.1 9091 validator
127.0.0.1 9092 validator
127.0.0.1 9093 validator
127.0.0.1 9094 validator
127.0.0.1 9095 validator
127.0.0.1 9096 validator
127.0.0.1 9097 validator
127.0.0.1 9098 validator
127.0.0.1 9099 validator
127.0.0.1 9100 validator
127.0.0.1 9000 leader

@ -1,11 +0,0 @@
127.0.0.1 9001 validator
127.0.0.1 9002 validator
127.0.0.1 9003 validator
127.0.0.1 9004 validator
127.0.0.1 9005 validator
127.0.0.1 9006 validator
127.0.0.1 9007 validator
127.0.0.1 9008 validator
127.0.0.1 9009 validator
127.0.0.1 9010 validator
127.0.0.1 9000 leader

@ -4,35 +4,47 @@ import (
"bytes" "bytes"
"encoding/gob" "encoding/gob"
"harmony-benchmark/blockchain" "harmony-benchmark/blockchain"
"harmony-benchmark/message" "harmony-benchmark/common"
) )
// The types of messages used for NODE/TRANSACTION
type TransactionMessageType int type TransactionMessageType int
const ( const (
SEND TransactionMessageType = iota SEND TransactionMessageType = iota
REQUEST
) )
// The types of messages used for NODE/CONTROL
type ControlMessageType int type ControlMessageType int
const ( const (
STOP ControlMessageType = iota STOP ControlMessageType = iota
) )
//ConstructTransactionListMessage constructs serialized transactions //ConstructTransactionListMessage constructs serialized transactions
func ConstructTransactionListMessage(transactions []blockchain.Transaction) []byte { func ConstructTransactionListMessage(transactions []blockchain.Transaction) []byte {
byteBuffer := bytes.NewBuffer([]byte{byte(message.NODE)}) byteBuffer := bytes.NewBuffer([]byte{byte(common.NODE)})
byteBuffer.WriteByte(byte(message.TRANSACTION)) byteBuffer.WriteByte(byte(common.TRANSACTION))
byteBuffer.WriteByte(byte(SEND)) byteBuffer.WriteByte(byte(SEND))
encoder := gob.NewEncoder(byteBuffer) encoder := gob.NewEncoder(byteBuffer)
encoder.Encode(transactions) encoder.Encode(transactions)
return byteBuffer.Bytes() return byteBuffer.Bytes()
} }
//ConstructTransactionListMessage constructs serialized transactions
func ConstructRequestTransactionsMessage(transactionIds [][]byte) []byte {
byteBuffer := bytes.NewBuffer([]byte{byte(common.NODE)})
byteBuffer.WriteByte(byte(common.TRANSACTION))
byteBuffer.WriteByte(byte(REQUEST))
for _, txId := range transactionIds {
byteBuffer.Write(txId)
}
return byteBuffer.Bytes()
}
//ConstructStopMessage is STOP message //ConstructStopMessage is STOP message
func ConstructStopMessage() []byte { func ConstructStopMessage() []byte {
byteBuffer := bytes.NewBuffer([]byte{byte(message.NODE)}) byteBuffer := bytes.NewBuffer([]byte{byte(common.NODE)})
byteBuffer.WriteByte(byte(message.CONTROL)) byteBuffer.WriteByte(byte(common.CONTROL))
byteBuffer.WriteByte(byte(STOP)) byteBuffer.WriteByte(byte(STOP))
return byteBuffer.Bytes() return byteBuffer.Bytes()
} }

@ -1,16 +1,16 @@
package node package node
import ( import (
"bytes"
"encoding/gob"
"harmony-benchmark/blockchain" "harmony-benchmark/blockchain"
"harmony-benchmark/consensus" "harmony-benchmark/consensus"
"harmony-benchmark/message" "harmony-benchmark/common"
"harmony-benchmark/p2p" "harmony-benchmark/p2p"
"log" "log"
"net" "net"
"os" "os"
"time" "time"
"bytes"
"encoding/gob"
) )
// A node represents a program (machine) participating in the network // A node represents a program (machine) participating in the network
@ -60,7 +60,7 @@ func (node *Node) NodeHandler(conn net.Conn) {
return return
} }
msgCategory, err := message.GetMessageCategory(content) msgCategory, err := common.GetMessageCategory(content)
if err != nil { if err != nil {
if consensus.IsLeader { if consensus.IsLeader {
log.Printf("[Leader] Read node type failed:%s", err) log.Printf("[Leader] Read node type failed:%s", err)
@ -70,7 +70,7 @@ func (node *Node) NodeHandler(conn net.Conn) {
return return
} }
msgType, err := message.GetMessageType(content) msgType, err := common.GetMessageType(content)
if err != nil { if err != nil {
if consensus.IsLeader { if consensus.IsLeader {
log.Printf("[Leader] Read action type failed:%s", err) log.Printf("[Leader] Read action type failed:%s", err)
@ -80,7 +80,7 @@ func (node *Node) NodeHandler(conn net.Conn) {
return return
} }
msgPayload, err := message.GetMessagePayload(content) msgPayload, err := common.GetMessagePayload(content)
if err != nil { if err != nil {
if consensus.IsLeader { if consensus.IsLeader {
log.Printf("[Leader] Read message payload failed:%s", err) log.Printf("[Leader] Read message payload failed:%s", err)
@ -91,20 +91,37 @@ func (node *Node) NodeHandler(conn net.Conn) {
} }
switch msgCategory { switch msgCategory {
case message.COMMITTEE: case common.COMMITTEE:
actionType := message.CommitteeMessageType(msgType) actionType := common.CommitteeMessageType(msgType)
switch actionType { switch actionType {
case message.CONSENSUS: case common.CONSENSUS:
if consensus.IsLeader { if consensus.IsLeader {
consensus.ProcessMessageLeader(msgPayload) consensus.ProcessMessageLeader(msgPayload)
} else { } else {
consensus.ProcessMessageValidator(msgPayload) consensus.ProcessMessageValidator(msgPayload)
} }
} }
case message.NODE: case common.NODE:
actionType := message.NodeMessageType(msgType) actionType := common.NodeMessageType(msgType)
switch actionType { switch actionType {
case message.TRANSACTION: case common.TRANSACTION:
node.transactionMessageHandler(msgPayload)
case common.CONTROL:
controlType := msgPayload[0]
if ControlMessageType(controlType) == STOP {
log.Println("Stopping Node")
os.Exit(0)
}
}
}
}
func (node *Node) transactionMessageHandler(msgPayload []byte) {
txMessageType := TransactionMessageType(msgPayload[0])
switch txMessageType {
case SEND:
txDecoder := gob.NewDecoder(bytes.NewReader(msgPayload[1:])) // skip the SEND messge type txDecoder := gob.NewDecoder(bytes.NewReader(msgPayload[1:])) // skip the SEND messge type
txList := new([]blockchain.Transaction) txList := new([]blockchain.Transaction)
@ -113,16 +130,37 @@ func (node *Node) NodeHandler(conn net.Conn) {
log.Println("Failed deserializing transaction list") log.Println("Failed deserializing transaction list")
} }
node.pendingTransactions = append(node.pendingTransactions, *txList...) node.pendingTransactions = append(node.pendingTransactions, *txList...)
log.Println(len(node.pendingTransactions)) case REQUEST:
case message.CONTROL: reader := bytes.NewBuffer(msgPayload[1:])
controlType := msgPayload[0] var txIds map[[32]byte]bool
if ControlMessageType(controlType) == STOP { txId := make([]byte, 32) // 32 byte hash Id
log.Println("Stopping Node") for {
os.Exit(0) _, err := reader.Read(txId)
if err != nil {
break
} }
txIds[getFixedByteTxId(txId)] = true
} }
var txToReturn []blockchain.Transaction
for _, tx := range node.pendingTransactions {
if txIds[getFixedByteTxId(tx.ID)] {
txToReturn = append(txToReturn, tx)
}
}
// TODO: return the transaction list to requester
}
}
// Copy the txId byte slice over to 32 byte array so the map can key on it
func getFixedByteTxId(txId []byte) [32]byte {
var id [32]byte
for i := range id {
id[i] = txId[i]
} }
return id
} }
func (node *Node) WaitForConsensusReady(readySignal chan int) { func (node *Node) WaitForConsensusReady(readySignal chan int) {

@ -48,7 +48,6 @@ func ReadMessageContent(conn net.Conn) ([]byte, error) {
} }
// TODO: check on msgType and take actions accordingly // TODO: check on msgType and take actions accordingly
//// Read 4 bytes for message size //// Read 4 bytes for message size
fourBytes := make([]byte, 4) fourBytes := make([]byte, 4)
n, err := r.Read(fourBytes) n, err := r.Read(fourBytes)

Loading…
Cancel
Save