Merge pull request #154 from harmony-one/rj_branch

[HAR-20] Implement faucet functionality and sharded transaction for wallet
pull/156/head
Leo Chen 6 years ago committed by GitHub
commit e0276d9435
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 7
      beaconchain/libs/beaconchain.go
  2. 9
      client/client.go
  3. 12
      client/service/client.go
  4. 131
      client/service/proto/client.pb.go
  5. 13
      client/service/proto/client.proto
  6. 15
      client/service/server.go
  7. 88
      client/wallet/main.go
  8. 8
      consensus/consensus_leader.go
  9. 5
      core/types/transaction.go
  10. 2
      deploy.sh
  11. 15
      harmony/main.go
  12. 66
      node/node.go
  13. 1
      node/node_handler.go
  14. 8
      node/worker/worker.go

@ -61,7 +61,11 @@ func (bc *BeaconChain) StartRPCServer() {
// GetShardLeaderMap returns the map from shard id to leader. // GetShardLeaderMap returns the map from shard id to leader.
func (bc *BeaconChain) GetShardLeaderMap() map[int]*bcconn.NodeInfo { func (bc *BeaconChain) GetShardLeaderMap() map[int]*bcconn.NodeInfo {
return bc.ShardLeaderMap result := make(map[int]*bcconn.NodeInfo)
for i, leader := range bc.Leaders {
result[i] = leader
}
return result
} }
//New beaconchain initialization //New beaconchain initialization
@ -93,7 +97,6 @@ func (bc *BeaconChain) AcceptConnections(b []byte) {
_, isLeader := utils.AllocateShard(bc.NumberOfNodesAdded, bc.NumberOfShards) _, isLeader := utils.AllocateShard(bc.NumberOfNodesAdded, bc.NumberOfShards)
if isLeader { if isLeader {
bc.Leaders = append(bc.Leaders, Node) bc.Leaders = append(bc.Leaders, Node)
bc.ShardLeaderMap[bc.NumberOfNodesAdded-1] = Node
} }
response := bcconn.ResponseRandomNumber{NumberOfShards: bc.NumberOfShards, NumberOfNodesAdded: bc.NumberOfNodesAdded, Leaders: bc.Leaders} response := bcconn.ResponseRandomNumber{NumberOfShards: bc.NumberOfShards, NumberOfNodesAdded: bc.NumberOfNodesAdded, Leaders: bc.Leaders}
msg := bcconn.SerializeRandomInfo(response) msg := bcconn.SerializeRandomInfo(response)

@ -178,3 +178,12 @@ func (client *Client) GetLeaders() []p2p.Peer {
} }
return leaders return leaders
} }
//// GetLeaders returns leader peers.
//func (client *Client) GetShardLeader(uint32 shardID) p2p.Peer {
// leaders := []p2p.Peer{}
// for _, leader := range *client.Leaders {
// leaders = append(leaders, leader)
// }
// return leaders
//}

@ -49,3 +49,15 @@ func (client *Client) GetBalance(address common.Address) *proto.FetchAccountStat
} }
return response return response
} }
// GetFreeToken requests free token from the faucet contract.
func (client *Client) GetFreeToken(address common.Address) *proto.GetFreeTokenResponse {
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
defer cancel()
request := &proto.GetFreeTokenRequest{Address: address.Bytes()}
response, err := client.clientServiceClient.GetFreeToken(ctx, request)
if err != nil {
log.Fatalf("Error getting free token: %s", err)
}
return response
}

