From bfaa0fdaef9171081537e75e2a0fbd6846d72c82 Mon Sep 17 00:00:00 2001 From: Rongjian Lan Date: Fri, 14 Dec 2018 00:36:50 -0800 Subject: [PATCH] Add rpc server for beacon chain --- beaconchain/libs/beaconchain.go | 35 ++++ beaconchain/main/main.go | 2 + beaconchain/rpc/client.go | 50 +++++ beaconchain/rpc/proto/beaconchain.pb.go | 247 ++++++++++++++++++++++++ beaconchain/rpc/proto/beaconchain.proto | 22 +++ beaconchain/rpc/server.go | 50 +++++ client/service/client.go | 4 +- client/service/server.go | 2 +- client/wallet/main.go | 35 ++-- 9 files changed, 426 insertions(+), 21 deletions(-) create mode 100644 beaconchain/rpc/client.go create mode 100644 beaconchain/rpc/proto/beaconchain.pb.go create mode 100644 beaconchain/rpc/proto/beaconchain.proto create mode 100644 beaconchain/rpc/server.go diff --git a/beaconchain/libs/beaconchain.go b/beaconchain/libs/beaconchain.go index 172f0d8f9..4463fe14f 100644 --- a/beaconchain/libs/beaconchain.go +++ b/beaconchain/libs/beaconchain.go @@ -1,7 +1,9 @@ package beaconchain import ( + "github.com/harmony-one/harmony/beaconchain/rpc" "math/rand" + "strconv" "sync" "github.com/dedis/kyber" @@ -18,6 +20,9 @@ import ( var mutex sync.Mutex var identityPerBlock = 100000 +// BeaconchainServicePortDiff is the positive port diff from beacon chain's self port +const BeaconchainServicePortDiff = 4444 + // BeaconChain (Blockchain) keeps Identities per epoch, currently centralized! type BeaconChain struct { Leaders []*bcconn.NodeInfo @@ -29,6 +34,34 @@ type BeaconChain struct { IP string Port string host host.Host + + rpcServer *beaconchain.Server +} + +// SupportRPC initializes and starts the rpc service +func (bc *BeaconChain) SupportRPC() { + bc.InitRPCServer() + bc.StartRPCServer() +} + +// InitRPCServer initializes Rpc server. +func (bc *BeaconChain) InitRPCServer() { + bc.rpcServer = beaconchain.NewServer(bc.GetShardLeaderMap) +} + +// StartRPCServer starts Rpc server. +func (bc *BeaconChain) StartRPCServer() { + port, err := strconv.Atoi(bc.Port) + if err != nil { + port = 0 + } + bc.log.Info("support_client: StartRpcServer on port:", "port", strconv.Itoa(port+BeaconchainServicePortDiff)) + bc.rpcServer.Start(bc.IP, strconv.Itoa(port+BeaconchainServicePortDiff)) +} + +// GetShardLeaderMap returns the map from shard id to leader. +func (bc *BeaconChain) GetShardLeaderMap() map[int]*bcconn.NodeInfo { + return bc.ShardLeaderMap } //New beaconchain initialization @@ -38,6 +71,7 @@ func New(numShards int, ip, port string) *BeaconChain { bc.NumberOfShards = numShards bc.PubKey = generateBCKey() bc.NumberOfNodesAdded = 0 + bc.ShardLeaderMap = make(map[int]*bcconn.NodeInfo) bc.Port = port bc.IP = ip bc.host = p2pimpl.NewHost(p2p.Peer{IP: ip, Port: port}) @@ -59,6 +93,7 @@ func (bc *BeaconChain) AcceptConnections(b []byte) { _, isLeader := utils.AllocateShard(bc.NumberOfNodesAdded, bc.NumberOfShards) if isLeader { bc.Leaders = append(bc.Leaders, Node) + bc.ShardLeaderMap[bc.NumberOfNodesAdded-1] = Node } response := bcconn.ResponseRandomNumber{NumberOfShards: bc.NumberOfShards, NumberOfNodesAdded: bc.NumberOfNodesAdded, Leaders: bc.Leaders} msg := bcconn.SerializeRandomInfo(response) diff --git a/beaconchain/main/main.go b/beaconchain/main/main.go index 69f78e3a8..b52227712 100644 --- a/beaconchain/main/main.go +++ b/beaconchain/main/main.go @@ -38,5 +38,7 @@ func main() { log.Root().SetHandler(h) bc := beaconchain.New(*numShards, *ip, *port) + go bc.SupportRPC() + bc.StartServer() } diff --git a/beaconchain/rpc/client.go b/beaconchain/rpc/client.go new file mode 100644 index 000000000..8777fd02f --- /dev/null +++ b/beaconchain/rpc/client.go @@ -0,0 +1,50 @@ +package beaconchain + +import ( + "context" + "fmt" + proto "github.com/harmony-one/harmony/beaconchain/rpc/proto" + "log" + "time" + + "google.golang.org/grpc" +) + +// Client is the client model for beaconchain service. +type Client struct { + beaconChainServiceClient proto.BeaconChainServiceClient + opts []grpc.DialOption + conn *grpc.ClientConn +} + +// NewClient setups a Client given ip and port. +func NewClient(ip, port string) *Client { + client := Client{} + client.opts = append(client.opts, grpc.WithInsecure()) + var err error + client.conn, err = grpc.Dial(fmt.Sprintf("%s:%s", ip, port), client.opts...) + if err != nil { + log.Fatalf("fail to dial: %v", err) + return nil + } + + client.beaconChainServiceClient = proto.NewBeaconChainServiceClient(client.conn) + return &client +} + +// Close closes the Client. +func (client *Client) Close() { + client.conn.Close() +} + +// GetLeaders gets current leaders from beacon chain +func (client *Client) GetLeaders() *proto.FetchLeadersResponse { + ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) + defer cancel() + request := &proto.FetchLeadersRequest{} + response, err := client.beaconChainServiceClient.FetchLeaders(ctx, request) + if err != nil { + log.Fatalf("Error fetching leaders from beacon chain: %s", err) + } + return response +} diff --git a/beaconchain/rpc/proto/beaconchain.pb.go b/beaconchain/rpc/proto/beaconchain.pb.go new file mode 100644 index 000000000..df3fd3c60 --- /dev/null +++ b/beaconchain/rpc/proto/beaconchain.pb.go @@ -0,0 +1,247 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// source: beaconchain.proto + +package beaconchain + +import ( + context "context" + fmt "fmt" + proto "github.com/golang/protobuf/proto" + grpc "google.golang.org/grpc" + math "math" +) + +// Reference imports to suppress errors if they are not otherwise used. +var _ = proto.Marshal +var _ = fmt.Errorf +var _ = math.Inf + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the proto package it is being compiled against. +// A compilation error at this line likely means your copy of the +// proto package needs to be updated. +const _ = proto.ProtoPackageIsVersion3 // please upgrade the proto package + +// FetchLeadersRequest is the request to fetch the current leaders. +type FetchLeadersRequest struct { + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *FetchLeadersRequest) Reset() { *m = FetchLeadersRequest{} } +func (m *FetchLeadersRequest) String() string { return proto.CompactTextString(m) } +func (*FetchLeadersRequest) ProtoMessage() {} +func (*FetchLeadersRequest) Descriptor() ([]byte, []int) { + return fileDescriptor_474fd8061d1037cf, []int{0} +} + +func (m *FetchLeadersRequest) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_FetchLeadersRequest.Unmarshal(m, b) +} +func (m *FetchLeadersRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_FetchLeadersRequest.Marshal(b, m, deterministic) +} +func (m *FetchLeadersRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_FetchLeadersRequest.Merge(m, src) +} +func (m *FetchLeadersRequest) XXX_Size() int { + return xxx_messageInfo_FetchLeadersRequest.Size(m) +} +func (m *FetchLeadersRequest) XXX_DiscardUnknown() { + xxx_messageInfo_FetchLeadersRequest.DiscardUnknown(m) +} + +var xxx_messageInfo_FetchLeadersRequest proto.InternalMessageInfo + +// FetchLeadersResponse is the response of FetchLeadersRequest. +type FetchLeadersResponse struct { + Leaders []*FetchLeadersResponse_Leader `protobuf:"bytes,1,rep,name=leaders,proto3" json:"leaders,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *FetchLeadersResponse) Reset() { *m = FetchLeadersResponse{} } +func (m *FetchLeadersResponse) String() string { return proto.CompactTextString(m) } +func (*FetchLeadersResponse) ProtoMessage() {} +func (*FetchLeadersResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_474fd8061d1037cf, []int{1} +} + +func (m *FetchLeadersResponse) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_FetchLeadersResponse.Unmarshal(m, b) +} +func (m *FetchLeadersResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_FetchLeadersResponse.Marshal(b, m, deterministic) +} +func (m *FetchLeadersResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_FetchLeadersResponse.Merge(m, src) +} +func (m *FetchLeadersResponse) XXX_Size() int { + return xxx_messageInfo_FetchLeadersResponse.Size(m) +} +func (m *FetchLeadersResponse) XXX_DiscardUnknown() { + xxx_messageInfo_FetchLeadersResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_FetchLeadersResponse proto.InternalMessageInfo + +func (m *FetchLeadersResponse) GetLeaders() []*FetchLeadersResponse_Leader { + if m != nil { + return m.Leaders + } + return nil +} + +type FetchLeadersResponse_Leader struct { + Ip string `protobuf:"bytes,1,opt,name=ip,proto3" json:"ip,omitempty"` + Port string `protobuf:"bytes,2,opt,name=port,proto3" json:"port,omitempty"` + ShardId uint32 `protobuf:"varint,3,opt,name=shardId,proto3" json:"shardId,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *FetchLeadersResponse_Leader) Reset() { *m = FetchLeadersResponse_Leader{} } +func (m *FetchLeadersResponse_Leader) String() string { return proto.CompactTextString(m) } +func (*FetchLeadersResponse_Leader) ProtoMessage() {} +func (*FetchLeadersResponse_Leader) Descriptor() ([]byte, []int) { + return fileDescriptor_474fd8061d1037cf, []int{1, 0} +} + +func (m *FetchLeadersResponse_Leader) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_FetchLeadersResponse_Leader.Unmarshal(m, b) +} +func (m *FetchLeadersResponse_Leader) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_FetchLeadersResponse_Leader.Marshal(b, m, deterministic) +} +func (m *FetchLeadersResponse_Leader) XXX_Merge(src proto.Message) { + xxx_messageInfo_FetchLeadersResponse_Leader.Merge(m, src) +} +func (m *FetchLeadersResponse_Leader) XXX_Size() int { + return xxx_messageInfo_FetchLeadersResponse_Leader.Size(m) +} +func (m *FetchLeadersResponse_Leader) XXX_DiscardUnknown() { + xxx_messageInfo_FetchLeadersResponse_Leader.DiscardUnknown(m) +} + +var xxx_messageInfo_FetchLeadersResponse_Leader proto.InternalMessageInfo + +func (m *FetchLeadersResponse_Leader) GetIp() string { + if m != nil { + return m.Ip + } + return "" +} + +func (m *FetchLeadersResponse_Leader) GetPort() string { + if m != nil { + return m.Port + } + return "" +} + +func (m *FetchLeadersResponse_Leader) GetShardId() uint32 { + if m != nil { + return m.ShardId + } + return 0 +} + +func init() { + proto.RegisterType((*FetchLeadersRequest)(nil), "beaconchain.FetchLeadersRequest") + proto.RegisterType((*FetchLeadersResponse)(nil), "beaconchain.FetchLeadersResponse") + proto.RegisterType((*FetchLeadersResponse_Leader)(nil), "beaconchain.FetchLeadersResponse.Leader") +} + +func init() { proto.RegisterFile("beaconchain.proto", fileDescriptor_474fd8061d1037cf) } + +var fileDescriptor_474fd8061d1037cf = []byte{ + // 207 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0x12, 0x4c, 0x4a, 0x4d, 0x4c, + 0xce, 0xcf, 0x4b, 0xce, 0x48, 0xcc, 0xcc, 0xd3, 0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x17, 0xe2, 0x46, + 0x12, 0x52, 0x12, 0xe5, 0x12, 0x76, 0x4b, 0x2d, 0x49, 0xce, 0xf0, 0x49, 0x4d, 0x4c, 0x49, 0x2d, + 0x2a, 0x0e, 0x4a, 0x2d, 0x2c, 0x4d, 0x2d, 0x2e, 0x51, 0x5a, 0xc4, 0xc8, 0x25, 0x82, 0x2a, 0x5e, + 0x5c, 0x90, 0x9f, 0x57, 0x9c, 0x2a, 0xe4, 0xc4, 0xc5, 0x9e, 0x03, 0x11, 0x92, 0x60, 0x54, 0x60, + 0xd6, 0xe0, 0x36, 0xd2, 0xd0, 0x43, 0xb6, 0x01, 0x9b, 0x1e, 0x3d, 0x08, 0x3f, 0x08, 0xa6, 0x51, + 0xca, 0x8d, 0x8b, 0x0d, 0x22, 0x24, 0xc4, 0xc7, 0xc5, 0x94, 0x59, 0x20, 0xc1, 0xa8, 0xc0, 0xa8, + 0xc1, 0x19, 0xc4, 0x94, 0x59, 0x20, 0x24, 0xc4, 0xc5, 0x52, 0x90, 0x5f, 0x54, 0x22, 0xc1, 0x04, + 0x16, 0x01, 0xb3, 0x85, 0x24, 0xb8, 0xd8, 0x8b, 0x33, 0x12, 0x8b, 0x52, 0x3c, 0x53, 0x24, 0x98, + 0x15, 0x18, 0x35, 0x78, 0x83, 0x60, 0x5c, 0xa3, 0x6c, 0x2e, 0x21, 0x27, 0xb0, 0xdd, 0xce, 0x20, + 0xbb, 0x83, 0x53, 0x8b, 0xca, 0x32, 0x93, 0x53, 0x85, 0x42, 0xb9, 0x78, 0x90, 0x5d, 0x21, 0xa4, + 0x80, 0xc7, 0x81, 0x60, 0xcf, 0x4a, 0x29, 0x12, 0xf4, 0x82, 0x12, 0x43, 0x12, 0x1b, 0x38, 0xf0, + 0x8c, 0x01, 0x01, 0x00, 0x00, 0xff, 0xff, 0x27, 0x0b, 0x9f, 0xda, 0x51, 0x01, 0x00, 0x00, +} + +// Reference imports to suppress errors if they are not otherwise used. +var _ context.Context +var _ grpc.ClientConn + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the grpc package it is being compiled against. +const _ = grpc.SupportPackageIsVersion4 + +// BeaconChainServiceClient is the client API for BeaconChainService service. +// +// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream. +type BeaconChainServiceClient interface { + FetchLeaders(ctx context.Context, in *FetchLeadersRequest, opts ...grpc.CallOption) (*FetchLeadersResponse, error) +} + +type beaconChainServiceClient struct { + cc *grpc.ClientConn +} + +func NewBeaconChainServiceClient(cc *grpc.ClientConn) BeaconChainServiceClient { + return &beaconChainServiceClient{cc} +} + +func (c *beaconChainServiceClient) FetchLeaders(ctx context.Context, in *FetchLeadersRequest, opts ...grpc.CallOption) (*FetchLeadersResponse, error) { + out := new(FetchLeadersResponse) + err := c.cc.Invoke(ctx, "/beaconchain.BeaconChainService/FetchLeaders", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +// BeaconChainServiceServer is the server API for BeaconChainService service. +type BeaconChainServiceServer interface { + FetchLeaders(context.Context, *FetchLeadersRequest) (*FetchLeadersResponse, error) +} + +func RegisterBeaconChainServiceServer(s *grpc.Server, srv BeaconChainServiceServer) { + s.RegisterService(&_BeaconChainService_serviceDesc, srv) +} + +func _BeaconChainService_FetchLeaders_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(FetchLeadersRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(BeaconChainServiceServer).FetchLeaders(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/beaconchain.BeaconChainService/FetchLeaders", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(BeaconChainServiceServer).FetchLeaders(ctx, req.(*FetchLeadersRequest)) + } + return interceptor(ctx, in, info, handler) +} + +var _BeaconChainService_serviceDesc = grpc.ServiceDesc{ + ServiceName: "beaconchain.BeaconChainService", + HandlerType: (*BeaconChainServiceServer)(nil), + Methods: []grpc.MethodDesc{ + { + MethodName: "FetchLeaders", + Handler: _BeaconChainService_FetchLeaders_Handler, + }, + }, + Streams: []grpc.StreamDesc{}, + Metadata: "beaconchain.proto", +} diff --git a/beaconchain/rpc/proto/beaconchain.proto b/beaconchain/rpc/proto/beaconchain.proto new file mode 100644 index 000000000..15d7406ab --- /dev/null +++ b/beaconchain/rpc/proto/beaconchain.proto @@ -0,0 +1,22 @@ +syntax = "proto3"; + +package beaconchain; + +// BeaconChainService is the service used for any beacon chain requests. +service BeaconChainService { + rpc FetchLeaders(FetchLeadersRequest) returns (FetchLeadersResponse) {} +} + +// FetchLeadersRequest is the request to fetch the current leaders. +message FetchLeadersRequest { +} + +// FetchLeadersResponse is the response of FetchLeadersRequest. +message FetchLeadersResponse { + message Leader { + string ip = 1; + string port = 2; + uint32 shardId = 3; + } + repeated Leader leaders = 1; +} diff --git a/beaconchain/rpc/server.go b/beaconchain/rpc/server.go new file mode 100644 index 000000000..bead27bc2 --- /dev/null +++ b/beaconchain/rpc/server.go @@ -0,0 +1,50 @@ +package beaconchain + +import ( + "context" + "github.com/harmony-one/harmony/proto/bcconn" + "log" + "net" + + "google.golang.org/grpc" + + proto "github.com/harmony-one/harmony/beaconchain/rpc/proto" +) + +// Server is the Server struct for beacon chain package. +type Server struct { + shardLeaderMap func() map[int]*bcconn.NodeInfo +} + +// FetchLeaders implements the FetchLeaders interface to return current leaders. +func (s *Server) FetchLeaders(ctx context.Context, request *proto.FetchLeadersRequest) (*proto.FetchLeadersResponse, error) { + log.Println("Returning FetchLeadersResponse") + + leaders := []*proto.FetchLeadersResponse_Leader{} + for shardID, leader := range s.shardLeaderMap() { + leaders = append(leaders, &proto.FetchLeadersResponse_Leader{Ip: leader.Self.IP, Port: leader.Self.Port, ShardId: uint32(shardID)}) + } + log.Println(leaders) + return &proto.FetchLeadersResponse{Leaders: leaders}, nil +} + +// Start starts the Server on given ip and port. +func (s *Server) Start(ip, port string) (*grpc.Server, error) { + // TODO(minhdoan): Currently not using ip. Fix it later. + addr := net.JoinHostPort("", port) + lis, err := net.Listen("tcp", addr) + if err != nil { + log.Fatalf("failed to listen: %v", err) + } + var opts []grpc.ServerOption + grpcServer := grpc.NewServer(opts...) + proto.RegisterBeaconChainServiceServer(grpcServer, s) + go grpcServer.Serve(lis) + return grpcServer, nil +} + +// NewServer creates new Server which implements BeaconChainServiceServer interface. +func NewServer(shardLeaderMap func() map[int]*bcconn.NodeInfo) *Server { + s := &Server{shardLeaderMap} + return s +} diff --git a/client/service/client.go b/client/service/client.go index 348beb176..c2b05718d 100644 --- a/client/service/client.go +++ b/client/service/client.go @@ -11,7 +11,7 @@ import ( "google.golang.org/grpc" ) -// Client is the client model for downloader package. +// Client is the client model for client service. type Client struct { clientServiceClient proto.ClientServiceClient opts []grpc.DialOption @@ -38,7 +38,7 @@ func (client *Client) Close() { client.conn.Close() } -// GetBalance gets block hashes from all the peers by calling grpc request. +// GetBalance gets account balance from the client service. func (client *Client) GetBalance(address common.Address) *proto.FetchAccountStateResponse { ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) defer cancel() diff --git a/client/service/server.go b/client/service/server.go index 0a7646e66..412bbe479 100644 --- a/client/service/server.go +++ b/client/service/server.go @@ -12,7 +12,7 @@ import ( proto "github.com/harmony-one/harmony/client/service/proto" ) -// Server is the Server struct for downloader package. +// Server is the Server struct for client service package. type Server struct { stateReader func() (*state.StateDB, error) } diff --git a/client/wallet/main.go b/client/wallet/main.go index c4f914de8..0e1222c25 100644 --- a/client/wallet/main.go +++ b/client/wallet/main.go @@ -10,17 +10,17 @@ import ( "github.com/ethereum/go-ethereum/common" crypto2 "github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/params" + libs "github.com/harmony-one/harmony/beaconchain/libs" + "github.com/harmony-one/harmony/beaconchain/rpc" client2 "github.com/harmony-one/harmony/client/service" "github.com/harmony-one/harmony/core/types" + "github.com/harmony-one/harmony/p2p/p2pimpl" "log" "math/big" "strings" - "github.com/harmony-one/harmony/p2p/p2pimpl" - "github.com/harmony-one/harmony/blockchain" "github.com/harmony-one/harmony/client" - client_config "github.com/harmony-one/harmony/client/config" "github.com/harmony-one/harmony/node" "github.com/harmony-one/harmony/p2p" proto_node "github.com/harmony-one/harmony/proto/node" @@ -46,7 +46,7 @@ func main() { transferCommand := flag.NewFlagSet("transfer", flag.ExitOnError) transferSenderPtr := transferCommand.String("from", "0", "Specify the sender account address or index") transferReceiverPtr := transferCommand.String("to", "", "Specify the receiver account") - transferAmountPtr := transferCommand.Int("amount", 0, "Specify the amount to transfer") + transferAmountPtr := transferCommand.Float64("amount", 0, "Specify the amount to transfer") // Verify that a subcommand has been provided // os.Arg[0] is the main command @@ -114,7 +114,7 @@ func main() { for i, address := range ReadAddresses() { fmt.Printf("Account %d: %s:\n", i, address.Hex()) for shardID, balanceNonce := range FetchBalance(address, walletNode) { - fmt.Printf(" Balance in Shard %d: %.2f \n", shardID, float32(balanceNonce.balance.Uint64()/params.Ether)) + fmt.Printf(" Balance in Shard %d: %.6f \n", shardID, float32(balanceNonce.balance.Uint64())/params.Ether) } } case "transfer": @@ -167,10 +167,11 @@ func main() { walletNode := CreateWalletNode() shardIDToAccountState := FetchBalance(senderAddress, walletNode) - if shardIDToAccountState[0].balance.Uint64()/params.Ether < uint64(amount) { - fmt.Printf("Balance is not enough for the transfer: %d harmony token\n", shardIDToAccountState[0].balance.Uint64()/params.Ether) + if float64(shardIDToAccountState[0].balance.Uint64())/params.Ether < amount { + fmt.Printf("Balance is not enough for the transfer, current balance is %.6f\n", float64(shardIDToAccountState[0].balance.Uint64())/params.Ether) return } + fmt.Println(big.NewInt(int64(amount * params.Ether))) tx, _ := types.SignTx(types.NewTransaction(shardIDToAccountState[0].nonce, receiverAddress, 0, big.NewInt(int64(amount*params.Ether)), params.TxGas, nil, nil), types.HomesteadSigner{}, senderPriKey) SubmitTransaction(tx, walletNode) default: @@ -204,19 +205,17 @@ func getShardIDToLeaderMap() map[uint32]p2p.Peer { // CreateWalletNode creates wallet server node. func CreateWalletNode() *node.Node { - configr := client_config.NewConfig() - var shardIDLeaderMap map[uint32]p2p.Peer - var clientPeer *p2p.Peer - if true { - configr.ReadConfigFile("local_config1.txt") - shardIDLeaderMap = configr.GetShardIDToLeaderMap() - clientPeer = configr.GetClientPeer() - } else { - shardIDLeaderMap = getShardIDToLeaderMap() - clientPeer = &p2p.Peer{Port: "127.0.0.1", IP: "1234"} + shardIDLeaderMap := make(map[uint32]p2p.Peer) + + port, _ := strconv.Atoi("8081") + bcClient := beaconchain.NewClient("127.0.0.1", strconv.Itoa(port+libs.BeaconchainServicePortDiff)) + response := bcClient.GetLeaders() + + for _, leader := range response.Leaders { + shardIDLeaderMap[leader.ShardId] = p2p.Peer{IP: leader.Ip, Port: leader.Port} } - host := p2pimpl.NewHost(*clientPeer) + host := p2pimpl.NewHost(p2p.Peer{}) walletNode := node.New(host, nil, nil) walletNode.Client = client.NewClient(walletNode.GetHost(), &shardIDLeaderMap) return walletNode