[HAR-49] Create grpc service for client wallet and implement basic balance check

[HAR-49] Create grpc service for client wallet and implement basic balance check
pull/149/head
Rongjian Lan 6 years ago committed by GitHub
commit 83eba88395
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 3
      benchmark.go
  2. 52
      client/service/client.go
  3. 208
      client/service/proto/client.pb.go
  4. 22
      client/service/proto/client.proto
  5. 52
      client/service/server.go
  6. 159
      client/wallet/main.go
  7. 5
      deploy.sh
  8. 37
      node/node.go

@ -226,5 +226,8 @@ func main() {
}
go currentNode.SupportSyncing()
if consensus.IsLeader {
go currentNode.SupportClient()
}
currentNode.StartServer()
}

@ -0,0 +1,52 @@
package client
import (
"context"
"fmt"
"github.com/ethereum/go-ethereum/common"
proto "github.com/harmony-one/harmony/client/service/proto"
"log"
"time"
"google.golang.org/grpc"
)
// Client is the client model for downloader package.
type Client struct {
clientServiceClient proto.ClientServiceClient
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.clientServiceClient = proto.NewClientServiceClient(client.conn)
return &client
}
// Close closes the Client.
func (client *Client) Close() {
client.conn.Close()
}
// GetBalance gets block hashes from all the peers by calling grpc request.
func (client *Client) GetBalance(address common.Address) *proto.FetchAccountStateResponse {
log.Println("Getting balance from address: ", address.Hex())
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
defer cancel()
request := &proto.FetchAccountStateRequest{Address: address.Bytes()}
response, err := client.clientServiceClient.FetchAccountState(ctx, request)
if err != nil {
log.Fatalf("Error getting balance: %s", err)
}
return response
}