@ -113,15 +113,99 @@ func (m *FetchAccountStateResponse) GetNonce() uint64 {
return 0 return 0
} }
// GetFreeTokenRequest is the request to get free token from the faucet smart contract.
type GetFreeTokenRequest struct {
// The account address to receive the free token
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 *GetFreeTokenRequest) Reset() { *m = GetFreeTokenRequest{} }
func (m *GetFreeTokenRequest) String() string { return proto.CompactTextString(m) }
func (*GetFreeTokenRequest) ProtoMessage() {}
func (*GetFreeTokenRequest) Descriptor() ([]byte, []int) {
return fileDescriptor_014de31d7ac8c57c, []int{2}
}
func (m *GetFreeTokenRequest) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_GetFreeTokenRequest.Unmarshal(m, b)
}
func (m *GetFreeTokenRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
return xxx_messageInfo_GetFreeTokenRequest.Marshal(b, m, deterministic)
}
func (m *GetFreeTokenRequest) XXX_Merge(src proto.Message) {
xxx_messageInfo_GetFreeTokenRequest.Merge(m, src)
}
func (m *GetFreeTokenRequest) XXX_Size() int {
return xxx_messageInfo_GetFreeTokenRequest.Size(m)
}
func (m *GetFreeTokenRequest) XXX_DiscardUnknown() {
xxx_messageInfo_GetFreeTokenRequest.DiscardUnknown(m)
}
var xxx_messageInfo_GetFreeTokenRequest proto.InternalMessageInfo
func (m *GetFreeTokenRequest) GetAddress() []byte {
if m != nil {
return m.Address
}
return nil
}
// GetFreeTokenResponse is the response of GetFreeTokenRequest.
type GetFreeTokenResponse struct {
// The transaction Id that requests free token from the faucet.
TxId []byte `protobuf:"bytes,1,opt,name=txId,proto3" json:"txId,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
func (m *GetFreeTokenResponse) Reset() { *m = GetFreeTokenResponse{} }
func (m *GetFreeTokenResponse) String() string { return proto.CompactTextString(m) }
func (*GetFreeTokenResponse) ProtoMessage() {}
func (*GetFreeTokenResponse) Descriptor() ([]byte, []int) {
return fileDescriptor_014de31d7ac8c57c, []int{3}
}
func (m *GetFreeTokenResponse) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_GetFreeTokenResponse.Unmarshal(m, b)
}
func (m *GetFreeTokenResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
return xxx_messageInfo_GetFreeTokenResponse.Marshal(b, m, deterministic)
}
func (m *GetFreeTokenResponse) XXX_Merge(src proto.Message) {
xxx_messageInfo_GetFreeTokenResponse.Merge(m, src)
}
func (m *GetFreeTokenResponse) XXX_Size() int {
return xxx_messageInfo_GetFreeTokenResponse.Size(m)
}
func (m *GetFreeTokenResponse) XXX_DiscardUnknown() {
xxx_messageInfo_GetFreeTokenResponse.DiscardUnknown(m)
}
var xxx_messageInfo_GetFreeTokenResponse proto.InternalMessageInfo
func (m *GetFreeTokenResponse) GetTxId() []byte {
if m != nil {
return m.TxId
}
return nil
}
func init() { func init() {
proto.RegisterType((*FetchAccountStateRequest)(nil), "client.FetchAccountStateRequest") proto.RegisterType((*FetchAccountStateRequest)(nil), "client.FetchAccountStateRequest")
proto.RegisterType((*FetchAccountStateResponse)(nil), "client.FetchAccountStateResponse") proto.RegisterType((*FetchAccountStateResponse)(nil), "client.FetchAccountStateResponse")
proto.RegisterType((*GetFreeTokenRequest)(nil), "client.GetFreeTokenRequest")
proto.RegisterType((*GetFreeTokenResponse)(nil), "client.GetFreeTokenResponse")
} }
func init() { proto.RegisterFile("client.proto", fileDescriptor_014de31d7ac8c57c) } func init() { proto.RegisterFile("client.proto", fileDescriptor_014de31d7ac8c57c) }
var fileDescriptor_014de31d7ac8c57c = []byte{ var fileDescriptor_014de31d7ac8c57c = []byte{
// 172 bytes of a gzipped FileDescriptorProto // 229 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0xe2, 0x49, 0xce, 0xc9, 0x4c, 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, 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, 0xdc, 0x52, 0x4b, 0x92, 0x33, 0x1c, 0x93, 0x93, 0xf3, 0x4b, 0xf3, 0x4a, 0x82, 0x4b, 0x12, 0x4b,
@ -129,10 +213,14 @@ var fileDescriptor_014de31d7ac8c57c = []byte{
0x52, 0x8b, 0x8b, 0x25, 0x18, 0x15, 0x18, 0x35, 0x78, 0x82, 0x60, 0x5c, 0x25, 0x6f, 0x2e, 0x49, 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, 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, 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, 0x06, 0x4b, 0x10, 0x84, 0xa3, 0xa4, 0xcf, 0x25, 0xec, 0x9e, 0x5a, 0xe2, 0x56, 0x94, 0x9a, 0x1a,
0x66, 0x72, 0xaa, 0x50, 0x14, 0x97, 0x20, 0x86, 0xe9, 0x42, 0x0a, 0x7a, 0x50, 0xf7, 0xe3, 0x72, 0x92, 0x9f, 0x9d, 0x9a, 0x47, 0xd8, 0x76, 0x2d, 0x2e, 0x11, 0x54, 0x0d, 0x50, 0x8b, 0x85, 0xb8,
0xae, 0x94, 0x22, 0x1e, 0x15, 0x10, 0xa7, 0x29, 0x31, 0x24, 0xb1, 0x81, 0xbd, 0x6f, 0x0c, 0x08, 0x58, 0x4a, 0x2a, 0x3c, 0x53, 0xa0, 0xca, 0xc1, 0x6c, 0xa3, 0x1d, 0x8c, 0x5c, 0xbc, 0xce, 0x60,
0x00, 0x00, 0xff, 0xff, 0x2a, 0x07, 0xa9, 0xb6, 0x0e, 0x01, 0x00, 0x00, 0xaf, 0x06, 0xa7, 0x16, 0x95, 0x65, 0x26, 0xa7, 0x0a, 0x45, 0x71, 0x09, 0x62, 0xb8, 0x5d, 0x48,
0x41, 0x0f, 0x1a, 0x3a, 0xb8, 0x02, 0x43, 0x4a, 0x11, 0x8f, 0x0a, 0x88, 0xfd, 0x4a, 0x0c, 0x42,
0xde, 0x5c, 0x3c, 0xc8, 0x2e, 0x13, 0x92, 0x86, 0x69, 0xc2, 0xe2, 0x41, 0x29, 0x19, 0xec, 0x92,
0x30, 0xc3, 0x92, 0xd8, 0xc0, 0x31, 0x65, 0x0c, 0x08, 0x00, 0x00, 0xff, 0xff, 0xc6, 0xd9, 0x35,
0x0c, 0xb9, 0x01, 0x00, 0x00,
} }
// Reference imports to suppress errors if they are not otherwise used. // Reference imports to suppress errors if they are not otherwise used.
@ -148,6 +236,7 @@ const _ = grpc.SupportPackageIsVersion4
// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream. // 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 { type ClientServiceClient interface {
FetchAccountState(ctx context.Context, in *FetchAccountStateRequest, opts ...grpc.CallOption) (*FetchAccountStateResponse, error) FetchAccountState(ctx context.Context, in *FetchAccountStateRequest, opts ...grpc.CallOption) (*FetchAccountStateResponse, error)
GetFreeToken(ctx context.Context, in *GetFreeTokenRequest, opts ...grpc.CallOption) (*GetFreeTokenResponse, error)
} }
type clientServiceClient struct { type clientServiceClient struct {
@ -167,9 +256,19 @@ func (c *clientServiceClient) FetchAccountState(ctx context.Context, in *FetchAc
return out, nil return out, nil
} }
func (c *clientServiceClient) GetFreeToken(ctx context.Context, in *GetFreeTokenRequest, opts ...grpc.CallOption) (*GetFreeTokenResponse, error) {
out := new(GetFreeTokenResponse)
err := c.cc.Invoke(ctx, "/client.ClientService/GetFreeToken", in, out, opts...)
if err != nil {
return nil, err
}
return out, nil
}
// ClientServiceServer is the server API for ClientService service. // ClientServiceServer is the server API for ClientService service.
type ClientServiceServer interface { type ClientServiceServer interface {
FetchAccountState(context.Context, *FetchAccountStateRequest) (*FetchAccountStateResponse, error) FetchAccountState(context.Context, *FetchAccountStateRequest) (*FetchAccountStateResponse, error)
GetFreeToken(context.Context, *GetFreeTokenRequest) (*GetFreeTokenResponse, error)
} }
func RegisterClientServiceServer(s *grpc.Server, srv ClientServiceServer) { func RegisterClientServiceServer(s *grpc.Server, srv ClientServiceServer) {
@ -194,6 +293,24 @@ func _ClientService_FetchAccountState_Handler(srv interface{}, ctx context.Conte
return interceptor(ctx, in, info, handler) return interceptor(ctx, in, info, handler)
} }
func _ClientService_GetFreeToken_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(GetFreeTokenRequest)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(ClientServiceServer).GetFreeToken(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: "/client.ClientService/GetFreeToken",
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(ClientServiceServer).GetFreeToken(ctx, req.(*GetFreeTokenRequest))
}
return interceptor(ctx, in, info, handler)
}
var _ClientService_serviceDesc = grpc.ServiceDesc{ var _ClientService_serviceDesc = grpc.ServiceDesc{
ServiceName: "client.ClientService", ServiceName: "client.ClientService",
HandlerType: (*ClientServiceServer)(nil), HandlerType: (*ClientServiceServer)(nil),
@ -202,6 +319,10 @@ var _ClientService_serviceDesc = grpc.ServiceDesc{
MethodName: "FetchAccountState", MethodName: "FetchAccountState",
Handler: _ClientService_FetchAccountState_Handler, Handler: _ClientService_FetchAccountState_Handler,
}, },
{
MethodName: "GetFreeToken",
Handler: _ClientService_GetFreeToken_Handler,
},
}, },
Streams: []grpc.StreamDesc{}, Streams: []grpc.StreamDesc{},
Metadata: "client.proto", Metadata: "client.proto",

@ -5,6 +5,7 @@ package client;
// Client is the service used for any client-facing requests. // Client is the service used for any client-facing requests.
service ClientService { service ClientService {
rpc FetchAccountState(FetchAccountStateRequest) returns (FetchAccountStateResponse) {} rpc FetchAccountState(FetchAccountStateRequest) returns (FetchAccountStateResponse) {}
rpc GetFreeToken(GetFreeTokenRequest) returns (GetFreeTokenResponse) {}
} }
// FetchAccountStateRequest is the request to fetch an account's balance and nonce. // FetchAccountStateRequest is the request to fetch an account's balance and nonce.
@ -20,3 +21,15 @@ message FetchAccountStateResponse {
// The nonce of the account // The nonce of the account
uint64 nonce = 2; uint64 nonce = 2;
} }
// GetFreeTokenRequest is the request to get free token from the faucet smart contract.
message GetFreeTokenRequest {
// The account address to receive the free token
bytes address = 1;
}
// GetFreeTokenResponse is the response of GetFreeTokenRequest.
message GetFreeTokenResponse {
// The transaction Id that requests free token from the faucet.
bytes txId = 1;
}

@ -14,7 +14,8 @@ import (
// Server is the Server struct for client service package. // Server is the Server struct for client service package.
type Server struct { type Server struct {
stateReader func() (*state.StateDB, error) stateReader func() (*state.StateDB, error)
callFaucetContract func(common.Address) common.Hash
} }
// FetchAccountState implements the FetchAccountState interface to return account state. // FetchAccountState implements the FetchAccountState interface to return account state.
@ -29,6 +30,14 @@ func (s *Server) FetchAccountState(ctx context.Context, request *proto.FetchAcco
return &proto.FetchAccountStateResponse{Balance: state.GetBalance(address).Bytes(), Nonce: state.GetNonce(address)}, nil return &proto.FetchAccountStateResponse{Balance: state.GetBalance(address).Bytes(), Nonce: state.GetNonce(address)}, nil
} }
// GetFreeToken implements the GetFreeToken interface to request free token.
func (s *Server) GetFreeToken(ctx context.Context, request *proto.GetFreeTokenRequest) (*proto.GetFreeTokenResponse, error) {
var address common.Address
address.SetBytes(request.Address)
log.Println("Returning GetFreeTokenResponse for address: ", address.Hex())
return &proto.GetFreeTokenResponse{TxId: s.callFaucetContract(address).Bytes()}, nil
}
// Start starts the Server on given ip and port. // Start starts the Server on given ip and port.
func (s *Server) Start(ip, port string) (*grpc.Server, error) { func (s *Server) Start(ip, port string) (*grpc.Server, error) {
// TODO(minhdoan): Currently not using ip. Fix it later. // TODO(minhdoan): Currently not using ip. Fix it later.
@ -45,7 +54,7 @@ func (s *Server) Start(ip, port string) (*grpc.Server, error) {
} }
// NewServer creates new Server which implements ClientServiceServer interface. // NewServer creates new Server which implements ClientServiceServer interface.
func NewServer(stateReader func() (*state.StateDB, error)) *Server { func NewServer(stateReader func() (*state.StateDB, error), callFaucetContract func(common.Address) common.Hash) *Server {
s := &Server{stateReader} s := &Server{stateReader: stateReader, callFaucetContract: callFaucetContract}
return s return s
} }

@ -47,6 +47,13 @@ func main() {
transferSenderPtr := transferCommand.String("from", "0", "Specify the sender account address or index") transferSenderPtr := transferCommand.String("from", "0", "Specify the sender account address or index")
transferReceiverPtr := transferCommand.String("to", "", "Specify the receiver account") transferReceiverPtr := transferCommand.String("to", "", "Specify the receiver account")
transferAmountPtr := transferCommand.Float64("amount", 0, "Specify the amount to transfer") transferAmountPtr := transferCommand.Float64("amount", 0, "Specify the amount to transfer")
transferShardIDPtr := transferCommand.Int("shardID", -1, "Specify the shard ID for the transfer")
freeTokenCommand := flag.NewFlagSet("getFreeToken", flag.ExitOnError)
freeTokenAddressPtr := freeTokenCommand.String("address", "", "Specify the account address to receive the free token")
balanceCommand := flag.NewFlagSet("getFreeToken", flag.ExitOnError)
balanceAddressPtr := balanceCommand.String("address", "", "Specify the account address to check balance for")
// Verify that a subcommand has been provided // Verify that a subcommand has been provided
// os.Arg[0] is the main command // os.Arg[0] is the main command
@ -60,11 +67,15 @@ func main() {
fmt.Println(" 3. removeAll - Removes all accounts in local keystore") fmt.Println(" 3. removeAll - Removes all accounts in local keystore")
fmt.Println(" 4. import - Imports a new account by private key") fmt.Println(" 4. import - Imports a new account by private key")
fmt.Println(" --privateKey - the private key to import") fmt.Println(" --privateKey - the private key to import")
fmt.Println(" 5. balances - Shows the balances of all accounts") fmt.Println(" 5. balances - Shows the balances of all addresses or specific address")
fmt.Println(" 6. transfer") fmt.Println(" --address - The address to check balance for")
fmt.Println(" 6. getFreeToken - Gets free token on each shard")
fmt.Println(" --address - The free token receiver account's address")
fmt.Println(" 7. transfer")
fmt.Println(" --from - The sender account's address or index in the local keystore") fmt.Println(" --from - The sender account's address or index in the local keystore")
fmt.Println(" --to - The receiver account's address") fmt.Println(" --to - The receiver account's address")
fmt.Println(" --amount - The amount of token to transfer") fmt.Println(" --amount - The amount of token to transfer")
fmt.Println(" --shardId - The shard Id for the transfer")
os.Exit(1) os.Exit(1)
} }
@ -86,14 +97,15 @@ func main() {
fmt.Printf("New account created with address:\n {%s}\n", crypto2.PubkeyToAddress(priKey.PublicKey).Hex()) fmt.Printf("New account created with address:\n {%s}\n", crypto2.PubkeyToAddress(priKey.PublicKey).Hex())
fmt.Printf("Please keep a copy of the private key:\n {%s}\n", hex.EncodeToString(crypto2.FromECDSA(priKey))) fmt.Printf("Please keep a copy of the private key:\n {%s}\n", hex.EncodeToString(crypto2.FromECDSA(priKey)))
case "list": case "list":
for i, address := range ReadAddresses() { for i, key := range ReadPrivateKeys() {
fmt.Printf("Account %d:\n {%s}\n", i, address.Hex()) fmt.Printf("Account %d:\n {%s}\n", i, crypto2.PubkeyToAddress(key.PublicKey).Hex())
fmt.Printf(" PrivateKey: {%s}\n", hex.EncodeToString(key.D.Bytes()))
} }
case "removeAll": case "removeAll":
ClearKeystore() ClearKeystore()
fmt.Println("All existing accounts deleted...") fmt.Println("All existing accounts deleted...")
case "import": case "import":
accountImportCommand.Parse(os.Args[3:]) accountImportCommand.Parse(os.Args[2:])
priKey := *accountImportPtr priKey := *accountImportPtr
if priKey == "" { if priKey == "" {
fmt.Println("Error: --privateKey is required") fmt.Println("Error: --privateKey is required")
@ -109,14 +121,37 @@ func main() {
StorePrivateKey(priKeyBytes) StorePrivateKey(priKeyBytes)
fmt.Println("Private key imported...") fmt.Println("Private key imported...")
case "balances": case "balances":
balanceCommand.Parse(os.Args[2:])
walletNode := CreateWalletNode() walletNode := CreateWalletNode()
for i, address := range ReadAddresses() { if *balanceAddressPtr == "" {
fmt.Printf("Account %d: %s:\n", i, address.Hex()) for i, address := range ReadAddresses() {
fmt.Printf("Account %d: %s:\n", i, address.Hex())
for shardID, balanceNonce := range FetchBalance(address, walletNode) {
balance := balanceNonce.balance
balance = balance.Div(balance, big.NewInt(params.GWei))
fmt.Printf(" Balance in Shard %d: %.6f \n", shardID, float32(balanceNonce.balance.Uint64())/params.GWei)
}
}
} else {
address := common.HexToAddress(*freeTokenAddressPtr)
for shardID, balanceNonce := range FetchBalance(address, walletNode) { for shardID, balanceNonce := range FetchBalance(address, walletNode) {
fmt.Printf(" Balance in Shard %d: %.6f \n", shardID, float32(balanceNonce.balance.Uint64())/params.Ether) balance := balanceNonce.balance
balance = balance.Div(balance, big.NewInt(params.GWei))
fmt.Printf(" Balance in Shard %d: %.6f \n", shardID, float32(balanceNonce.balance.Uint64())/params.GWei)
} }
} }
case "getFreeToken":
freeTokenCommand.Parse(os.Args[2:])
walletNode := CreateWalletNode()
if *freeTokenAddressPtr == "" {
fmt.Println("Error: --address is required")
return
}
address := common.HexToAddress(*freeTokenAddressPtr)
GetFreeToken(address, walletNode)
case "transfer": case "transfer":
transferCommand.Parse(os.Args[2:]) transferCommand.Parse(os.Args[2:])
if !transferCommand.Parsed() { if !transferCommand.Parsed() {
@ -125,9 +160,15 @@ func main() {
sender := *transferSenderPtr sender := *transferSenderPtr
receiver := *transferReceiverPtr receiver := *transferReceiverPtr
amount := *transferAmountPtr amount := *transferAmountPtr
shardID := *transferShardIDPtr
if shardID == -1 {
fmt.Println("Please specify the shard ID for the transfer (e.g. --shardID=0)")
return
}
if amount <= 0 { if amount <= 0 {
fmt.Println("Please specify positive amount to transfer") fmt.Println("Please specify positive amount to transfer")
return
} }
priKeys := ReadPrivateKeys() priKeys := ReadPrivateKeys()
if len(priKeys) == 0 { if len(priKeys) == 0 {
@ -167,14 +208,19 @@ func main() {
walletNode := CreateWalletNode() walletNode := CreateWalletNode()
shardIDToAccountState := FetchBalance(senderAddress, walletNode) shardIDToAccountState := FetchBalance(senderAddress, walletNode)
if float64(shardIDToAccountState[0].balance.Uint64())/params.Ether < amount { balance := shardIDToAccountState[uint32(shardID)].balance
fmt.Printf("Balance is not enough for the transfer, current balance is %.6f\n", float64(shardIDToAccountState[0].balance.Uint64())/params.Ether) balance = balance.Div(balance, big.NewInt(params.GWei))
if amount > float64(balance.Uint64())/params.GWei {
fmt.Printf("Balance is not enough for the transfer, current balance is %.6f\n", float64(balance.Uint64())/params.GWei)
return 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) amountBigInt := big.NewInt(int64(amount * params.GWei))
SubmitTransaction(tx, walletNode) amountBigInt = amountBigInt.Mul(amountBigInt, big.NewInt(params.GWei))
tx, _ := types.SignTx(types.NewTransaction(shardIDToAccountState[uint32(shardID)].nonce, receiverAddress, uint32(shardID), amountBigInt, params.TxGas, nil, nil), types.HomesteadSigner{}, senderPriKey)
SubmitTransaction(tx, walletNode, uint32(shardID))
default: default:
fmt.Printf("Unknown action: %s\n", os.Args[1])
flag.PrintDefaults() flag.PrintDefaults()
os.Exit(1) os.Exit(1)
} }
@ -222,9 +268,11 @@ func CreateWalletNode() *node.Node {
} }
// SubmitTransaction submits the transaction to the Harmony network // SubmitTransaction submits the transaction to the Harmony network
func SubmitTransaction(tx *types.Transaction, walletNode *node.Node) error { func SubmitTransaction(tx *types.Transaction, walletNode *node.Node, shardID uint32) error {
msg := proto_node.ConstructTransactionListMessageAccount(types.Transactions{tx}) msg := proto_node.ConstructTransactionListMessageAccount(types.Transactions{tx})
walletNode.BroadcastMessage(walletNode.Client.GetLeaders(), msg) leader := (*walletNode.Client.Leaders)[shardID]
walletNode.SendMessage(leader, msg)
fmt.Printf("Transaction Id for shard %d: %s\n", int(shardID), common.BytesToAddress(tx.Hash().Bytes()).Hex())
time.Sleep(300 * time.Millisecond) time.Sleep(300 * time.Millisecond)
return nil return nil
} }
@ -244,6 +292,16 @@ func FetchBalance(address common.Address, walletNode *node.Node) map[uint32]Acco
return result return result
} }
// GetFreeToken requests for token test token on each shard
func GetFreeToken(address common.Address, walletNode *node.Node) {
for shardID, leader := range *walletNode.Client.Leaders {
port, _ := strconv.Atoi(leader.Port)
client := client2.NewClient(leader.IP, strconv.Itoa(port+node.ClientServicePortDiff))
response := client.GetFreeToken(address)
fmt.Printf("Transaction Id requesting free token in shard %d: %s\n", int(shardID), common.BytesToAddress(response.TxId).Hex())
}
}
// FetchUtxos fetches utxos of specified address from the Harmony network // FetchUtxos fetches utxos of specified address from the Harmony network
func FetchUtxos(addresses [][20]byte, walletNode *node.Node) (map[uint32]blockchain.UtxoMap, error) { func FetchUtxos(addresses [][20]byte, walletNode *node.Node) (map[uint32]blockchain.UtxoMap, error) {
walletNode.Client.ShardUtxoMap = make(map[uint32]blockchain.UtxoMap) walletNode.Client.ShardUtxoMap = make(map[uint32]blockchain.UtxoMap)

@ -25,7 +25,7 @@ import (
) )
const ( const (
waitForEnoughValidators = 300 waitForEnoughValidators = 1000
) )
var ( var (
@ -43,10 +43,9 @@ func (consensus *Consensus) WaitForNewBlock(blockChannel chan blockchain.Block)
consensus.Log.Debug("WaitForNewBlock", "removed peers", c) consensus.Log.Debug("WaitForNewBlock", "removed peers", c)
} }
if !consensus.HasEnoughValidators() { for !consensus.HasEnoughValidators() {
consensus.Log.Debug("Not enough validators", "# Validators", len(consensus.PublicKeys)) consensus.Log.Debug("Not enough validators", "# Validators", len(consensus.PublicKeys))
time.Sleep(waitForEnoughValidators * time.Millisecond) time.Sleep(waitForEnoughValidators * time.Millisecond)
continue
} }
// TODO: think about potential race condition // TODO: think about potential race condition
@ -73,10 +72,9 @@ func (consensus *Consensus) WaitForNewBlockAccount(blockChannel chan *types.Bloc
consensus.Log.Debug("WaitForNewBlock", "removed peers", c) consensus.Log.Debug("WaitForNewBlock", "removed peers", c)
} }
if !consensus.HasEnoughValidators() { for !consensus.HasEnoughValidators() {
consensus.Log.Debug("Not enough validators", "# Validators", len(consensus.PublicKeys)) consensus.Log.Debug("Not enough validators", "# Validators", len(consensus.PublicKeys))
time.Sleep(waitForEnoughValidators * time.Millisecond) time.Sleep(waitForEnoughValidators * time.Millisecond)
continue
} }
startTime = time.Now() startTime = time.Now()

@ -115,6 +115,11 @@ func (tx *Transaction) ChainID() *big.Int {
return deriveChainID(tx.data.V) return deriveChainID(tx.data.V)
} }
// ShardID returns which shard id this transaction was signed for (if at all)
func (tx *Transaction) ShardID() uint32 {
return tx.data.ShardID
}
// Protected returns whether the transaction is protected from replay protection. // Protected returns whether the transaction is protected from replay protection.
func (tx *Transaction) Protected() bool { func (tx *Transaction) Protected() bool {
return isProtectedV(tx.data.V) return isProtectedV(tx.data.V)

@ -112,7 +112,7 @@ while IFS='' read -r line || [[ -n "$line" ]]; do
./bin/benchmark -ip $ip -port $port -config_file $config -log_folder $log_folder $DB -min_peers $MIN & ./bin/benchmark -ip $ip -port $port -config_file $config -log_folder $log_folder $DB -min_peers $MIN &
else else
./bin/benchmark -ip $ip -port $port -log_folder $log_folder $DB $PEER -min_peers $MIN & ./bin/benchmark -ip $ip -port $port -log_folder $log_folder $DB $PEER -min_peers $MIN &
sleep 1 sleep 0.5
fi fi
fi fi
done < $config done < $config

@ -1,6 +1,7 @@
package main package main
import ( import (
"encoding/hex"
"fmt" "fmt"
"github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common"
"log" "log"
@ -86,7 +87,7 @@ func main() {
} }
txs := make([]*types.Transaction, 10) txs := make([]*types.Transaction, 10)
worker := worker.New(params.TestChainConfig, chain, consensus.NewFaker(), crypto.PubkeyToAddress(testBankKey.PublicKey)) worker := worker.New(params.TestChainConfig, chain, consensus.NewFaker(), crypto.PubkeyToAddress(testBankKey.PublicKey), 0)
nonce := worker.GetCurrentState().GetNonce(crypto.PubkeyToAddress(testBankKey.PublicKey)) nonce := worker.GetCurrentState().GetNonce(crypto.PubkeyToAddress(testBankKey.PublicKey))
for i := range txs { for i := range txs {
randomUserKey, _ := crypto.GenerateKey() randomUserKey, _ := crypto.GenerateKey()
@ -116,7 +117,7 @@ func main() {
// return address(this).balance; // return address(this).balance;
//} //}
//} //}
contractData := "0x60806040526706f05b59d3b2000060015560028054600160a060020a031916331790556101aa806100316000396000f3fe608060405260043610610045577c0100000000000000000000000000000000000000000000000000000000600035046327c78c42811461004a5780634ddd108a1461008c575b600080fd5b34801561005657600080fd5b5061008a6004803603602081101561006d57600080fd5b503573ffffffffffffffffffffffffffffffffffffffff166100b3565b005b34801561009857600080fd5b506100a1610179565b60408051918252519081900360200190f35b60025473ffffffffffffffffffffffffffffffffffffffff1633146100d757600080fd5b600154303110156100e757600080fd5b73ffffffffffffffffffffffffffffffffffffffff811660009081526020819052604090205460ff161561011a57600080fd5b73ffffffffffffffffffffffffffffffffffffffff8116600081815260208190526040808220805460ff1916600190811790915554905181156108fc0292818181858888f19350505050158015610175573d6000803e3d6000fd5b5050565b30319056fea165627a7a72305820fc2f7280f3590bd63f7b13a34411e0086c18e5a947b4437759ee79fbc566782f0029" contractData := "0x60806040526802b5e3af16b188000060015560028054600160a060020a031916331790556101aa806100326000396000f3fe608060405260043610610045577c0100000000000000000000000000000000000000000000000000000000600035046327c78c42811461004a5780634ddd108a1461008c575b600080fd5b34801561005657600080fd5b5061008a6004803603602081101561006d57600080fd5b503573ffffffffffffffffffffffffffffffffffffffff166100b3565b005b34801561009857600080fd5b506100a1610179565b60408051918252519081900360200190f35b60025473ffffffffffffffffffffffffffffffffffffffff1633146100d757600080fd5b600154303110156100e757600080fd5b73ffffffffffffffffffffffffffffffffffffffff811660009081526020819052604090205460ff161561011a57600080fd5b73ffffffffffffffffffffffffffffffffffffffff8116600081815260208190526040808220805460ff1916600190811790915554905181156108fc0292818181858888f19350505050158015610175573d6000803e3d6000fd5b5050565b30319056fea165627a7a7230582003d799bcee73e96e0f40ca432d9c3d2aa9c00a1eba8d00877114a0d7234790ce0029"
_ = contractData _ = contractData
dataEnc := common.FromHex(contractData) dataEnc := common.FromHex(contractData)
@ -140,15 +141,19 @@ func main() {
} }
fmt.Println(contractAddress) fmt.Println(contractAddress)
var address common.Address
bytes, err := hex.DecodeString("ac51b997a3a17fa18e46baceb32fcab9acc93917")
address.SetBytes(bytes)
receipts := worker.GetCurrentReceipts() receipts := worker.GetCurrentReceipts()
fmt.Println(receipts[len(receipts)-1].ContractAddress) fmt.Println(receipts[len(receipts)-1].ContractAddress)
fmt.Println(receipts[len(receipts)-1]) fmt.Println(receipts[len(receipts)-1])
fmt.Println(state.GetNonce(testBankAddress)) fmt.Println(state.GetNonce(testBankAddress))
fmt.Println(state.GetNonce(contractAddress)) fmt.Println(testBankKey)
fmt.Println(state.GetBalance(contractAddress)) fmt.Println(state.GetBalance(contractAddress))
fmt.Println(state.GetBalance(address))
fmt.Println(state.GetCodeHash(contractAddress)) fmt.Println(state.GetCodeHash(contractAddress))
callData := "0x27c78c4200000000000000000000000024182601fe6e2e5da0b831496cc0489b7173b44f" callData := "0x27c78c42000000000000000000000000ac51b997a3a17fa18e46baceb32fcab9acc93917" //24182601fe6e2e5da0b831496cc0489b7173b44f"
callEnc := common.FromHex(callData) callEnc := common.FromHex(callData)
tx, _ = types.SignTx(types.NewTransaction(nonce+uint64(11), contractAddress, 0, big.NewInt(0), params.TxGasContractCreation*10, nil, callEnc), types.HomesteadSigner{}, testBankKey) tx, _ = types.SignTx(types.NewTransaction(nonce+uint64(11), contractAddress, 0, big.NewInt(0), params.TxGasContractCreation*10, nil, callEnc), types.HomesteadSigner{}, testBankKey)
@ -160,7 +165,7 @@ func main() {
fmt.Println(receipts[len(receipts)-1].ContractAddress) fmt.Println(receipts[len(receipts)-1].ContractAddress)
fmt.Println(receipts[len(receipts)-1]) fmt.Println(receipts[len(receipts)-1])
fmt.Println(state.GetNonce(testBankAddress)) fmt.Println(state.GetNonce(testBankAddress))
fmt.Println(state.GetNonce(contractAddress))
fmt.Println(state.GetBalance(contractAddress)) fmt.Println(state.GetBalance(contractAddress))
fmt.Println(state.GetBalance(address))
fmt.Println(state.GetCodeHash(contractAddress)) fmt.Println(state.GetCodeHash(contractAddress))
} }

@ -4,6 +4,7 @@ import (
"bytes" "bytes"
"crypto/ecdsa" "crypto/ecdsa"
"encoding/gob" "encoding/gob"
"encoding/hex"
"fmt" "fmt"
"math/big" "math/big"
"math/rand" "math/rand"
@ -132,8 +133,9 @@ type Node struct {
syncingState uint32 syncingState uint32
// Test only // Test only
TestBankKeys []*ecdsa.PrivateKey TestBankKeys []*ecdsa.PrivateKey
ContractKeys []*ecdsa.PrivateKey ContractKeys []*ecdsa.PrivateKey
ContractAddresses []common.Address
// The p2p host used to send/receive p2p messages // The p2p host used to send/receive p2p messages
host host.Host host host.Host
@ -259,17 +261,6 @@ func DeserializeNode(d []byte) *NetworkNode {
return &wn return &wn
} }
//AddSmartContractsToPendingTransactions adds the faucet contract the genesis block.
func (node *Node) AddSmartContractsToPendingTransactions() {
// Add a contract deployment transactionv
priKey := node.ContractKeys[0]
contractData := "0x608060405234801561001057600080fd5b506040516020806104c08339810180604052602081101561003057600080fd5b505160008054600160a060020a0319163317808255600160a060020a031681526001602081905260409091205560ff811661006c600282610073565b50506100bd565b8154818355818111156100975760008381526020902061009791810190830161009c565b505050565b6100ba91905b808211156100b657600081556001016100a2565b5090565b90565b6103f4806100cc6000396000f3fe60806040526004361061005b577c010000000000000000000000000000000000000000000000000000000060003504635c19a95c8114610060578063609ff1bd146100955780639e7b8d61146100c0578063b3f98adc146100f3575b600080fd5b34801561006c57600080fd5b506100936004803603602081101561008357600080fd5b5035600160a060020a0316610120565b005b3480156100a157600080fd5b506100aa610280565b6040805160ff9092168252519081900360200190f35b3480156100cc57600080fd5b50610093600480360360208110156100e357600080fd5b5035600160a060020a03166102eb565b3480156100ff57600080fd5b506100936004803603602081101561011657600080fd5b503560ff16610348565b3360009081526001602081905260409091209081015460ff1615610144575061027d565b5b600160a060020a0382811660009081526001602081905260409091200154620100009004161580159061019c5750600160a060020a0382811660009081526001602081905260409091200154620100009004163314155b156101ce57600160a060020a039182166000908152600160208190526040909120015462010000900490911690610145565b600160a060020a0382163314156101e5575061027d565b6001818101805460ff1916821775ffffffffffffffffffffffffffffffffffffffff0000191662010000600160a060020a0386169081029190911790915560009081526020829052604090209081015460ff16156102725781546001820154600280549091610100900460ff1690811061025b57fe5b60009182526020909120018054909101905561027a565b815481540181555b50505b50565b600080805b60025460ff821610156102e6578160028260ff168154811015156102a557fe5b906000526020600020016000015411156102de576002805460ff83169081106102ca57fe5b906000526020600020016000015491508092505b600101610285565b505090565b600054600160a060020a0316331415806103215750600160a060020a0381166000908152600160208190526040909120015460ff165b1561032b5761027d565b600160a060020a0316600090815260016020819052604090912055565b3360009081526001602081905260409091209081015460ff1680610371575060025460ff831610155b1561037c575061027d565b6001818101805460ff191690911761ff00191661010060ff8516908102919091179091558154600280549192909181106103b257fe5b600091825260209091200180549091019055505056fea165627a7a72305820164189ef302b4648e01e22456b0a725191604cb63ee472f230ef6a2d17d702f900290000000000000000000000000000000000000000000000000000000000000002"
dataEnc := common.FromHex(contractData)
// Unsigned transaction to avoid the case of transaction address.
mycontracttx, _ := types.SignTx(types.NewContractCreation(uint64(0), 0, big.NewInt(1000000), params.TxGasContractCreation*10, nil, dataEnc), types.HomesteadSigner{}, priKey)
node.addPendingTransactionsAccount(types.Transactions{mycontracttx})
}
// New creates a new node. // New creates a new node.
func New(host host.Host, consensus *bft.Consensus, db *hdb.LDBDatabase) *Node { func New(host host.Host, consensus *bft.Consensus, db *hdb.LDBDatabase) *Node {
node := Node{} node := Node{}
@ -314,16 +305,18 @@ func New(host host.Host, consensus *bft.Consensus, db *hdb.LDBDatabase) *Node {
for i := 0; i < 100; i++ { for i := 0; i < 100; i++ {
testBankKey, _ := ecdsa.GenerateKey(crypto.S256(), reader) testBankKey, _ := ecdsa.GenerateKey(crypto.S256(), reader)
testBankAddress := crypto.PubkeyToAddress(testBankKey.PublicKey) testBankAddress := crypto.PubkeyToAddress(testBankKey.PublicKey)
testBankFunds := big.NewInt(8000000000000000000) testBankFunds := big.NewInt(1000)
//fmt.Println(crypto.PubkeyToAddress(testBankKey.PublicKey).Hex()) testBankFunds = testBankFunds.Mul(testBankFunds, big.NewInt(params.Ether))
//fmt.Println(hex.EncodeToString(crypto.FromECDSA(testBankKey))) fmt.Println(crypto.PubkeyToAddress(testBankKey.PublicKey).Hex())
fmt.Println(hex.EncodeToString(crypto.FromECDSA(testBankKey)))
genesisAloc[testBankAddress] = core.GenesisAccount{Balance: testBankFunds} genesisAloc[testBankAddress] = core.GenesisAccount{Balance: testBankFunds}
node.TestBankKeys = append(node.TestBankKeys, testBankKey) node.TestBankKeys = append(node.TestBankKeys, testBankKey)
} }
contractKey, _ := ecdsa.GenerateKey(crypto.S256(), reader) contractKey, _ := ecdsa.GenerateKey(crypto.S256(), reader)
contractAddress := crypto.PubkeyToAddress(contractKey.PublicKey) contractAddress := crypto.PubkeyToAddress(contractKey.PublicKey)
contractFunds := big.NewInt(8000000000000000000) contractFunds := big.NewInt(9000000)
contractFunds = contractFunds.Mul(contractFunds, big.NewInt(params.Ether))
genesisAloc[contractAddress] = core.GenesisAccount{Balance: contractFunds} genesisAloc[contractAddress] = core.GenesisAccount{Balance: contractFunds}
node.ContractKeys = append(node.ContractKeys, contractKey) node.ContractKeys = append(node.ContractKeys, contractKey)
@ -342,9 +335,9 @@ func New(host host.Host, consensus *bft.Consensus, db *hdb.LDBDatabase) *Node {
//This one is not used --- RJ. //This one is not used --- RJ.
node.TxPool = core.NewTxPool(core.DefaultTxPoolConfig, params.TestChainConfig, chain) node.TxPool = core.NewTxPool(core.DefaultTxPoolConfig, params.TestChainConfig, chain)
node.BlockChannelAccount = make(chan *types.Block) node.BlockChannelAccount = make(chan *types.Block)
node.Worker = worker.New(params.TestChainConfig, chain, node.Consensus, pki.GetAddressFromPublicKey(node.SelfPeer.PubKey)) node.Worker = worker.New(params.TestChainConfig, chain, node.Consensus, pki.GetAddressFromPublicKey(node.SelfPeer.PubKey), node.Consensus.ShardID)
//Initialize the pending transactions with smart contract transactions
//node.AddSmartContractsToPendingTransactions() node.AddSmartContractsToPendingTransactions()
} }
if consensus != nil && consensus.IsLeader { if consensus != nil && consensus.IsLeader {
@ -434,14 +427,37 @@ func (node *Node) GetSyncingPeers() []p2p.Peer {
return res return res
} }
//AddSmartContractsToPendingTransactions adds the faucet contract the genesis block.
func (node *Node) AddSmartContractsToPendingTransactions() {
// Add a contract deployment transactionv
priKey := node.ContractKeys[0]
contractData := "0x6080604052678ac7230489e8000060015560028054600160a060020a031916331790556101aa806100316000396000f3fe608060405260043610610045577c0100000000000000000000000000000000000000000000000000000000600035046327c78c42811461004a5780634ddd108a1461008c575b600080fd5b34801561005657600080fd5b5061008a6004803603602081101561006d57600080fd5b503573ffffffffffffffffffffffffffffffffffffffff166100b3565b005b34801561009857600080fd5b506100a1610179565b60408051918252519081900360200190f35b60025473ffffffffffffffffffffffffffffffffffffffff1633146100d757600080fd5b600154303110156100e757600080fd5b73ffffffffffffffffffffffffffffffffffffffff811660009081526020819052604090205460ff161561011a57600080fd5b73ffffffffffffffffffffffffffffffffffffffff8116600081815260208190526040808220805460ff1916600190811790915554905181156108fc0292818181858888f19350505050158015610175573d6000803e3d6000fd5b5050565b30319056fea165627a7a723058203e799228fee2fa7c5d15e71c04267a0cc2687c5eff3b48b98f21f355e1064ab30029"
dataEnc := common.FromHex(contractData)
// Unsigned transaction to avoid the case of transaction address.
contractFunds := big.NewInt(8000000)
contractFunds = contractFunds.Mul(contractFunds, big.NewInt(params.Ether))
mycontracttx, _ := types.SignTx(types.NewContractCreation(uint64(0), node.Consensus.ShardID, contractFunds, params.TxGasContractCreation*10, nil, dataEnc), types.HomesteadSigner{}, priKey)
node.ContractAddresses = append(node.ContractAddresses, crypto.CreateAddress(crypto.PubkeyToAddress(priKey.PublicKey), uint64(0)))
fmt.Println(node.ContractAddresses[0].Hex())
node.addPendingTransactionsAccount(types.Transactions{mycontracttx})
}
//CallFaucetContract invokes the faucet contract to give the walletAddress initial money //CallFaucetContract invokes the faucet contract to give the walletAddress initial money
func (node *Node) CallFaucetContract(contractAddress common.Address, walletAddress common.Address) { func (node *Node) CallFaucetContract(walletAddress common.Address) common.Hash {
nonce := node.Worker.GetCurrentState().GetNonce(crypto.PubkeyToAddress(node.ContractKeys[0].PublicKey)) state, err := node.Chain.State()
if err != nil {
log.Error("Failed to get chain state", "Error", err)
}
nonce := state.GetNonce(crypto.PubkeyToAddress(node.ContractKeys[0].PublicKey))
callingFunction := "0x27c78c42000000000000000000000000" callingFunction := "0x27c78c42000000000000000000000000"
contractData := callingFunction + walletAddress.Hex() contractData := callingFunction + hex.EncodeToString(walletAddress.Bytes())
dataEnc := common.FromHex(contractData) dataEnc := common.FromHex(contractData)
tx, _ := types.SignTx(types.NewTransaction(nonce, contractAddress, node.Consensus.ShardID, big.NewInt(7000000000000000000), params.TxGasContractCreation*10, nil, dataEnc), types.HomesteadSigner{}, node.ContractKeys[0]) tx, _ := types.SignTx(types.NewTransaction(nonce, node.ContractAddresses[0], node.Consensus.ShardID, big.NewInt(0), params.TxGasContractCreation*10, nil, dataEnc), types.HomesteadSigner{}, node.ContractKeys[0])
node.addPendingTransactionsAccount(types.Transactions{tx}) node.addPendingTransactionsAccount(types.Transactions{tx})
return tx.Hash()
} }
// JoinShard helps a new node to join a shard. // JoinShard helps a new node to join a shard.
@ -481,7 +497,7 @@ func (node *Node) SupportClient() {
// InitClientServer initializes client server. // InitClientServer initializes client server.
func (node *Node) InitClientServer() { func (node *Node) InitClientServer() {
node.clientServer = clientService.NewServer(node.Chain.State) node.clientServer = clientService.NewServer(node.Chain.State, node.CallFaucetContract)
} }
// StartClientServer starts client server. // StartClientServer starts client server.

@ -331,6 +331,7 @@ func (node *Node) WaitForConsensusReady(readySignal chan struct{}) {
// WaitForConsensusReadyAccount ... // WaitForConsensusReadyAccount ...
func (node *Node) WaitForConsensusReadyAccount(readySignal chan struct{}) { func (node *Node) WaitForConsensusReadyAccount(readySignal chan struct{}) {
node.log.Debug("Waiting for Consensus ready", "node", node) node.log.Debug("Waiting for Consensus ready", "node", node)
time.Sleep(10 * time.Second)
var newBlock *types.Block var newBlock *types.Block
timeoutCount := 0 timeoutCount := 0

@ -37,6 +37,8 @@ type Worker struct {
gasFloor uint64 gasFloor uint64
gasCeil uint64 gasCeil uint64
shardID uint32
} }
// SelectTransactionsForNewBlock selects transactions for new block. // SelectTransactionsForNewBlock selects transactions for new block.
@ -48,6 +50,9 @@ func (w *Worker) SelectTransactionsForNewBlock(txs types.Transactions, maxNumTxs
unselected := types.Transactions{} unselected := types.Transactions{}
invalid := types.Transactions{} invalid := types.Transactions{}
for _, tx := range txs { for _, tx := range txs {
if tx.ShardID() != w.shardID {
invalid = append(invalid, tx)
}
snap := w.current.state.Snapshot() snap := w.current.state.Snapshot()
_, err := w.commitTransaction(tx, w.coinbase) _, err := w.commitTransaction(tx, w.coinbase)
if len(selected) > maxNumTxs { if len(selected) > maxNumTxs {
@ -151,7 +156,7 @@ func (w *Worker) Commit() (*types.Block, error) {
} }
// New ... // New ...
func New(config *params.ChainConfig, chain *core.BlockChain, engine consensus.Engine, coinbase common.Address) *Worker { func New(config *params.ChainConfig, chain *core.BlockChain, engine consensus.Engine, coinbase common.Address, shardID uint32) *Worker {
worker := &Worker{ worker := &Worker{
config: config, config: config,
chain: chain, chain: chain,
@ -160,6 +165,7 @@ func New(config *params.ChainConfig, chain *core.BlockChain, engine consensus.En
worker.gasFloor = 0 worker.gasFloor = 0
worker.gasCeil = 1000000000000000 worker.gasCeil = 1000000000000000
worker.coinbase = coinbase worker.coinbase = coinbase
worker.shardID = shardID
parent := worker.chain.CurrentBlock() parent := worker.chain.CurrentBlock()
num := parent.Number() num := parent.Number()

Loading…
Cancel
Save