diff --git a/agent/main.go b/agent/main.go new file mode 100644 index 000000000..204857d42 --- /dev/null +++ b/agent/main.go @@ -0,0 +1,74 @@ +package main + +import ( + "flag" + "fmt" + "time" + + "github.com/shirou/gopsutil/process" + "github.com/simple-rules/harmony-benchmark/configr" + "github.com/simple-rules/harmony-benchmark/log" +) + +var ( + shardID string + ip string + port string + pid int32 +) + +func logMemUsage() { + p, _ := process.NewProcess(pid) + for { + info, _ := p.MemoryInfo() + memMap, _ := p.MemoryMaps(false) + log.Info("Mem Report", "info", info, "map", memMap, "shardID", shardID) + time.Sleep(3 * time.Second) + } +} + +// TODO: @ricl, start another process for reporting. +func logCPUUsage() { + p, _ := process.NewProcess(pid) + for { + percent, _ := p.CPUPercent() + times, _ := p.Times() + log.Info("CPU Report", "percent", percent, "times", times, "shardID", shardID) + time.Sleep(3 * time.Second) + } +} +func main() { + _ip := flag.String("ip", "127.0.0.1", "IP of the node") + _port := flag.String("port", "9000", "port of the node.") + _pid := flag.Int("pid", 0, "process id of the node") + configFile := flag.String("config_file", "config.txt", "file containing all ip addresses") + logFolder := flag.String("log_folder", "latest", "the folder collecting the logs of this execution") + flag.Parse() + + fmt.Print(*configFile) + ip = *_ip + port = *_port + pid = int32(*_pid) + config, _ := configr.ReadConfigFile(*configFile) + shardID := configr.GetShardID(ip, port, &config) + leader := configr.GetLeader(shardID, &config) + + var role string + if leader.Ip == ip && leader.Port == port { + role = "leader" + } else { + role = "validator" + } + // Setup a logger to stdout and log file. + logFileName := fmt.Sprintf("./%v/agent-%s-%v-%v.log", *logFolder, role, ip, port) + + h := log.MultiHandler( + log.StdoutHandler, + log.Must.FileHandler(logFileName, log.JSONFormat()), // Log to file + // log.Must.NetHandler("tcp", ":3000", log.JSONFormat()) // Log to remote + ) + log.Root().SetHandler(h) + + go logMemUsage() + logCPUUsage() +} diff --git a/benchmark.go b/benchmark.go index 66c9143ec..a7a8fe953 100644 --- a/benchmark.go +++ b/benchmark.go @@ -12,59 +12,14 @@ import ( "github.com/simple-rules/harmony-benchmark/consensus" "github.com/simple-rules/harmony-benchmark/log" "github.com/simple-rules/harmony-benchmark/node" - "github.com/simple-rules/harmony-benchmark/p2p" "github.com/shirou/gopsutil/process" - "github.com/simple-rules/harmony-benchmark/crypto" - "github.com/simple-rules/harmony-benchmark/utils" ) const ( AttackProbability = 20 ) -func getShardId(myIp, myPort string, config *[][]string) string { - for _, node := range *config { - 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 - for _, node := range *config { - ip, port, status, shardId := node[0], node[1], node[2], node[3] - if status == "leader" && myShardId == shardId { - leaderPeer.Ip = ip - leaderPeer.Port = port - - // Get public key deterministically based on ip and port - priKey := crypto.Ed25519Curve.Scalar().SetInt64(int64(utils.GetUniqueIdFromPeer(leaderPeer))) // TODO: figure out why using a random hash value doesn't work for private key (schnorr) - leaderPeer.PubKey = crypto.GetPublicKeyFromScalar(crypto.Ed25519Curve, priKey) - } - } - return leaderPeer -} - -func getPeers(myIp, myPort, myShardId string, config *[][]string) []p2p.Peer { - var peerList []p2p.Peer - for _, node := range *config { - ip, port, status, shardId := node[0], node[1], node[2], node[3] - if status != "validator" || ip == myIp && port == myPort || myShardId != shardId { - continue - } - // Get public key deterministically based on ip and port - peer := p2p.Peer{Port: port, Ip: ip} - priKey := crypto.Ed25519Curve.Scalar().SetInt64(int64(utils.GetUniqueIdFromPeer(peer))) - peer.PubKey = crypto.GetPublicKeyFromScalar(crypto.Ed25519Curve, priKey) - peerList = append(peerList, peer) - } - return peerList -} - func attackDetermination(attackedMode int) bool { switch attackedMode { case 0: @@ -113,9 +68,9 @@ func main() { attack.GetInstance().SetAttackEnabled(attackDetermination(*attackedMode)) config, _ := configr.ReadConfigFile(*configFile) - shardID := getShardId(*ip, *port, &config) - peers := getPeers(*ip, *port, shardID, &config) - leader := getLeader(shardID, &config) + shardID := configr.GetShardID(*ip, *port, &config) + peers := configr.GetPeers(*ip, *port, shardID, &config) + leader := configr.GetLeader(shardID, &config) var role string if leader.Ip == *ip && leader.Port == *port { diff --git a/configr/main.go b/configr/main.go index e383eb7d3..57dbf6172 100644 --- a/configr/main.go +++ b/configr/main.go @@ -7,7 +7,9 @@ import ( "strconv" "strings" + "github.com/simple-rules/harmony-benchmark/crypto" "github.com/simple-rules/harmony-benchmark/p2p" + "github.com/simple-rules/harmony-benchmark/utils" ) // Gets all the validator peers @@ -69,6 +71,51 @@ func GetClientPort(config *[][]string) string { return "" } +// GetShardID Gets the shard id of the node corresponding to this ip and port +func GetShardID(myIp, myPort string, config *[][]string) string { + for _, node := range *config { + ip, port, shardId := node[0], node[1], node[3] + if ip == myIp && port == myPort { + return shardId + } + } + return "N/A" +} + +// GetPeers Gets the peer list of the node corresponding to this ip and port +func GetPeers(myIp, myPort, myShardId string, config *[][]string) []p2p.Peer { + var peerList []p2p.Peer + for _, node := range *config { + ip, port, status, shardId := node[0], node[1], node[2], node[3] + if status != "validator" || ip == myIp && port == myPort || myShardId != shardId { + continue + } + // Get public key deterministically based on ip and port + peer := p2p.Peer{Port: port, Ip: ip} + priKey := crypto.Ed25519Curve.Scalar().SetInt64(int64(utils.GetUniqueIdFromPeer(peer))) + peer.PubKey = crypto.GetPublicKeyFromScalar(crypto.Ed25519Curve, priKey) + peerList = append(peerList, peer) + } + return peerList +} + +// GetLeader Gets the leader of this shard id +func GetLeader(myShardId string, config *[][]string) p2p.Peer { + var leaderPeer p2p.Peer + for _, node := range *config { + ip, port, status, shardId := node[0], node[1], node[2], node[3] + if status == "leader" && myShardId == shardId { + leaderPeer.Ip = ip + leaderPeer.Port = port + + // Get public key deterministically based on ip and port + priKey := crypto.Ed25519Curve.Scalar().SetInt64(int64(utils.GetUniqueIdFromPeer(leaderPeer))) // TODO: figure out why using a random hash value doesn't work for private key (schnorr) + leaderPeer.PubKey = crypto.GetPublicKeyFromScalar(crypto.Ed25519Curve, priKey) + } + } + return leaderPeer +} + // Parse the config file and return a 2d array containing the file data func ReadConfigFile(filename string) ([][]string, error) { file, err := os.Open(filename)