@ -0,0 +1,208 @@
// Code generated by protoc-gen-go. DO NOT EDIT.
// source: client.proto
package client
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
// FetchAccountStateRequest is the request to fetch an account's balance and nonce.
type FetchAccountStateRequest struct {
// The account address
Address []byte `protobuf:"bytes,1,opt,name=address,proto3" json:"address,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
func (m *FetchAccountStateRequest) Reset() { *m = FetchAccountStateRequest{} }
func (m *FetchAccountStateRequest) String() string { return proto.CompactTextString(m) }
func (*FetchAccountStateRequest) ProtoMessage() {}
func (*FetchAccountStateRequest) Descriptor() ([]byte, []int) {
return fileDescriptor_014de31d7ac8c57c, []int{0}
}
func (m *FetchAccountStateRequest) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_FetchAccountStateRequest.Unmarshal(m, b)
}
func (m *FetchAccountStateRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
return xxx_messageInfo_FetchAccountStateRequest.Marshal(b, m, deterministic)
}
func (m *FetchAccountStateRequest) XXX_Merge(src proto.Message) {
xxx_messageInfo_FetchAccountStateRequest.Merge(m, src)
}
func (m *FetchAccountStateRequest) XXX_Size() int {
return xxx_messageInfo_FetchAccountStateRequest.Size(m)
}
func (m *FetchAccountStateRequest) XXX_DiscardUnknown() {
xxx_messageInfo_FetchAccountStateRequest.DiscardUnknown(m)
}
var xxx_messageInfo_FetchAccountStateRequest proto.InternalMessageInfo
func (m *FetchAccountStateRequest) GetAddress() []byte {
if m != nil {
return m.Address
}
return nil
}
// FetchAccountStateResponse is the response of FetchAccountStateRequest.
type FetchAccountStateResponse struct {
// The balance of the account (big.Int)
Balance []byte `protobuf:"bytes,1,opt,name=balance,proto3" json:"balance,omitempty"`
// The nonce of the account
Nonce uint64 `protobuf:"varint,2,opt,name=nonce,proto3" json:"nonce,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
func (m *FetchAccountStateResponse) Reset() { *m = FetchAccountStateResponse{} }
func (m *FetchAccountStateResponse) String() string { return proto.CompactTextString(m) }
func (*FetchAccountStateResponse) ProtoMessage() {}
func (*FetchAccountStateResponse) Descriptor() ([]byte, []int) {
return fileDescriptor_014de31d7ac8c57c, []int{1}
}
func (m *FetchAccountStateResponse) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_FetchAccountStateResponse.Unmarshal(m, b)
}
func (m *FetchAccountStateResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
return xxx_messageInfo_FetchAccountStateResponse.Marshal(b, m, deterministic)
}
func (m *FetchAccountStateResponse) XXX_Merge(src proto.Message) {
xxx_messageInfo_FetchAccountStateResponse.Merge(m, src)
}
func (m *FetchAccountStateResponse) XXX_Size() int {
return xxx_messageInfo_FetchAccountStateResponse.Size(m)
}
func (m *FetchAccountStateResponse) XXX_DiscardUnknown() {
xxx_messageInfo_FetchAccountStateResponse.DiscardUnknown(m)
}
var xxx_messageInfo_FetchAccountStateResponse proto.InternalMessageInfo
func (m *FetchAccountStateResponse) GetBalance() []byte {
if m != nil {
return m.Balance
}
return nil
}
func (m *FetchAccountStateResponse) GetNonce() uint64 {
if m != nil {
return m.Nonce
}
return 0
}
func init() {
proto.RegisterType((*FetchAccountStateRequest)(nil), "client.FetchAccountStateRequest")
proto.RegisterType((*FetchAccountStateResponse)(nil), "client.FetchAccountStateResponse")
}
func init() { proto.RegisterFile("client.proto", fileDescriptor_014de31d7ac8c57c) }
var fileDescriptor_014de31d7ac8c57c = []byte{
// 172 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0xe2, 0x49, 0xce, 0xc9, 0x4c,
0xcd, 0x2b, 0xd1, 0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x17, 0x62, 0x83, 0xf0, 0x94, 0x4c, 0xb8, 0x24,
0xdc, 0x52, 0x4b, 0x92, 0x33, 0x1c, 0x93, 0x93, 0xf3, 0x4b, 0xf3, 0x4a, 0x82, 0x4b, 0x12, 0x4b,
0x52, 0x83, 0x52, 0x0b, 0x4b, 0x53, 0x8b, 0x4b, 0x84, 0x24, 0xb8, 0xd8, 0x13, 0x53, 0x52, 0x8a,
0x52, 0x8b, 0x8b, 0x25, 0x18, 0x15, 0x18, 0x35, 0x78, 0x82, 0x60, 0x5c, 0x25, 0x6f, 0x2e, 0x49,
0x2c, 0xba, 0x8a, 0x0b, 0xf2, 0xf3, 0x8a, 0x53, 0x41, 0xda, 0x92, 0x12, 0x73, 0x12, 0xf3, 0x92,
0x53, 0x61, 0xda, 0xa0, 0x5c, 0x21, 0x11, 0x2e, 0xd6, 0xbc, 0x7c, 0x90, 0x38, 0x93, 0x02, 0xa3,
0x06, 0x4b, 0x10, 0x84, 0x63, 0x94, 0xcd, 0xc5, 0xeb, 0x0c, 0x76, 0x4c, 0x70, 0x6a, 0x51, 0x59,
0x66, 0x72, 0xaa, 0x50, 0x14, 0x97, 0x20, 0x86, 0xe9, 0x42, 0x0a, 0x7a, 0x50, 0xf7, 0xe3, 0x72,
0xae, 0x94, 0x22, 0x1e, 0x15, 0x10, 0xa7, 0x29, 0x31, 0x24, 0xb1, 0x81, 0xbd, 0x6f, 0x0c, 0x08,
0x00, 0x00, 0xff, 0xff, 0x2a, 0x07, 0xa9, 0xb6, 0x0e, 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
// ClientServiceClient is the client API for ClientService service.
//
// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream.
type ClientServiceClient interface {
FetchAccountState(ctx context.Context, in *FetchAccountStateRequest, opts ...grpc.CallOption) (*FetchAccountStateResponse, error)
}
type clientServiceClient struct {
cc *grpc.ClientConn
}
func NewClientServiceClient(cc *grpc.ClientConn) ClientServiceClient {
return &clientServiceClient{cc}
}
func (c *clientServiceClient) FetchAccountState(ctx context.Context, in *FetchAccountStateRequest, opts ...grpc.CallOption) (*FetchAccountStateResponse, error) {
out := new(FetchAccountStateResponse)
err := c.cc.Invoke(ctx, "/client.ClientService/FetchAccountState", in, out, opts...)
if err != nil {
return nil, err
}
return out, nil
}
// ClientServiceServer is the server API for ClientService service.
type ClientServiceServer interface {
FetchAccountState(context.Context, *FetchAccountStateRequest) (*FetchAccountStateResponse, error)
}
func RegisterClientServiceServer(s *grpc.Server, srv ClientServiceServer) {
s.RegisterService(&_ClientService_serviceDesc, srv)
}
func _ClientService_FetchAccountState_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(FetchAccountStateRequest)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(ClientServiceServer).FetchAccountState(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: "/client.ClientService/FetchAccountState",
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(ClientServiceServer).FetchAccountState(ctx, req.(*FetchAccountStateRequest))
}
return interceptor(ctx, in, info, handler)
}
var _ClientService_serviceDesc = grpc.ServiceDesc{
ServiceName: "client.ClientService",
HandlerType: (*ClientServiceServer)(nil),
Methods: []grpc.MethodDesc{
{
MethodName: "FetchAccountState",
Handler: _ClientService_FetchAccountState_Handler,
},
},
Streams: []grpc.StreamDesc{},
Metadata: "client.proto",
}

@ -0,0 +1,22 @@
syntax = "proto3";
package client;
// Client is the service used for any client-facing requests.
service ClientService {
rpc FetchAccountState(FetchAccountStateRequest) returns (FetchAccountStateResponse) {}
}
// FetchAccountStateRequest is the request to fetch an account's balance and nonce.
message FetchAccountStateRequest {
// The account address
bytes address = 1;
}
// FetchAccountStateResponse is the response of FetchAccountStateRequest.
message FetchAccountStateResponse {
// The balance of the account (big.Int)
bytes balance = 1;
// The nonce of the account
uint64 nonce = 2;
}

@ -0,0 +1,52 @@
package client
import (
"context"
"github.com/ethereum/go-ethereum/common"
"github.com/harmony-one/harmony/core/state"
"log"
"net"
"google.golang.org/grpc"
proto "github.com/harmony-one/harmony/client/service/proto"
)
// Constants for downloader server.
const (
DefaultDownloadPort = "6666"
)
// Server is the Server struct for downloader package.
type Server struct {
state *state.StateDB
}
// FetchAccountState implements the FetchAccountState interface to return account state.
func (s *Server) FetchAccountState(ctx context.Context, request *proto.FetchAccountStateRequest) (*proto.FetchAccountStateResponse, error) {
var address common.Address
address.SetBytes(request.Address)
log.Println("Returning FetchAccountStateResponse for address: ", address.Hex())
return &proto.FetchAccountStateResponse{Balance: s.state.GetBalance(address).Bytes(), Nonce: s.state.GetNonce(address)}, 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.RegisterClientServiceServer(grpcServer, s)
go grpcServer.Serve(lis)
return grpcServer, nil
}
// NewServer creates new Server which implements ClientServiceServer interface.
func NewServer(state *state.StateDB) *Server {
s := &Server{state}
return s
}

@ -1,24 +1,22 @@
package main
import (
"crypto/ecdsa"
"crypto/rand"
"encoding/hex"
"errors"
"flag"
"fmt"
"github.com/ethereum/go-ethereum/common"
crypto2 "github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum/go-ethereum/params"
client2 "github.com/harmony-one/harmony/client/service"
"log"
"math/big"
"strings"
"github.com/harmony-one/harmony/p2p/p2pimpl"
"io"
"io/ioutil"
math_rand "math/rand"
"os"
"strconv"
"time"
"github.com/dedis/kyber"
"github.com/harmony-one/harmony/blockchain"
"github.com/harmony-one/harmony/client"
client_config "github.com/harmony-one/harmony/client/config"
@ -27,7 +25,11 @@ import (
"github.com/harmony-one/harmony/node"
"github.com/harmony-one/harmony/p2p"
proto_node "github.com/harmony-one/harmony/proto/node"
"github.com/harmony-one/harmony/utils"
"io"
"io/ioutil"
"os"
"strconv"
"time"
)
func main() {
@ -72,7 +74,7 @@ func main() {
fmt.Printf("New account created:\nAddress: {%x}\n", address)
case "list":
for i, address := range ReadAddresses() {
fmt.Printf("Account %d:\n {%x}\n", i+1, address)
fmt.Printf("Account %d:\n {%s}\n", i+1, address.Hex())
}
case "clearAll":
ClearKeystore()
@ -95,13 +97,11 @@ func main() {
fmt.Println("Private key imported...")
case "showBalance":
walletNode := CreateWalletServerNode()
go walletNode.StartServer()
shardUtxoMap, err := FetchUtxos(ReadAddresses(), walletNode)
if err != nil {
fmt.Println(err)
for _, address := range ReadAddresses() {
fmt.Printf("Account %s:\n %d ether \n", address.Hex(), FetchBalance(address, walletNode).Uint64()/params.Ether)
}
PrintUtxoBalance(shardUtxoMap)
case "test":
// Testing code
priKey := pki.GetPrivateKeyScalarFromInt(444)
@ -161,62 +161,9 @@ func main() {
copy(trimmedReceiverAddress[:], receiverAddress[:20])
senderPriKey := priKeys[senderIndex]
senderAddressBytes := pki.GetAddressFromPrivateKey(senderPriKey)
// Start client server
walletNode := CreateWalletServerNode()
go walletNode.StartServer()
shardUtxoMap, err := FetchUtxos([][20]byte{senderAddressBytes}, walletNode)
if err != nil {
fmt.Printf("Failed to fetch utxos: %s\n", err)
}
cummulativeBalance := 0
txInputs := []blockchain.TXInput{}
LOOP:
for shardID, utxoMap := range shardUtxoMap {
for txID, vout2AmountMap := range utxoMap[senderAddressBytes] {
txIDBytes, err := utils.Get32BytesFromString(txID)
if err != nil {
fmt.Println("Failed to parse txID")
continue
}
for voutIndex, utxoAmount := range vout2AmountMap {
cummulativeBalance += utxoAmount
txIn := blockchain.NewTXInput(blockchain.NewOutPoint(&txIDBytes, voutIndex), senderAddressBytes, shardID)
txInputs = append(txInputs, *txIn)
if cummulativeBalance >= amount {
break LOOP
}
}
}
}
txout := blockchain.TXOutput{Amount: amount, Address: trimmedReceiverAddress, ShardID: uint32(math_rand.Intn(len(shardUtxoMap)))}
txOutputs := []blockchain.TXOutput{txout}
if cummulativeBalance > amount {
changeTxOut := blockchain.TXOutput{Amount: cummulativeBalance - amount, Address: senderAddressBytes, ShardID: uint32(math_rand.Intn(len(shardUtxoMap)))}
txOutputs = append(txOutputs, changeTxOut)
}
tx := blockchain.Transaction{ID: [32]byte{}, PublicKey: pki.GetBytesFromPublicKey(pki.GetPublicKeyFromScalar(senderPriKey)), TxInput: txInputs, TxOutput: txOutputs, Proofs: nil}
tx.SetID() // TODO(RJ): figure out the correct way to set Tx ID.
tx.Sign(senderPriKey)
_ = senderPriKey
pubKey := crypto.Ed25519Curve.Point()
err = pubKey.UnmarshalBinary(tx.PublicKey[:])
if err != nil {
fmt.Println("Failed to deserialize public key", "error", err)
}
err = ExecuteTransaction(tx, walletNode)
if err != nil {
fmt.Println(err)
} else {
fmt.Println("Transaction submitted successfully")
}
// TODO: implement account transaction logic
default:
flag.PrintDefaults()
os.Exit(1)
@ -252,7 +199,7 @@ func CreateWalletServerNode() *node.Node {
var shardIDLeaderMap map[uint32]p2p.Peer
var clientPeer *p2p.Peer
if true {
configr.ReadConfigFile("local_config2.txt")
configr.ReadConfigFile("local_config1.txt")
shardIDLeaderMap = configr.GetShardIDToLeaderMap()
clientPeer = configr.GetClientPeer()
} else {
@ -295,6 +242,24 @@ func ExecuteTransaction(tx blockchain.Transaction, walletNode *node.Node) error
}
}
// FetchBalance fetches account balance of specified address from the Harmony network
func FetchBalance(address common.Address, walletNode *node.Node) *big.Int {
fmt.Println("Fetching account balance...")
clients := []*client2.Client{}
for _, leader := range *walletNode.Client.Leaders {
clients = append(clients, client2.NewClient(leader.IP, "1841"))
}
balance := big.NewInt(0)
for _, client := range clients {
response := client.GetBalance(address)
theirBalance := big.NewInt(0)
theirBalance.SetBytes(response.Balance)
balance.Add(balance, theirBalance)
}
return balance
}
// FetchUtxos fetches utxos of specified address from the Harmony network
func FetchUtxos(addresses [][20]byte, walletNode *node.Node) (map[uint32]blockchain.UtxoMap, error) {
fmt.Println("Fetching account balance...")
@ -319,43 +284,24 @@ func FetchUtxos(addresses [][20]byte, walletNode *node.Node) (map[uint32]blockch
}
}
// PrintUtxoBalance prints utxo balance.
func PrintUtxoBalance(shardUtxoMap map[uint32]blockchain.UtxoMap) {
addressBalance := make(map[[20]byte]int)
for _, utxoMap := range shardUtxoMap {
for address, txHash2Vout2AmountMap := range utxoMap {
for _, vout2AmountMap := range txHash2Vout2AmountMap {
for _, amount := range vout2AmountMap {
value, ok := addressBalance[address]
if ok {
addressBalance[address] = value + amount
} else {
addressBalance[address] = amount
}
}
}
}
}
for address, balance := range addressBalance {
fmt.Printf("Address: {%x}\n", address)
fmt.Printf("Balance: %d\n", balance)
}
}
// ReadAddresses reads the addresses stored in local keystore
func ReadAddresses() [][20]byte {
func ReadAddresses() []common.Address {
priKeys := ReadPrivateKeys()
addresses := [][20]byte{}
addresses := []common.Address{}
for _, key := range priKeys {
addresses = append(addresses, pki.GetAddressFromPrivateKey(key))
addresses = append(addresses, crypto2.PubkeyToAddress(key.PublicKey))
}
return addresses
}
// StorePrivateKey stores the specified private key in local keystore
func StorePrivateKey(priKey []byte) {
privateKey, err := crypto2.ToECDSA(priKey)
if err != nil {
panic("Failed to deserialize private key")
}
for _, address := range ReadAddresses() {
if address == pki.GetAddressFromPrivateKey(crypto.Ed25519Curve.Scalar().SetBytes(priKey)) {
if address == crypto2.PubkeyToAddress(privateKey.PublicKey) {
fmt.Println("The key already exists in the keystore")
return
}
@ -379,16 +325,19 @@ func ClearKeystore() {
}
// ReadPrivateKeys reads all the private key stored in local keystore
func ReadPrivateKeys() []kyber.Scalar {
func ReadPrivateKeys() []*ecdsa.PrivateKey {
keys, err := ioutil.ReadFile("keystore")
if err != nil {
return []kyber.Scalar{}
return []*ecdsa.PrivateKey{}
}
keyScalars := []kyber.Scalar{}
priKeys := []*ecdsa.PrivateKey{}
for i := 0; i < len(keys); i += 32 {
priKey := crypto.Ed25519Curve.Scalar()
priKey.UnmarshalBinary(keys[i : i+32])
keyScalars = append(keyScalars, priKey)
priKey, err := crypto2.ToECDSA(keys[i : i+32])
if err != nil {
fmt.Println("Failed deserializing key data: ", keys[i:i+32])
continue
}
priKeys = append(priKeys, priKey)
}
return keyScalars
return priKeys
}

@ -62,7 +62,7 @@ while getopts "hpdtD:m:s:k:" option; do
h) usage ;;
p) PEER='-peer_discovery' ;;
d) DB='-db_supported' ;;
t) TXGEN=false ;;
t) TXGEN=$OPTARG ;;
D) DURATION=$OPTARG ;;
m) MIN=$OPTARG ;;
s) SHARDS=$OPTARG ;;
@ -120,8 +120,9 @@ done < $config
# Emulate node offline
(sleep 45; killnode $KILLPORT) &
echo "launching txgen ..."
echo "launching txgen ..."Z
if [ "$TXGEN" == "true" ]; then
echo "launching txgen ..."
if [ -z "$PEER" ]; then
./bin/txgen -config_file $config -log_folder $log_folder -duration $DURATION
else

@ -5,6 +5,8 @@ import (
"crypto/ecdsa"
"encoding/gob"
"fmt"
"github.com/harmony-one/harmony/client"
clientService "github.com/harmony-one/harmony/client/service"
"math/big"
"math/rand"
"os"
@ -18,7 +20,6 @@ import (
"github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum/go-ethereum/params"
"github.com/harmony-one/harmony/blockchain"
"github.com/harmony-one/harmony/client"
bft "github.com/harmony-one/harmony/consensus"
"github.com/harmony-one/harmony/core"
"github.com/harmony-one/harmony/core/types"
@ -79,6 +80,7 @@ const (
syncingPortDifference = 3000
waitBeforeJoinShard = time.Second * 3
timeOutToJoinShard = time.Minute * 10
clientServicePort = "1841"
)
// NetworkNode ...
@ -119,6 +121,9 @@ type Node struct {
BlockChannelAccount chan *types.Block // The channel to receive new blocks from Node
Worker *worker.Worker
// Client server (for wallet requests)
clientServer *clientService.Server
// Syncing component.
downloaderServer *downloader.Server
stateSync *syncing.StateSync
@ -272,6 +277,9 @@ func New(host host.Host, consensus *bft.Consensus, db *hdb.LDBDatabase) *Node {
node.SelfPeer = host.GetSelfPeer()
}
// Logger
node.log = log.New()
if host != nil && consensus != nil {
// Consensus and associated channel to communicate blocks
node.Consensus = consensus
@ -305,6 +313,8 @@ func New(host host.Host, consensus *bft.Consensus, db *hdb.LDBDatabase) *Node {
testBankKey, _ := ecdsa.GenerateKey(crypto.S256(), reader)
testBankAddress := crypto.PubkeyToAddress(testBankKey.PublicKey)
testBankFunds := big.NewInt(8000000000000000000)
//fmt.Println(crypto.PubkeyToAddress(testBankKey.PublicKey).Hex())
//fmt.Println(hex.EncodeToString(crypto.FromECDSA(testBankKey)))
genesisAloc[testBankAddress] = core.GenesisAccount{Balance: testBankFunds}
node.TestBankKeys = append(node.TestBankKeys, testBankKey)
}
@ -335,9 +345,7 @@ func New(host host.Host, consensus *bft.Consensus, db *hdb.LDBDatabase) *Node {
node.AddSmartContractsToPendingTransactions()
}
// Logger
node.log = log.New()
if consensus.IsLeader {
if consensus != nil && consensus.IsLeader {
node.State = NodeLeader
} else {
node.State = NodeInit
@ -463,6 +471,27 @@ func (node *Node) JoinShard(leader p2p.Peer) {
}
}
// SupportClient initializes and starts the client service
func (node *Node) SupportClient() {
node.InitClientServer()
node.StartClientServer()
}
// InitClientServer initializes client server.
func (node *Node) InitClientServer() {
state, err := node.Chain.State()
if err != nil {
log.Error("Failed fetching state from blockchain")
}
node.clientServer = clientService.NewServer(state)
}
// StartClientServer starts client server.
func (node *Node) StartClientServer() {
node.log.Info("support_client: StartClientServer on port:", "port", clientServicePort)
node.clientServer.Start(node.SelfPeer.IP, clientServicePort)
}
// SupportSyncing keeps sleeping until it's doing consensus or it's a leader.
func (node *Node) SupportSyncing() {
node.InitSyncingServer()

Loading…
Cancel
Save