Refactor HD Wallets for Enhanced Security (#7821)

* begin hd wallet refactor

* further simplify the new derived keymanager

* make it almost a full wrapper around an imported keymanager

* fix up the EIP test

* deprecated derived

* fixing keymanager tests

* fix up derived tests

* refactor initialize keymanager

* simplify hd

* pass some tests

* pass accounts list test

* gaz

* regenerate protos without create account privilege

* enforce account recovery on wallet create

* allow accounts delete to work

* remove mentions of accounts create

* resolve comments and go mod

* fix up tests

* build fixes

* remove insecure warning

* revert

* fix proto file

* remove create account message

* gaz

* remove account create

* update web api protos

* fix up imports

* change func sig

* tidy

Co-authored-by: Preston Van Loon <preston@prysmaticlabs.com>
This commit is contained in:
Raul Jordan
2020-11-16 16:26:04 -06:00
committed by GitHub
parent d85cf028ef
commit 7449eba612
48 changed files with 648 additions and 2299 deletions

1
go.mod
View File

@@ -104,7 +104,6 @@ require (
github.com/tyler-smith/go-bip39 v1.0.2
github.com/urfave/cli/v2 v2.2.0
github.com/wealdtech/go-bytesutil v1.1.1
github.com/wealdtech/go-eth2-types/v2 v2.5.1
github.com/wealdtech/go-eth2-util v1.6.2
github.com/wealdtech/go-eth2-wallet-encryptor-keystorev4 v1.1.1
github.com/wercker/journalhook v0.0.0-20180428041537-5d0a5ae867b3

View File

@@ -1066,53 +1066,6 @@ func (m *ImportKeystoresResponse) GetImportedPublicKeys() [][]byte {
return nil
}
type CreateAccountRequest struct {
NumAccounts uint64 `protobuf:"varint,1,opt,name=num_accounts,json=numAccounts,proto3" json:"num_accounts,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
func (m *CreateAccountRequest) Reset() { *m = CreateAccountRequest{} }
func (m *CreateAccountRequest) String() string { return proto.CompactTextString(m) }
func (*CreateAccountRequest) ProtoMessage() {}
func (*CreateAccountRequest) Descriptor() ([]byte, []int) {
return fileDescriptor_8a5153635bfe042e, []int{16}
}
func (m *CreateAccountRequest) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b)
}
func (m *CreateAccountRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
if deterministic {
return xxx_messageInfo_CreateAccountRequest.Marshal(b, m, deterministic)
} else {
b = b[:cap(b)]
n, err := m.MarshalToSizedBuffer(b)
if err != nil {
return nil, err
}
return b[:n], nil
}
}
func (m *CreateAccountRequest) XXX_Merge(src proto.Message) {
xxx_messageInfo_CreateAccountRequest.Merge(m, src)
}
func (m *CreateAccountRequest) XXX_Size() int {
return m.Size()
}
func (m *CreateAccountRequest) XXX_DiscardUnknown() {
xxx_messageInfo_CreateAccountRequest.DiscardUnknown(m)
}
var xxx_messageInfo_CreateAccountRequest proto.InternalMessageInfo
func (m *CreateAccountRequest) GetNumAccounts() uint64 {
if m != nil {
return m.NumAccounts
}
return 0
}
type DepositMessage struct {
Pubkey []byte `protobuf:"bytes,1,opt,name=pubkey,proto3" json:"pubkey,omitempty" ssz-size:"48"`
WithdrawalCredentials []byte `protobuf:"bytes,2,opt,name=withdrawal_credentials,json=withdrawalCredentials,proto3" json:"withdrawal_credentials,omitempty" ssz-size:"32"`
@@ -1126,7 +1079,7 @@ func (m *DepositMessage) Reset() { *m = DepositMessage{} }
func (m *DepositMessage) String() string { return proto.CompactTextString(m) }
func (*DepositMessage) ProtoMessage() {}
func (*DepositMessage) Descriptor() ([]byte, []int) {
return fileDescriptor_8a5153635bfe042e, []int{17}
return fileDescriptor_8a5153635bfe042e, []int{16}
}
func (m *DepositMessage) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b)
@@ -1187,7 +1140,7 @@ func (m *DepositDataResponse) Reset() { *m = DepositDataResponse{} }
func (m *DepositDataResponse) String() string { return proto.CompactTextString(m) }
func (*DepositDataResponse) ProtoMessage() {}
func (*DepositDataResponse) Descriptor() ([]byte, []int) {
return fileDescriptor_8a5153635bfe042e, []int{18}
return fileDescriptor_8a5153635bfe042e, []int{17}
}
func (m *DepositDataResponse) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b)
@@ -1234,7 +1187,7 @@ func (m *DepositDataResponse_DepositData) Reset() { *m = DepositDataResp
func (m *DepositDataResponse_DepositData) String() string { return proto.CompactTextString(m) }
func (*DepositDataResponse_DepositData) ProtoMessage() {}
func (*DepositDataResponse_DepositData) Descriptor() ([]byte, []int) {
return fileDescriptor_8a5153635bfe042e, []int{18, 0}
return fileDescriptor_8a5153635bfe042e, []int{17, 0}
}
func (m *DepositDataResponse_DepositData) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b)
@@ -1281,7 +1234,7 @@ func (m *DeleteAccountsRequest) Reset() { *m = DeleteAccountsRequest{} }
func (m *DeleteAccountsRequest) String() string { return proto.CompactTextString(m) }
func (*DeleteAccountsRequest) ProtoMessage() {}
func (*DeleteAccountsRequest) Descriptor() ([]byte, []int) {
return fileDescriptor_8a5153635bfe042e, []int{19}
return fileDescriptor_8a5153635bfe042e, []int{18}
}
func (m *DeleteAccountsRequest) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b)
@@ -1328,7 +1281,7 @@ func (m *DeleteAccountsResponse) Reset() { *m = DeleteAccountsResponse{}
func (m *DeleteAccountsResponse) String() string { return proto.CompactTextString(m) }
func (*DeleteAccountsResponse) ProtoMessage() {}
func (*DeleteAccountsResponse) Descriptor() ([]byte, []int) {
return fileDescriptor_8a5153635bfe042e, []int{20}
return fileDescriptor_8a5153635bfe042e, []int{19}
}
func (m *DeleteAccountsResponse) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b)
@@ -1383,7 +1336,6 @@ func init() {
proto.RegisterType((*HasWalletResponse)(nil), "ethereum.validator.accounts.v2.HasWalletResponse")
proto.RegisterType((*ImportKeystoresRequest)(nil), "ethereum.validator.accounts.v2.ImportKeystoresRequest")
proto.RegisterType((*ImportKeystoresResponse)(nil), "ethereum.validator.accounts.v2.ImportKeystoresResponse")
proto.RegisterType((*CreateAccountRequest)(nil), "ethereum.validator.accounts.v2.CreateAccountRequest")
proto.RegisterType((*DepositMessage)(nil), "ethereum.validator.accounts.v2.DepositMessage")
proto.RegisterType((*DepositDataResponse)(nil), "ethereum.validator.accounts.v2.DepositDataResponse")
proto.RegisterType((*DepositDataResponse_DepositData)(nil), "ethereum.validator.accounts.v2.DepositDataResponse.DepositData")
@@ -1397,122 +1349,119 @@ func init() {
}
var fileDescriptor_8a5153635bfe042e = []byte{
// 1832 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xb4, 0x58, 0xcd, 0x6f, 0x23, 0x49,
0x15, 0xa7, 0x6c, 0xc7, 0xb1, 0x9f, 0x1d, 0xc7, 0xa9, 0x24, 0x1e, 0xe3, 0x99, 0xc9, 0x64, 0x7a,
0xd9, 0x99, 0x24, 0xb3, 0x63, 0x2f, 0x9e, 0x65, 0x27, 0x84, 0x03, 0x9a, 0x71, 0xcc, 0x4e, 0x94,
0xf9, 0x52, 0x6f, 0xc4, 0x8a, 0x03, 0xb4, 0x2a, 0xee, 0xda, 0x76, 0xc9, 0x76, 0xb5, 0xb7, 0xbb,
0x9c, 0x8f, 0xe1, 0xb6, 0x42, 0xe2, 0x00, 0x5c, 0xd8, 0x03, 0xe2, 0xc0, 0x81, 0x91, 0xb8, 0xc0,
0x09, 0x09, 0x89, 0x1b, 0x07, 0x4e, 0x1c, 0x91, 0xb8, 0x2f, 0x68, 0xc4, 0x95, 0x0b, 0x7f, 0x01,
0xaa, 0x8f, 0x6e, 0x7f, 0xc4, 0xc6, 0xc9, 0x20, 0x2e, 0x56, 0xd7, 0xab, 0x57, 0xef, 0xfd, 0xea,
0x7d, 0x97, 0x61, 0xbb, 0x1f, 0xf8, 0xc2, 0xaf, 0x9d, 0x90, 0x2e, 0x73, 0x89, 0xf0, 0x83, 0x1a,
0x69, 0xb5, 0xfc, 0x01, 0x17, 0x61, 0xed, 0xa4, 0x5e, 0x3b, 0xa5, 0xc7, 0x0e, 0xe9, 0xb3, 0xaa,
0xe2, 0xc1, 0x1b, 0x54, 0xb4, 0x69, 0x40, 0x07, 0xbd, 0x6a, 0xcc, 0x5d, 0x8d, 0xb8, 0xab, 0x27,
0xf5, 0xca, 0x0d, 0xcf, 0xf7, 0xbd, 0x2e, 0xad, 0x91, 0x3e, 0xab, 0x11, 0xce, 0x7d, 0x41, 0x04,
0xf3, 0x79, 0xa8, 0x4f, 0x57, 0xae, 0x9b, 0x5d, 0xb5, 0x3a, 0x1e, 0x7c, 0x5a, 0xa3, 0xbd, 0xbe,
0x38, 0x37, 0x9b, 0xf7, 0x3d, 0x26, 0xda, 0x83, 0xe3, 0x6a, 0xcb, 0xef, 0xd5, 0x3c, 0xdf, 0xf3,
0x87, 0x5c, 0x72, 0xa5, 0x21, 0xca, 0x2f, 0xcd, 0x6e, 0xfd, 0x34, 0x09, 0xab, 0x8d, 0x80, 0x12,
0x41, 0x3f, 0x21, 0xdd, 0x2e, 0x15, 0x36, 0xfd, 0x6c, 0x40, 0x43, 0x81, 0x6f, 0x41, 0xee, 0x54,
0x11, 0x9c, 0x3e, 0x11, 0xed, 0x32, 0xda, 0x44, 0x5b, 0x59, 0x1b, 0x34, 0xe9, 0x25, 0x11, 0x6d,
0xfc, 0x1c, 0xa0, 0x43, 0xcf, 0x7b, 0x84, 0x13, 0x8f, 0x06, 0xe5, 0xc4, 0x26, 0xda, 0x2a, 0xd4,
0xab, 0xd5, 0xff, 0x7e, 0xaf, 0xea, 0x61, 0x7c, 0xe2, 0x90, 0x71, 0xd7, 0x1e, 0x91, 0x80, 0xef,
0xc2, 0x72, 0xac, 0x30, 0x0c, 0x4f, 0xfd, 0xc0, 0x2d, 0x27, 0x95, 0xd2, 0x42, 0xa4, 0x54, 0x53,
0x71, 0x05, 0x32, 0x3d, 0x4e, 0x7b, 0x3e, 0x67, 0xad, 0x72, 0x4a, 0x71, 0xc4, 0x6b, 0x7c, 0x1b,
0xf2, 0x7c, 0xd0, 0x73, 0x22, 0x95, 0xe5, 0x85, 0x4d, 0xb4, 0x95, 0xb2, 0x73, 0x7c, 0xd0, 0x7b,
0x64, 0x48, 0xf2, 0x62, 0x01, 0xed, 0xf9, 0x82, 0x3a, 0xc4, 0x75, 0x83, 0x72, 0x5a, 0x5f, 0x4c,
0x93, 0x1e, 0xb9, 0x6e, 0x80, 0xef, 0xc0, 0xb2, 0x61, 0x68, 0x05, 0xe6, 0xf6, 0x8b, 0x8a, 0x69,
0x49, 0x93, 0x1b, 0x81, 0x36, 0xc0, 0x90, 0xaf, 0x43, 0xcf, 0x35, 0x5f, 0x66, 0x94, 0xef, 0x90,
0x9e, 0x2b, 0xbe, 0x7b, 0x80, 0x23, 0x79, 0x64, 0x28, 0x32, 0xab, 0x58, 0x8d, 0x84, 0x06, 0x31,
0x42, 0xad, 0x3f, 0x21, 0x58, 0x1b, 0x77, 0x47, 0xd8, 0xf7, 0x79, 0x48, 0xf1, 0x77, 0x20, 0xad,
0xed, 0xa0, 0x5c, 0x91, 0x9b, 0x6f, 0xea, 0xf1, 0xf3, 0xb6, 0x39, 0x8d, 0x7f, 0x00, 0xc5, 0x88,
0xcb, 0x69, 0x29, 0x45, 0xae, 0x72, 0x5e, 0xae, 0xfe, 0x60, 0x9e, 0xc4, 0x7d, 0xda, 0xf7, 0x43,
0x26, 0xf6, 0x89, 0x20, 0xb1, 0xd8, 0xe5, 0x88, 0x41, 0x83, 0x76, 0xad, 0x3f, 0x22, 0xb8, 0xd6,
0x74, 0x99, 0xd0, 0xea, 0x1b, 0x3e, 0xff, 0x94, 0x79, 0x23, 0x31, 0x35, 0x6a, 0x7a, 0x74, 0x19,
0xd3, 0x27, 0x2e, 0x69, 0xfa, 0xe4, 0xe5, 0x4d, 0x9f, 0x9a, 0x6e, 0xfa, 0x0f, 0xa1, 0xfc, 0x11,
0xe5, 0x34, 0x20, 0x82, 0x3e, 0x33, 0xf1, 0x14, 0x5b, 0x7f, 0x34, 0xe6, 0xd0, 0x78, 0xcc, 0x59,
0x7f, 0x4e, 0x40, 0x61, 0xc2, 0x59, 0x73, 0x93, 0xe7, 0x13, 0x58, 0x1e, 0x86, 0xbe, 0xd3, 0x61,
0xdc, 0x7d, 0xcb, 0x0c, 0x2a, 0x74, 0xc6, 0xd6, 0xf8, 0x33, 0x58, 0x19, 0x11, 0xdc, 0x52, 0xe6,
0x2f, 0x27, 0x37, 0x93, 0x5b, 0xb9, 0xfa, 0xfe, 0xd5, 0x22, 0x66, 0x44, 0x93, 0xf6, 0x62, 0x93,
0x8b, 0xe0, 0xdc, 0x2e, 0x76, 0x26, 0xc8, 0x95, 0x06, 0xac, 0x4f, 0x65, 0xc5, 0x45, 0x48, 0x76,
0xe8, 0xb9, 0xb9, 0xbd, 0xfc, 0xc4, 0x6b, 0xb0, 0x70, 0x42, 0xba, 0x03, 0x6a, 0xbc, 0xaa, 0x17,
0x7b, 0x89, 0x5d, 0x64, 0xfd, 0x1c, 0xc1, 0xea, 0x53, 0x16, 0x8a, 0x28, 0x4d, 0xa3, 0x90, 0xb9,
0x0f, 0xab, 0x1e, 0x15, 0x8e, 0xab, 0x43, 0xcf, 0x11, 0x67, 0x8e, 0x4b, 0x04, 0x51, 0x32, 0x33,
0x76, 0xd1, 0xa3, 0xc2, 0x04, 0xe5, 0xd1, 0x99, 0x0c, 0x4b, 0x7c, 0x1d, 0xb2, 0x7d, 0xe2, 0x51,
0x27, 0x64, 0xaf, 0xb4, 0x92, 0x05, 0x3b, 0x23, 0x09, 0x1f, 0xb3, 0x57, 0x14, 0xdf, 0x04, 0x50,
0x9b, 0xc2, 0xef, 0x50, 0x6e, 0x02, 0x46, 0xb1, 0x1f, 0x49, 0x82, 0x84, 0x4b, 0xba, 0x5d, 0x15,
0x1d, 0x19, 0x5b, 0x7e, 0x5a, 0xaf, 0x11, 0xac, 0x8d, 0x83, 0x32, 0xfe, 0x6d, 0x40, 0x26, 0x2e,
0x31, 0x48, 0x19, 0xf7, 0xee, 0x3c, 0xe3, 0x1a, 0x19, 0x76, 0x7c, 0x50, 0x06, 0x31, 0xa7, 0x67,
0x32, 0x44, 0x62, 0x4c, 0x26, 0xd8, 0x25, 0xf9, 0x65, 0x8c, 0xeb, 0x26, 0x80, 0xf0, 0x05, 0xe9,
0xea, 0x4b, 0x25, 0xd5, 0xa5, 0xb2, 0x8a, 0x22, 0x6f, 0x65, 0xfd, 0x1e, 0xc1, 0xa2, 0x11, 0x8e,
0xeb, 0xb0, 0x6e, 0xb4, 0x33, 0xee, 0x39, 0xfd, 0xc1, 0x71, 0x97, 0xb5, 0x9c, 0xc8, 0x07, 0x79,
0x7b, 0x75, 0xb8, 0xf9, 0x52, 0xed, 0x1d, 0xd2, 0x73, 0x59, 0x32, 0x0d, 0x24, 0x87, 0x93, 0x5e,
0xe4, 0x9a, 0x9c, 0xa1, 0x3d, 0x27, 0x3d, 0x2a, 0x91, 0x4e, 0x3a, 0x20, 0xa9, 0x04, 0x2e, 0xb9,
0x63, 0xd6, 0xbf, 0x2b, 0xf9, 0x02, 0x76, 0xa2, 0x9a, 0xd5, 0x68, 0xae, 0x15, 0x86, 0x64, 0x95,
0x6a, 0x87, 0x50, 0x88, 0xec, 0x31, 0x2c, 0x0d, 0x43, 0xb8, 0xda, 0xa8, 0x79, 0x1b, 0xfa, 0x11,
0xca, 0x10, 0x97, 0x61, 0x91, 0x71, 0x97, 0xb5, 0x68, 0x58, 0x4e, 0x6c, 0x26, 0xb7, 0x52, 0x76,
0xb4, 0xb4, 0x9e, 0x40, 0xee, 0xd1, 0x40, 0xb4, 0x23, 0x49, 0x15, 0xc8, 0xc4, 0x0d, 0xc4, 0xa4,
0x6a, 0xb4, 0x96, 0xa6, 0x34, 0x79, 0xe9, 0xb2, 0xc0, 0xdc, 0x34, 0xab, 0x29, 0xfb, 0x2c, 0xb0,
0x5e, 0x40, 0x5e, 0x4b, 0x32, 0x6e, 0x5e, 0x83, 0x05, 0xed, 0x17, 0x2d, 0x47, 0x2f, 0xf0, 0x36,
0x14, 0xd5, 0x87, 0x43, 0xcf, 0xfa, 0x2c, 0x50, 0x97, 0x52, 0xa2, 0x52, 0xf6, 0xb2, 0xa2, 0x37,
0x63, 0xb2, 0xf5, 0x77, 0x04, 0xa5, 0xe7, 0xbe, 0x4b, 0x1b, 0x3e, 0xe7, 0xb4, 0x25, 0x49, 0xb1,
0xec, 0xf7, 0x61, 0xed, 0x98, 0x92, 0x96, 0xcf, 0x1d, 0xee, 0xbb, 0xd4, 0xa1, 0xdc, 0xed, 0xfb,
0x8c, 0x0b, 0xa3, 0x0a, 0xeb, 0x3d, 0x79, 0xb6, 0x69, 0x76, 0xf0, 0x0d, 0xc8, 0xb6, 0xb4, 0x1c,
0x53, 0xb2, 0x33, 0xf6, 0x90, 0x20, 0xed, 0x13, 0x9e, 0xf3, 0x16, 0xe3, 0x9e, 0xf2, 0x4d, 0xc6,
0x8e, 0x96, 0xd2, 0xc1, 0x1e, 0xe5, 0x34, 0x64, 0xa1, 0x23, 0x58, 0x8f, 0x2a, 0x97, 0xa4, 0xec,
0x9c, 0xa1, 0x1d, 0xb1, 0x1e, 0xc5, 0xbb, 0x50, 0x8e, 0x1c, 0xdc, 0xf2, 0xb9, 0x08, 0x48, 0x4b,
0xa8, 0x12, 0x4d, 0x43, 0xdd, 0x42, 0xf3, 0x76, 0xc9, 0xec, 0x37, 0xcc, 0xf6, 0x23, 0xbd, 0x6b,
0x7d, 0x81, 0x60, 0xbd, 0xd1, 0x26, 0xdc, 0xa3, 0x51, 0x7f, 0x8e, 0xfc, 0xb0, 0x0d, 0xc5, 0xd6,
0x20, 0x08, 0x28, 0x1f, 0x69, 0xe8, 0xfa, 0x72, 0xcb, 0x86, 0x3e, 0xda, 0xd1, 0x63, 0x96, 0xc4,
0x84, 0xcb, 0x1e, 0xc0, 0x7a, 0xf4, 0xad, 0xcb, 0x59, 0xd0, 0xd3, 0x26, 0xd7, 0xf9, 0xbb, 0x16,
0x6d, 0x36, 0x46, 0xf6, 0xac, 0x5d, 0x58, 0x79, 0x42, 0xc2, 0x89, 0xa2, 0xfc, 0x0e, 0x2c, 0x19,
0xe7, 0xd3, 0x33, 0x16, 0xaa, 0xcc, 0x95, 0x76, 0xca, 0x6b, 0x62, 0x53, 0xd1, 0xac, 0x13, 0x28,
0x1d, 0xf4, 0xfa, 0x7e, 0x20, 0x64, 0xd0, 0x09, 0x3f, 0xa0, 0x23, 0x95, 0x08, 0x77, 0x22, 0x9a,
0xc3, 0x14, 0x0f, 0x75, 0x55, 0xa0, 0x66, 0xed, 0x95, 0x78, 0xe7, 0xc0, 0x6c, 0x8c, 0xb3, 0x4f,
0xdc, 0x6e, 0xc8, 0x1e, 0x99, 0xc0, 0x3a, 0x84, 0x6b, 0x17, 0xf4, 0x0e, 0x23, 0x25, 0x52, 0xe7,
0x5c, 0xcc, 0x11, 0x1c, 0xed, 0xc5, 0x19, 0x1d, 0x5a, 0xdf, 0x8c, 0x66, 0x88, 0x89, 0x24, 0x9b,
0x9c, 0x8e, 0xd0, 0x85, 0xe9, 0xc8, 0xfa, 0x15, 0x82, 0x82, 0x29, 0xa9, 0xcf, 0x68, 0x18, 0x12,
0x8f, 0xe2, 0x6d, 0x48, 0xf7, 0x07, 0xc7, 0x71, 0x15, 0x79, 0xbc, 0xf2, 0xef, 0x2f, 0x6f, 0x2d,
0x85, 0xe1, 0xab, 0xfb, 0xb2, 0x1e, 0xed, 0x59, 0x1f, 0xec, 0x5a, 0xb6, 0x61, 0xc0, 0x4f, 0xa0,
0x74, 0xca, 0x44, 0xdb, 0x0d, 0xc8, 0x29, 0xe9, 0xca, 0xf1, 0xc2, 0xa5, 0x5c, 0x30, 0xd2, 0x0d,
0xd5, 0xc5, 0x2f, 0x1c, 0x7d, 0x50, 0xb7, 0xec, 0xf5, 0xe1, 0x81, 0xc6, 0x90, 0x1f, 0x97, 0x20,
0x4d, 0x7a, 0x12, 0x92, 0xf2, 0x73, 0xca, 0x36, 0x2b, 0xeb, 0xb7, 0x09, 0x58, 0x9d, 0x32, 0x87,
0xe0, 0x0e, 0xac, 0x44, 0x11, 0x2c, 0xeb, 0x93, 0xd3, 0x65, 0xa1, 0x30, 0xa5, 0xf9, 0xdb, 0x6f,
0x31, 0xd7, 0x8c, 0xd1, 0xa2, 0xe2, 0x27, 0x17, 0xb2, 0x1d, 0x54, 0x7e, 0x83, 0x20, 0x37, 0xc2,
0x80, 0xbf, 0x0f, 0x29, 0xd3, 0x95, 0xa4, 0xbe, 0x83, 0xff, 0x51, 0x5f, 0x55, 0xfe, 0xe8, 0x66,
0xab, 0xc4, 0x56, 0x1e, 0x42, 0x36, 0x26, 0x5d, 0xa9, 0xa9, 0xee, 0xc2, 0xfa, 0x3e, 0xed, 0xd2,
0x38, 0x0e, 0xc2, 0xcb, 0x56, 0x5b, 0xeb, 0x5b, 0x50, 0x9a, 0x3c, 0x69, 0x0c, 0x7d, 0x1b, 0xf2,
0xae, 0xda, 0x71, 0x47, 0xcf, 0xe6, 0x0c, 0x4d, 0x1e, 0xde, 0x79, 0x08, 0x85, 0xf1, 0x29, 0x05,
0xe7, 0x60, 0x71, 0xbf, 0x69, 0x1f, 0x7c, 0xb7, 0xb9, 0x5f, 0xfc, 0x0a, 0xce, 0x43, 0xe6, 0xe0,
0xd9, 0xcb, 0x17, 0xf6, 0x51, 0x73, 0xbf, 0x88, 0x30, 0x40, 0xda, 0x6e, 0x3e, 0x7b, 0x71, 0xd4,
0x2c, 0x26, 0xea, 0x3f, 0x59, 0x84, 0xb4, 0x4e, 0x5a, 0xfc, 0x43, 0xc8, 0xc6, 0x19, 0x8c, 0x4b,
0x55, 0xfd, 0xe0, 0xa9, 0x46, 0x4f, 0x99, 0x6a, 0x53, 0x3e, 0x78, 0x2a, 0x5f, 0x9f, 0x67, 0xe9,
0x0b, 0x45, 0xc0, 0x7a, 0xe7, 0xf3, 0xbf, 0xfd, 0xf3, 0x8b, 0xc4, 0x4d, 0x7c, 0x5d, 0xbe, 0xc9,
0x86, 0x2f, 0x35, 0x5d, 0x03, 0x6a, 0xba, 0x30, 0xe0, 0x5f, 0x23, 0xc8, 0x8f, 0x0e, 0xe1, 0x78,
0xee, 0x68, 0x3c, 0xe5, 0x05, 0x55, 0xf9, 0xe0, 0x6a, 0x87, 0x0c, 0xc0, 0x3b, 0x0a, 0xe0, 0xa6,
0x35, 0x1d, 0xa0, 0x9e, 0xd8, 0xf7, 0xd0, 0x0e, 0x7e, 0x8d, 0x00, 0xe4, 0x9c, 0xad, 0x07, 0x2e,
0xfc, 0x70, 0x9e, 0xb2, 0x19, 0x33, 0x79, 0xe5, 0x8a, 0xef, 0x08, 0xeb, 0x9e, 0xc2, 0xf7, 0xae,
0xb5, 0x39, 0x1d, 0x9f, 0x92, 0x5d, 0xa3, 0x2e, 0x13, 0x12, 0xa4, 0x80, 0xfc, 0xa8, 0xce, 0x99,
0x8e, 0xbc, 0x2a, 0x88, 0x1b, 0x0a, 0x44, 0x09, 0xaf, 0x4d, 0x03, 0x81, 0x7f, 0x86, 0xa0, 0x38,
0x39, 0xc9, 0xcf, 0x54, 0xbd, 0x3b, 0x4f, 0xf5, 0xac, 0x37, 0x81, 0x75, 0x57, 0x81, 0xb8, 0x8d,
0x6f, 0x8d, 0x83, 0x88, 0xde, 0x05, 0x35, 0xcf, 0x1c, 0xc4, 0x7f, 0x40, 0xb0, 0x3c, 0x51, 0xdc,
0xf1, 0x87, 0xf3, 0xd4, 0x4e, 0xef, 0x42, 0x95, 0x87, 0x57, 0x3e, 0x67, 0xd0, 0xbe, 0xaf, 0xd0,
0xee, 0x58, 0xef, 0x4e, 0xf5, 0x5b, 0xdc, 0x90, 0x6a, 0xba, 0x9d, 0xec, 0xa1, 0x9d, 0xfa, 0x97,
0x49, 0xc8, 0xc4, 0xaf, 0xe6, 0xdf, 0x21, 0x58, 0x1a, 0xeb, 0x29, 0xf8, 0x92, 0xe1, 0x3d, 0xde,
0x82, 0x2a, 0x6f, 0xf3, 0xc8, 0xb4, 0x6a, 0x0a, 0xfb, 0xb6, 0xf5, 0xb5, 0xa9, 0xd8, 0xe3, 0x7f,
0x59, 0x86, 0xc9, 0xf1, 0x4b, 0x04, 0xf9, 0xd1, 0xc1, 0x7d, 0x7e, 0x02, 0x4f, 0x79, 0x7b, 0xcc,
0x4f, 0xe0, 0x69, 0x6f, 0x03, 0x6b, 0x43, 0x81, 0x2d, 0xe3, 0xd2, 0x38, 0xd8, 0x78, 0xec, 0xff,
0x31, 0x82, 0xc2, 0xf8, 0xc4, 0x84, 0xbf, 0x31, 0xd7, 0x94, 0xd3, 0x26, 0xac, 0xca, 0x8c, 0x90,
0x9e, 0x55, 0x42, 0xa2, 0x21, 0x24, 0xca, 0xce, 0xfa, 0x6b, 0x04, 0xe9, 0x27, 0x94, 0x74, 0x45,
0x1b, 0xff, 0x02, 0xc1, 0xb5, 0x8f, 0xa8, 0x78, 0x1c, 0x4f, 0x9d, 0xc3, 0x89, 0x75, 0x66, 0xe6,
0xcc, 0x0d, 0xe1, 0xe9, 0x93, 0xaf, 0xf5, 0x9e, 0x82, 0x77, 0x07, 0x4f, 0x78, 0xb3, 0xad, 0x90,
0xd4, 0xd4, 0x34, 0xdc, 0x8a, 0x4f, 0xd5, 0xff, 0x95, 0x80, 0x94, 0x1c, 0xca, 0xf1, 0xe7, 0x08,
0x16, 0x9e, 0xfa, 0x1e, 0xe3, 0xf8, 0xde, 0xdc, 0xb7, 0xd6, 0xf0, 0x39, 0x50, 0x79, 0xef, 0x72,
0xcc, 0xe3, 0xce, 0xb3, 0x56, 0xc7, 0xb1, 0x75, 0xa5, 0x5e, 0x19, 0x58, 0x3f, 0x42, 0x90, 0xfe,
0x98, 0x79, 0x7c, 0xd0, 0xff, 0x7f, 0xa2, 0xb8, 0xa5, 0x50, 0x7c, 0xd5, 0x9a, 0x28, 0x6f, 0xa1,
0x52, 0x2c, 0x61, 0x7c, 0x0f, 0xd2, 0x4f, 0x7d, 0xcf, 0x1f, 0xcc, 0x6e, 0x8d, 0xb3, 0x62, 0x63,
0x86, 0xe8, 0xae, 0x92, 0xb6, 0x87, 0x76, 0x1e, 0xe7, 0xff, 0xf2, 0x66, 0x03, 0xfd, 0xf5, 0xcd,
0x06, 0xfa, 0xc7, 0x9b, 0x0d, 0x74, 0x9c, 0x56, 0xc7, 0x1f, 0xfc, 0x27, 0x00, 0x00, 0xff, 0xff,
0x85, 0x27, 0xdc, 0xab, 0xdb, 0x14, 0x00, 0x00,
// 1788 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xb4, 0x57, 0xcb, 0x8f, 0x1b, 0x49,
0x19, 0xa7, 0x6c, 0x8f, 0xc7, 0xfe, 0xec, 0x78, 0x3c, 0x35, 0x33, 0x8e, 0x71, 0x92, 0xc9, 0xa4,
0x97, 0x4d, 0x26, 0x93, 0x8d, 0xbd, 0x38, 0xcb, 0x66, 0x34, 0x1c, 0x50, 0xe2, 0x31, 0x9b, 0xd1,
0xe4, 0xa5, 0xde, 0x11, 0x2b, 0x0e, 0xd0, 0xaa, 0x71, 0xd7, 0xb6, 0x4b, 0xb6, 0xab, 0xbd, 0xdd,
0xe5, 0x79, 0x84, 0xdb, 0x0a, 0x89, 0x03, 0x70, 0x61, 0x0f, 0x88, 0x03, 0x07, 0x22, 0x71, 0xe1,
0x04, 0x12, 0x12, 0x37, 0x0e, 0x9c, 0x38, 0x22, 0x71, 0x07, 0x14, 0x71, 0xe5, 0xc2, 0x5f, 0x80,
0xea, 0xd1, 0xed, 0xb6, 0x63, 0xe3, 0x99, 0x45, 0x5c, 0x2c, 0xd7, 0xf7, 0xfc, 0xd5, 0xf7, 0xaa,
0xaf, 0xe1, 0xee, 0x30, 0xf0, 0x85, 0xdf, 0x38, 0x21, 0x7d, 0xe6, 0x12, 0xe1, 0x07, 0x0d, 0xd2,
0xe9, 0xf8, 0x23, 0x2e, 0xc2, 0xc6, 0x49, 0xb3, 0x71, 0x4a, 0x8f, 0x1d, 0x32, 0x64, 0x75, 0x25,
0x83, 0x37, 0xa9, 0xe8, 0xd2, 0x80, 0x8e, 0x06, 0xf5, 0x58, 0xba, 0x1e, 0x49, 0xd7, 0x4f, 0x9a,
0xb5, 0xeb, 0x9e, 0xef, 0x7b, 0x7d, 0xda, 0x20, 0x43, 0xd6, 0x20, 0x9c, 0xfb, 0x82, 0x08, 0xe6,
0xf3, 0x50, 0x6b, 0xd7, 0xae, 0x19, 0xae, 0x3a, 0x1d, 0x8f, 0x3e, 0x6d, 0xd0, 0xc1, 0x50, 0x9c,
0x1b, 0xe6, 0x7d, 0x8f, 0x89, 0xee, 0xe8, 0xb8, 0xde, 0xf1, 0x07, 0x0d, 0xcf, 0xf7, 0xfc, 0xb1,
0x94, 0x3c, 0x69, 0x88, 0xf2, 0x9f, 0x16, 0xb7, 0x7e, 0x92, 0x86, 0xb5, 0x56, 0x40, 0x89, 0xa0,
0x9f, 0x90, 0x7e, 0x9f, 0x0a, 0x9b, 0x7e, 0x36, 0xa2, 0xa1, 0xc0, 0x37, 0xa1, 0x70, 0xaa, 0x08,
0xce, 0x90, 0x88, 0x6e, 0x15, 0x6d, 0xa1, 0xed, 0xbc, 0x0d, 0x9a, 0xf4, 0x92, 0x88, 0x2e, 0x7e,
0x0e, 0xd0, 0xa3, 0xe7, 0x03, 0xc2, 0x89, 0x47, 0x83, 0x6a, 0x6a, 0x0b, 0x6d, 0x97, 0x9a, 0xf5,
0xfa, 0x7f, 0xbf, 0x57, 0xfd, 0x30, 0xd6, 0x38, 0x64, 0xdc, 0xb5, 0x13, 0x16, 0xf0, 0x1d, 0x58,
0x89, 0x1d, 0x86, 0xe1, 0xa9, 0x1f, 0xb8, 0xd5, 0xb4, 0x72, 0x5a, 0x8a, 0x9c, 0x6a, 0x2a, 0xae,
0x41, 0x6e, 0xc0, 0xe9, 0xc0, 0xe7, 0xac, 0x53, 0xcd, 0x28, 0x89, 0xf8, 0x8c, 0x6f, 0x41, 0x91,
0x8f, 0x06, 0x4e, 0xe4, 0xb2, 0xba, 0xb4, 0x85, 0xb6, 0x33, 0x76, 0x81, 0x8f, 0x06, 0x8f, 0x0c,
0x49, 0x5e, 0x2c, 0xa0, 0x03, 0x5f, 0x50, 0x87, 0xb8, 0x6e, 0x50, 0xcd, 0xea, 0x8b, 0x69, 0xd2,
0x23, 0xd7, 0x0d, 0xf0, 0x6d, 0x58, 0x31, 0x02, 0x9d, 0xc0, 0xdc, 0x7e, 0x59, 0x09, 0x5d, 0xd1,
0xe4, 0x56, 0xa0, 0x03, 0x30, 0x96, 0xeb, 0xd1, 0x73, 0x2d, 0x97, 0x4b, 0xca, 0x1d, 0xd2, 0x73,
0x25, 0x77, 0x0f, 0x70, 0x64, 0x8f, 0x8c, 0x4d, 0xe6, 0x95, 0xa8, 0xb1, 0xd0, 0x22, 0xc6, 0xa8,
0xf5, 0x47, 0x04, 0xeb, 0x93, 0xe9, 0x08, 0x87, 0x3e, 0x0f, 0x29, 0xfe, 0x36, 0x64, 0x75, 0x1c,
0x54, 0x2a, 0x0a, 0x8b, 0x43, 0x3d, 0xa9, 0x6f, 0x1b, 0x6d, 0xfc, 0x7d, 0x28, 0x47, 0x52, 0x4e,
0x47, 0x39, 0x72, 0x55, 0xf2, 0x0a, 0xcd, 0x07, 0x8b, 0x2c, 0xee, 0xd3, 0xa1, 0x1f, 0x32, 0xb1,
0x4f, 0x04, 0x89, 0xcd, 0xae, 0x44, 0x02, 0x1a, 0xb4, 0x6b, 0xfd, 0x01, 0xc1, 0xd5, 0xb6, 0xcb,
0x84, 0x76, 0xdf, 0xf2, 0xf9, 0xa7, 0xcc, 0x4b, 0xd4, 0x54, 0x32, 0xf4, 0xe8, 0x22, 0xa1, 0x4f,
0x5d, 0x30, 0xf4, 0xe9, 0x8b, 0x87, 0x3e, 0x33, 0x3b, 0xf4, 0x1f, 0x42, 0xf5, 0x23, 0xca, 0x69,
0x40, 0x04, 0x7d, 0x66, 0xea, 0x29, 0x8e, 0x7e, 0xb2, 0xe6, 0xd0, 0x64, 0xcd, 0x59, 0x7f, 0x4a,
0x41, 0x69, 0x2a, 0x59, 0x0b, 0x9b, 0xe7, 0x13, 0x58, 0x19, 0x97, 0xbe, 0xd3, 0x63, 0xdc, 0xfd,
0x92, 0x1d, 0x54, 0xea, 0x4d, 0x9c, 0xf1, 0x67, 0xb0, 0x9a, 0x30, 0xdc, 0x51, 0xe1, 0xaf, 0xa6,
0xb7, 0xd2, 0xdb, 0x85, 0xe6, 0xfe, 0xe5, 0x2a, 0x26, 0xe1, 0x49, 0x67, 0xb1, 0xcd, 0x45, 0x70,
0x6e, 0x97, 0x7b, 0x53, 0xe4, 0x5a, 0x0b, 0x36, 0x66, 0x8a, 0xe2, 0x32, 0xa4, 0x7b, 0xf4, 0xdc,
0xdc, 0x5e, 0xfe, 0xc5, 0xeb, 0xb0, 0x74, 0x42, 0xfa, 0x23, 0x6a, 0xb2, 0xaa, 0x0f, 0x7b, 0xa9,
0x5d, 0x64, 0xfd, 0x0c, 0xc1, 0xda, 0x53, 0x16, 0x8a, 0xa8, 0x4d, 0xa3, 0x92, 0xb9, 0x0f, 0x6b,
0x1e, 0x15, 0x8e, 0xab, 0x4b, 0xcf, 0x11, 0x67, 0x8e, 0x4b, 0x04, 0x51, 0x36, 0x73, 0x76, 0xd9,
0xa3, 0xc2, 0x14, 0xe5, 0xd1, 0x99, 0x2c, 0x4b, 0x7c, 0x0d, 0xf2, 0x43, 0xe2, 0x51, 0x27, 0x64,
0xaf, 0xb4, 0x93, 0x25, 0x3b, 0x27, 0x09, 0x1f, 0xb3, 0x57, 0x14, 0xdf, 0x00, 0x50, 0x4c, 0xe1,
0xf7, 0x28, 0x37, 0x05, 0xa3, 0xc4, 0x8f, 0x24, 0x41, 0xc2, 0x25, 0xfd, 0xbe, 0xaa, 0x8e, 0x9c,
0x2d, 0xff, 0x5a, 0xaf, 0x11, 0xac, 0x4f, 0x82, 0x32, 0xf9, 0x6d, 0x41, 0x2e, 0x1e, 0x31, 0x48,
0x05, 0xf7, 0xce, 0xa2, 0xe0, 0x1a, 0x1b, 0x76, 0xac, 0x28, 0x8b, 0x98, 0xd3, 0x33, 0x59, 0x22,
0x31, 0x26, 0x53, 0xec, 0x92, 0xfc, 0x32, 0xc6, 0x75, 0x03, 0x40, 0xf8, 0x82, 0xf4, 0xf5, 0xa5,
0xd2, 0xea, 0x52, 0x79, 0x45, 0x91, 0xb7, 0xb2, 0x7e, 0x87, 0x60, 0xd9, 0x18, 0xc7, 0x4d, 0xd8,
0x30, 0xde, 0x19, 0xf7, 0x9c, 0xe1, 0xe8, 0xb8, 0xcf, 0x3a, 0x4e, 0x94, 0x83, 0xa2, 0xbd, 0x36,
0x66, 0xbe, 0x54, 0xbc, 0x43, 0x7a, 0x2e, 0x47, 0xa6, 0x81, 0xe4, 0x70, 0x32, 0x88, 0x52, 0x53,
0x30, 0xb4, 0xe7, 0x64, 0x40, 0x25, 0xd2, 0xe9, 0x04, 0xa4, 0x95, 0xc1, 0x2b, 0xee, 0x44, 0xf4,
0xef, 0x48, 0xb9, 0x80, 0x9d, 0xa8, 0xc7, 0x2a, 0xd9, 0x6b, 0xa5, 0x31, 0x59, 0xb5, 0xda, 0x21,
0x94, 0xa2, 0x78, 0x8c, 0x47, 0xc3, 0x18, 0xae, 0x0e, 0x6a, 0xd1, 0x86, 0x61, 0x84, 0x32, 0xc4,
0x55, 0x58, 0x66, 0xdc, 0x65, 0x1d, 0x1a, 0x56, 0x53, 0x5b, 0xe9, 0xed, 0x8c, 0x1d, 0x1d, 0xad,
0x27, 0x50, 0x78, 0x34, 0x12, 0xdd, 0xc8, 0x52, 0x0d, 0x72, 0xf1, 0x03, 0x62, 0x5a, 0x35, 0x3a,
0xcb, 0x50, 0x9a, 0xbe, 0x74, 0x59, 0x60, 0x6e, 0x9a, 0xd7, 0x94, 0x7d, 0x16, 0x58, 0x2f, 0xa0,
0xa8, 0x2d, 0x99, 0x34, 0xaf, 0xc3, 0x92, 0xce, 0x8b, 0xb6, 0xa3, 0x0f, 0xf8, 0x2e, 0x94, 0xd5,
0x1f, 0x87, 0x9e, 0x0d, 0x59, 0xa0, 0x2e, 0xa5, 0x4c, 0x65, 0xec, 0x15, 0x45, 0x6f, 0xc7, 0x64,
0xeb, 0xef, 0x08, 0x2a, 0xcf, 0x7d, 0x97, 0xb6, 0x7c, 0xce, 0x69, 0x47, 0x92, 0x62, 0xdb, 0xef,
0xc3, 0xfa, 0x31, 0x25, 0x1d, 0x9f, 0x3b, 0xdc, 0x77, 0xa9, 0x43, 0xb9, 0x3b, 0xf4, 0x19, 0x17,
0xc6, 0x15, 0xd6, 0x3c, 0xa9, 0xdb, 0x36, 0x1c, 0x7c, 0x1d, 0xf2, 0x1d, 0x6d, 0xc7, 0x8c, 0xec,
0x9c, 0x3d, 0x26, 0xc8, 0xf8, 0x84, 0xe7, 0xbc, 0xc3, 0xb8, 0xa7, 0x72, 0x93, 0xb3, 0xa3, 0xa3,
0x4c, 0xb0, 0x47, 0x39, 0x0d, 0x59, 0xe8, 0x08, 0x36, 0xa0, 0x2a, 0x25, 0x19, 0xbb, 0x60, 0x68,
0x47, 0x6c, 0x40, 0xf1, 0x2e, 0x54, 0xa3, 0x04, 0x77, 0x7c, 0x2e, 0x02, 0xd2, 0x11, 0x6a, 0x44,
0xd3, 0x50, 0x3f, 0xa1, 0x45, 0xbb, 0x62, 0xf8, 0x2d, 0xc3, 0x7e, 0xa4, 0xb9, 0xd6, 0x17, 0x08,
0x36, 0x5a, 0x5d, 0xc2, 0x3d, 0x1a, 0xbd, 0xcf, 0x51, 0x1e, 0xee, 0x42, 0xb9, 0x33, 0x0a, 0x02,
0xca, 0x13, 0x0f, 0xba, 0xbe, 0xdc, 0x8a, 0xa1, 0x27, 0x5f, 0xf4, 0x58, 0x24, 0x35, 0x95, 0xb2,
0x07, 0xb0, 0x11, 0xfd, 0xd7, 0xe3, 0x2c, 0x18, 0xe8, 0x90, 0xeb, 0xfe, 0x5d, 0x8f, 0x98, 0xad,
0x04, 0xcf, 0xda, 0x85, 0xd5, 0x27, 0x24, 0x9c, 0x1a, 0xca, 0xef, 0xc0, 0x15, 0x93, 0x7c, 0x7a,
0xc6, 0x42, 0xd5, 0xb9, 0x32, 0x4e, 0x45, 0x4d, 0x6c, 0x2b, 0x9a, 0x75, 0x02, 0x95, 0x83, 0xc1,
0xd0, 0x0f, 0x84, 0x2c, 0x3a, 0xe1, 0x07, 0x34, 0x31, 0x89, 0x70, 0x2f, 0xa2, 0x39, 0x4c, 0xc9,
0x50, 0x57, 0x15, 0x6a, 0xde, 0x5e, 0x8d, 0x39, 0x07, 0x86, 0x31, 0x29, 0x3e, 0x75, 0xbb, 0xb1,
0x78, 0x14, 0x02, 0xeb, 0x10, 0xae, 0xbe, 0xe5, 0x77, 0x5c, 0x29, 0x91, 0x3b, 0xe7, 0xed, 0x1e,
0xc1, 0x11, 0x2f, 0xee, 0xe8, 0xd0, 0xfa, 0x25, 0x82, 0x92, 0x99, 0x8b, 0xcf, 0x68, 0x18, 0x12,
0x8f, 0xe2, 0xbb, 0x90, 0x1d, 0x8e, 0x8e, 0xe3, 0x51, 0xf0, 0x78, 0xf5, 0xdf, 0x7f, 0xbb, 0x79,
0x25, 0x0c, 0x5f, 0xdd, 0x97, 0x43, 0x65, 0xcf, 0xfa, 0x60, 0xd7, 0xb2, 0x8d, 0x00, 0x7e, 0x02,
0x95, 0x53, 0x26, 0xba, 0x6e, 0x40, 0x4e, 0x49, 0x5f, 0xee, 0x08, 0x2e, 0xe5, 0x82, 0x91, 0x7e,
0xa8, 0xd0, 0xbf, 0xa5, 0xfa, 0xa0, 0x69, 0xd9, 0x1b, 0x63, 0x85, 0xd6, 0x58, 0x1e, 0x57, 0x20,
0x4b, 0x06, 0xb2, 0xcb, 0x55, 0xb2, 0x32, 0xb6, 0x39, 0x59, 0xbf, 0x49, 0xc1, 0xda, 0x8c, 0x65,
0x02, 0xf7, 0x60, 0x35, 0x2a, 0x43, 0x39, 0x64, 0x9c, 0x3e, 0x0b, 0x85, 0x99, 0xaf, 0xdf, 0xfa,
0x12, 0xcb, 0xc9, 0x04, 0x2d, 0x9a, 0x60, 0xf2, 0x20, 0x67, 0x7a, 0xed, 0xd7, 0x08, 0x0a, 0x09,
0x01, 0xfc, 0x3d, 0xc8, 0x98, 0xa7, 0x45, 0xfa, 0x3b, 0xf8, 0x1f, 0xfd, 0xd5, 0xe5, 0x8f, 0x7e,
0x31, 0x95, 0xd9, 0xda, 0x43, 0xc8, 0xc7, 0xa4, 0x4b, 0xbd, 0x8c, 0xbb, 0xb0, 0xb1, 0x4f, 0xfb,
0x54, 0xd0, 0xe9, 0xa7, 0x71, 0xd1, 0xc8, 0xb4, 0xbe, 0x09, 0x95, 0x69, 0x4d, 0x13, 0xe8, 0x5b,
0x50, 0x74, 0x15, 0xc7, 0x4d, 0xea, 0x16, 0x0c, 0x4d, 0x2a, 0xef, 0x3c, 0x84, 0xd2, 0xe4, 0xaa,
0x81, 0x0b, 0xb0, 0xbc, 0xdf, 0xb6, 0x0f, 0xbe, 0xd3, 0xde, 0x2f, 0x7f, 0x05, 0x17, 0x21, 0x77,
0xf0, 0xec, 0xe5, 0x0b, 0xfb, 0xa8, 0xbd, 0x5f, 0x46, 0x18, 0x20, 0x6b, 0xb7, 0x9f, 0xbd, 0x38,
0x6a, 0x97, 0x53, 0xcd, 0x1f, 0x2f, 0x43, 0x56, 0x77, 0x1e, 0xfe, 0x01, 0xe4, 0xe3, 0x36, 0xc4,
0x95, 0xba, 0xfe, 0x6a, 0xa9, 0x47, 0xdf, 0x23, 0xf5, 0xb6, 0xfc, 0x6a, 0xa9, 0x7d, 0x7d, 0x51,
0xa4, 0xdf, 0xea, 0x64, 0xeb, 0x9d, 0xcf, 0xff, 0xfa, 0xcf, 0x2f, 0x52, 0x37, 0xf0, 0x35, 0xf9,
0x61, 0x35, 0xfe, 0xdc, 0xd2, 0x8d, 0xdc, 0xd0, 0xdd, 0x8d, 0x7f, 0x85, 0xa0, 0x98, 0xdc, 0xa4,
0xf1, 0xc2, 0xfd, 0x76, 0xc6, 0x67, 0x50, 0xed, 0x83, 0xcb, 0x29, 0x19, 0x80, 0xb7, 0x15, 0xc0,
0x2d, 0x6b, 0x36, 0x40, 0xbd, 0x76, 0xef, 0xa1, 0x1d, 0xfc, 0x1a, 0x01, 0xc8, 0x65, 0x59, 0x6f,
0x4d, 0xf8, 0xe1, 0x22, 0x67, 0x73, 0x16, 0xeb, 0xda, 0x25, 0x3f, 0x06, 0xac, 0x7b, 0x0a, 0xdf,
0xbb, 0xd6, 0xd6, 0x6c, 0x7c, 0xca, 0x76, 0x83, 0xba, 0x4c, 0x48, 0x90, 0x02, 0x8a, 0x49, 0x9f,
0x73, 0x13, 0x79, 0x59, 0x10, 0xd7, 0x15, 0x88, 0x0a, 0x5e, 0x9f, 0x05, 0x02, 0xff, 0x14, 0x41,
0x79, 0x7a, 0x1d, 0x9f, 0xeb, 0x7a, 0x77, 0x91, 0xeb, 0x79, 0x8b, 0xbd, 0x75, 0x47, 0x81, 0xb8,
0x85, 0x6f, 0x4e, 0x82, 0x88, 0x96, 0xfb, 0x86, 0x67, 0x14, 0xf1, 0xef, 0x11, 0xac, 0x4c, 0x4d,
0x68, 0xfc, 0xe1, 0x22, 0xb7, 0xb3, 0x9f, 0x92, 0xda, 0xc3, 0x4b, 0xeb, 0x19, 0xb4, 0xef, 0x2b,
0xb4, 0x3b, 0xd6, 0xbb, 0x33, 0xf3, 0x16, 0xbf, 0x2a, 0x0d, 0xfd, 0x26, 0xec, 0xa1, 0x9d, 0xe6,
0x6f, 0x53, 0x90, 0x8b, 0x3f, 0x7d, 0x7f, 0x81, 0xa0, 0x98, 0xdc, 0x67, 0x17, 0xb7, 0xc4, 0x8c,
0x95, 0x7c, 0x71, 0x4b, 0xcc, 0x5a, 0x99, 0xad, 0x4d, 0x05, 0xbd, 0x8a, 0x2b, 0x93, 0xd0, 0xe3,
0x6d, 0xf8, 0x47, 0x08, 0x4a, 0x93, 0x8b, 0x04, 0xfe, 0xc6, 0xc2, 0xde, 0x9b, 0xb5, 0x78, 0xd4,
0xe6, 0x14, 0xc9, 0xbc, 0xa6, 0x8c, 0xde, 0xe6, 0xa8, 0xde, 0x9b, 0xaf, 0x11, 0x64, 0x9f, 0x50,
0xd2, 0x17, 0x5d, 0xfc, 0x73, 0x04, 0x57, 0x3f, 0xa2, 0xe2, 0x71, 0xbc, 0x8c, 0x8d, 0x17, 0xb9,
0xb9, 0xb5, 0xb8, 0xb0, 0x28, 0x66, 0x2f, 0x84, 0xd6, 0x7b, 0x0a, 0xde, 0x6d, 0xfc, 0xb5, 0x49,
0x78, 0x5d, 0x85, 0xa4, 0xa1, 0x96, 0xc4, 0x4e, 0xac, 0xd5, 0xfc, 0x57, 0x0a, 0x32, 0x72, 0x57,
0xc5, 0x9f, 0x23, 0x58, 0x7a, 0xea, 0x7b, 0x8c, 0xe3, 0x7b, 0x0b, 0x3f, 0x41, 0xc6, 0x5b, 0x72,
0xed, 0xbd, 0x8b, 0x09, 0x4f, 0x26, 0xcf, 0x5a, 0x9b, 0xc4, 0xd6, 0x97, 0x7e, 0xe5, 0x88, 0xf8,
0x21, 0x82, 0xec, 0xc7, 0xcc, 0xe3, 0xa3, 0xe1, 0xff, 0x13, 0xc5, 0x4d, 0x85, 0xe2, 0xab, 0xd6,
0xd4, 0xc0, 0x08, 0x95, 0x63, 0x09, 0xe3, 0xbb, 0x90, 0x7d, 0xea, 0x7b, 0xfe, 0x68, 0xfe, 0x63,
0x33, 0xaf, 0x36, 0xe6, 0x98, 0xee, 0x2b, 0x6b, 0x7b, 0x68, 0xe7, 0x71, 0xf1, 0xcf, 0x6f, 0x36,
0xd1, 0x5f, 0xde, 0x6c, 0xa2, 0x7f, 0xbc, 0xd9, 0x44, 0xc7, 0x59, 0xa5, 0xfe, 0xe0, 0x3f, 0x01,
0x00, 0x00, 0xff, 0xff, 0x8c, 0xff, 0xde, 0xba, 0xf2, 0x13, 0x00, 0x00,
}
// Reference imports to suppress errors if they are not otherwise used.
@@ -1779,7 +1728,6 @@ var _Wallet_serviceDesc = grpc.ServiceDesc{
//
// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream.
type AccountsClient interface {
CreateAccount(ctx context.Context, in *CreateAccountRequest, opts ...grpc.CallOption) (*DepositDataResponse, error)
ListAccounts(ctx context.Context, in *ListAccountsRequest, opts ...grpc.CallOption) (*ListAccountsResponse, error)
ChangePassword(ctx context.Context, in *ChangePasswordRequest, opts ...grpc.CallOption) (*types.Empty, error)
}
@@ -1792,15 +1740,6 @@ func NewAccountsClient(cc *grpc.ClientConn) AccountsClient {
return &accountsClient{cc}
}
func (c *accountsClient) CreateAccount(ctx context.Context, in *CreateAccountRequest, opts ...grpc.CallOption) (*DepositDataResponse, error) {
out := new(DepositDataResponse)
err := c.cc.Invoke(ctx, "/ethereum.validator.accounts.v2.Accounts/CreateAccount", in, out, opts...)
if err != nil {
return nil, err
}
return out, nil
}
func (c *accountsClient) ListAccounts(ctx context.Context, in *ListAccountsRequest, opts ...grpc.CallOption) (*ListAccountsResponse, error) {
out := new(ListAccountsResponse)
err := c.cc.Invoke(ctx, "/ethereum.validator.accounts.v2.Accounts/ListAccounts", in, out, opts...)
@@ -1821,7 +1760,6 @@ func (c *accountsClient) ChangePassword(ctx context.Context, in *ChangePasswordR
// AccountsServer is the server API for Accounts service.
type AccountsServer interface {
CreateAccount(context.Context, *CreateAccountRequest) (*DepositDataResponse, error)
ListAccounts(context.Context, *ListAccountsRequest) (*ListAccountsResponse, error)
ChangePassword(context.Context, *ChangePasswordRequest) (*types.Empty, error)
}
@@ -1830,9 +1768,6 @@ type AccountsServer interface {
type UnimplementedAccountsServer struct {
}
func (*UnimplementedAccountsServer) CreateAccount(ctx context.Context, req *CreateAccountRequest) (*DepositDataResponse, error) {
return nil, status.Errorf(codes.Unimplemented, "method CreateAccount not implemented")
}
func (*UnimplementedAccountsServer) ListAccounts(ctx context.Context, req *ListAccountsRequest) (*ListAccountsResponse, error) {
return nil, status.Errorf(codes.Unimplemented, "method ListAccounts not implemented")
}
@@ -1844,24 +1779,6 @@ func RegisterAccountsServer(s *grpc.Server, srv AccountsServer) {
s.RegisterService(&_Accounts_serviceDesc, srv)
}
func _Accounts_CreateAccount_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(CreateAccountRequest)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(AccountsServer).CreateAccount(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: "/ethereum.validator.accounts.v2.Accounts/CreateAccount",
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(AccountsServer).CreateAccount(ctx, req.(*CreateAccountRequest))
}
return interceptor(ctx, in, info, handler)
}
func _Accounts_ListAccounts_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(ListAccountsRequest)
if err := dec(in); err != nil {
@@ -1902,10 +1819,6 @@ var _Accounts_serviceDesc = grpc.ServiceDesc{
ServiceName: "ethereum.validator.accounts.v2.Accounts",
HandlerType: (*AccountsServer)(nil),
Methods: []grpc.MethodDesc{
{
MethodName: "CreateAccount",
Handler: _Accounts_CreateAccount_Handler,
},
{
MethodName: "ListAccounts",
Handler: _Accounts_ListAccounts_Handler,
@@ -2950,38 +2863,6 @@ func (m *ImportKeystoresResponse) MarshalToSizedBuffer(dAtA []byte) (int, error)
return len(dAtA) - i, nil
}
func (m *CreateAccountRequest) Marshal() (dAtA []byte, err error) {
size := m.Size()
dAtA = make([]byte, size)
n, err := m.MarshalToSizedBuffer(dAtA[:size])
if err != nil {
return nil, err
}
return dAtA[:n], nil
}
func (m *CreateAccountRequest) MarshalTo(dAtA []byte) (int, error) {
size := m.Size()
return m.MarshalToSizedBuffer(dAtA[:size])
}
func (m *CreateAccountRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) {
i := len(dAtA)
_ = i
var l int
_ = l
if m.XXX_unrecognized != nil {
i -= len(m.XXX_unrecognized)
copy(dAtA[i:], m.XXX_unrecognized)
}
if m.NumAccounts != 0 {
i = encodeVarintWebApi(dAtA, i, uint64(m.NumAccounts))
i--
dAtA[i] = 0x8
}
return len(dAtA) - i, nil
}
func (m *DepositMessage) Marshal() (dAtA []byte, err error) {
size := m.Size()
dAtA = make([]byte, size)
@@ -3585,21 +3466,6 @@ func (m *ImportKeystoresResponse) Size() (n int) {
return n
}
func (m *CreateAccountRequest) Size() (n int) {
if m == nil {
return 0
}
var l int
_ = l
if m.NumAccounts != 0 {
n += 1 + sovWebApi(uint64(m.NumAccounts))
}
if m.XXX_unrecognized != nil {
n += len(m.XXX_unrecognized)
}
return n
}
func (m *DepositMessage) Size() (n int) {
if m == nil {
return 0
@@ -6107,79 +5973,6 @@ func (m *ImportKeystoresResponse) Unmarshal(dAtA []byte) error {
}
return nil
}
func (m *CreateAccountRequest) Unmarshal(dAtA []byte) error {
l := len(dAtA)
iNdEx := 0
for iNdEx < l {
preIndex := iNdEx
var wire uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowWebApi
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
wire |= uint64(b&0x7F) << shift
if b < 0x80 {
break
}
}
fieldNum := int32(wire >> 3)
wireType := int(wire & 0x7)
if wireType == 4 {
return fmt.Errorf("proto: CreateAccountRequest: wiretype end group for non-group")
}
if fieldNum <= 0 {
return fmt.Errorf("proto: CreateAccountRequest: illegal tag %d (wire type %d)", fieldNum, wire)
}
switch fieldNum {
case 1:
if wireType != 0 {
return fmt.Errorf("proto: wrong wireType = %d for field NumAccounts", wireType)
}
m.NumAccounts = 0
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowWebApi
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
m.NumAccounts |= uint64(b&0x7F) << shift
if b < 0x80 {
break
}
}
default:
iNdEx = preIndex
skippy, err := skipWebApi(dAtA[iNdEx:])
if err != nil {
return err
}
if skippy < 0 {
return ErrInvalidLengthWebApi
}
if (iNdEx + skippy) < 0 {
return ErrInvalidLengthWebApi
}
if (iNdEx + skippy) > l {
return io.ErrUnexpectedEOF
}
m.XXX_unrecognized = append(m.XXX_unrecognized, dAtA[iNdEx:iNdEx+skippy]...)
iNdEx += skippy
}
}
if iNdEx > l {
return io.ErrUnexpectedEOF
}
return nil
}
func (m *DepositMessage) Unmarshal(dAtA []byte) error {
l := len(dAtA)
iNdEx := 0

View File

@@ -43,12 +43,6 @@ service Wallet {
}
service Accounts {
rpc CreateAccount(CreateAccountRequest) returns (DepositDataResponse) {
option (google.api.http) = {
post: "/v2/validator/wallet/accounts/create",
body: "*"
};
}
rpc ListAccounts(ListAccountsRequest) returns (ListAccountsResponse) {
option (google.api.http) = {
get: "/v2/validator/accounts"
@@ -241,10 +235,6 @@ message ImportKeystoresResponse {
repeated bytes imported_public_keys = 1;
}
message CreateAccountRequest {
uint64 num_accounts = 1;
}
message DepositMessage {
bytes pubkey = 1 [(gogoproto.moretags) = "ssz-size:\"48\""];
bytes withdrawal_credentials = 2 [(gogoproto.moretags) = "ssz-size:\"32\""];

View File

@@ -1090,53 +1090,6 @@ func (x *ImportKeystoresResponse) GetImportedPublicKeys() [][]byte {
return nil
}
type CreateAccountRequest struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
NumAccounts uint64 `protobuf:"varint,1,opt,name=num_accounts,json=numAccounts,proto3" json:"num_accounts,omitempty"`
}
func (x *CreateAccountRequest) Reset() {
*x = CreateAccountRequest{}
if protoimpl.UnsafeEnabled {
mi := &file_proto_validator_accounts_v2_web_api_proto_msgTypes[16]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *CreateAccountRequest) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*CreateAccountRequest) ProtoMessage() {}
func (x *CreateAccountRequest) ProtoReflect() protoreflect.Message {
mi := &file_proto_validator_accounts_v2_web_api_proto_msgTypes[16]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use CreateAccountRequest.ProtoReflect.Descriptor instead.
func (*CreateAccountRequest) Descriptor() ([]byte, []int) {
return file_proto_validator_accounts_v2_web_api_proto_rawDescGZIP(), []int{16}
}
func (x *CreateAccountRequest) GetNumAccounts() uint64 {
if x != nil {
return x.NumAccounts
}
return 0
}
type DepositMessage struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
@@ -1150,7 +1103,7 @@ type DepositMessage struct {
func (x *DepositMessage) Reset() {
*x = DepositMessage{}
if protoimpl.UnsafeEnabled {
mi := &file_proto_validator_accounts_v2_web_api_proto_msgTypes[17]
mi := &file_proto_validator_accounts_v2_web_api_proto_msgTypes[16]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -1163,7 +1116,7 @@ func (x *DepositMessage) String() string {
func (*DepositMessage) ProtoMessage() {}
func (x *DepositMessage) ProtoReflect() protoreflect.Message {
mi := &file_proto_validator_accounts_v2_web_api_proto_msgTypes[17]
mi := &file_proto_validator_accounts_v2_web_api_proto_msgTypes[16]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -1176,7 +1129,7 @@ func (x *DepositMessage) ProtoReflect() protoreflect.Message {
// Deprecated: Use DepositMessage.ProtoReflect.Descriptor instead.
func (*DepositMessage) Descriptor() ([]byte, []int) {
return file_proto_validator_accounts_v2_web_api_proto_rawDescGZIP(), []int{17}
return file_proto_validator_accounts_v2_web_api_proto_rawDescGZIP(), []int{16}
}
func (x *DepositMessage) GetPubkey() []byte {
@@ -1211,7 +1164,7 @@ type DepositDataResponse struct {
func (x *DepositDataResponse) Reset() {
*x = DepositDataResponse{}
if protoimpl.UnsafeEnabled {
mi := &file_proto_validator_accounts_v2_web_api_proto_msgTypes[18]
mi := &file_proto_validator_accounts_v2_web_api_proto_msgTypes[17]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -1224,7 +1177,7 @@ func (x *DepositDataResponse) String() string {
func (*DepositDataResponse) ProtoMessage() {}
func (x *DepositDataResponse) ProtoReflect() protoreflect.Message {
mi := &file_proto_validator_accounts_v2_web_api_proto_msgTypes[18]
mi := &file_proto_validator_accounts_v2_web_api_proto_msgTypes[17]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -1237,7 +1190,7 @@ func (x *DepositDataResponse) ProtoReflect() protoreflect.Message {
// Deprecated: Use DepositDataResponse.ProtoReflect.Descriptor instead.
func (*DepositDataResponse) Descriptor() ([]byte, []int) {
return file_proto_validator_accounts_v2_web_api_proto_rawDescGZIP(), []int{18}
return file_proto_validator_accounts_v2_web_api_proto_rawDescGZIP(), []int{17}
}
func (x *DepositDataResponse) GetDepositDataList() []*DepositDataResponse_DepositData {
@@ -1258,7 +1211,7 @@ type DeleteAccountsRequest struct {
func (x *DeleteAccountsRequest) Reset() {
*x = DeleteAccountsRequest{}
if protoimpl.UnsafeEnabled {
mi := &file_proto_validator_accounts_v2_web_api_proto_msgTypes[19]
mi := &file_proto_validator_accounts_v2_web_api_proto_msgTypes[18]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -1271,7 +1224,7 @@ func (x *DeleteAccountsRequest) String() string {
func (*DeleteAccountsRequest) ProtoMessage() {}
func (x *DeleteAccountsRequest) ProtoReflect() protoreflect.Message {
mi := &file_proto_validator_accounts_v2_web_api_proto_msgTypes[19]
mi := &file_proto_validator_accounts_v2_web_api_proto_msgTypes[18]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -1284,7 +1237,7 @@ func (x *DeleteAccountsRequest) ProtoReflect() protoreflect.Message {
// Deprecated: Use DeleteAccountsRequest.ProtoReflect.Descriptor instead.
func (*DeleteAccountsRequest) Descriptor() ([]byte, []int) {
return file_proto_validator_accounts_v2_web_api_proto_rawDescGZIP(), []int{19}
return file_proto_validator_accounts_v2_web_api_proto_rawDescGZIP(), []int{18}
}
func (x *DeleteAccountsRequest) GetPublicKeys() [][]byte {
@@ -1305,7 +1258,7 @@ type DeleteAccountsResponse struct {
func (x *DeleteAccountsResponse) Reset() {
*x = DeleteAccountsResponse{}
if protoimpl.UnsafeEnabled {
mi := &file_proto_validator_accounts_v2_web_api_proto_msgTypes[20]
mi := &file_proto_validator_accounts_v2_web_api_proto_msgTypes[19]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -1318,7 +1271,7 @@ func (x *DeleteAccountsResponse) String() string {
func (*DeleteAccountsResponse) ProtoMessage() {}
func (x *DeleteAccountsResponse) ProtoReflect() protoreflect.Message {
mi := &file_proto_validator_accounts_v2_web_api_proto_msgTypes[20]
mi := &file_proto_validator_accounts_v2_web_api_proto_msgTypes[19]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -1331,7 +1284,7 @@ func (x *DeleteAccountsResponse) ProtoReflect() protoreflect.Message {
// Deprecated: Use DeleteAccountsResponse.ProtoReflect.Descriptor instead.
func (*DeleteAccountsResponse) Descriptor() ([]byte, []int) {
return file_proto_validator_accounts_v2_web_api_proto_rawDescGZIP(), []int{20}
return file_proto_validator_accounts_v2_web_api_proto_rawDescGZIP(), []int{19}
}
func (x *DeleteAccountsResponse) GetDeletedKeys() [][]byte {
@@ -1352,7 +1305,7 @@ type DepositDataResponse_DepositData struct {
func (x *DepositDataResponse_DepositData) Reset() {
*x = DepositDataResponse_DepositData{}
if protoimpl.UnsafeEnabled {
mi := &file_proto_validator_accounts_v2_web_api_proto_msgTypes[22]
mi := &file_proto_validator_accounts_v2_web_api_proto_msgTypes[21]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@@ -1365,7 +1318,7 @@ func (x *DepositDataResponse_DepositData) String() string {
func (*DepositDataResponse_DepositData) ProtoMessage() {}
func (x *DepositDataResponse_DepositData) ProtoReflect() protoreflect.Message {
mi := &file_proto_validator_accounts_v2_web_api_proto_msgTypes[22]
mi := &file_proto_validator_accounts_v2_web_api_proto_msgTypes[21]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@@ -1378,7 +1331,7 @@ func (x *DepositDataResponse_DepositData) ProtoReflect() protoreflect.Message {
// Deprecated: Use DepositDataResponse_DepositData.ProtoReflect.Descriptor instead.
func (*DepositDataResponse_DepositData) Descriptor() ([]byte, []int) {
return file_proto_validator_accounts_v2_web_api_proto_rawDescGZIP(), []int{18, 0}
return file_proto_validator_accounts_v2_web_api_proto_rawDescGZIP(), []int{17, 0}
}
func (x *DepositDataResponse_DepositData) GetData() map[string]string {
@@ -1559,171 +1512,157 @@ var file_proto_validator_accounts_v2_web_api_proto_rawDesc = []byte{
0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x30, 0x0a, 0x14, 0x69, 0x6d, 0x70, 0x6f, 0x72,
0x74, 0x65, 0x64, 0x5f, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x5f, 0x6b, 0x65, 0x79, 0x73, 0x18,
0x01, 0x20, 0x03, 0x28, 0x0c, 0x52, 0x12, 0x69, 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x50,
0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x73, 0x22, 0x39, 0x0a, 0x14, 0x43, 0x72, 0x65,
0x61, 0x74, 0x65, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73,
0x74, 0x12, 0x21, 0x0a, 0x0c, 0x6e, 0x75, 0x6d, 0x5f, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74,
0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0b, 0x6e, 0x75, 0x6d, 0x41, 0x63, 0x63, 0x6f,
0x75, 0x6e, 0x74, 0x73, 0x22, 0x9d, 0x01, 0x0a, 0x0e, 0x44, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74,
0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x29, 0x0a, 0x06, 0x70, 0x75, 0x62, 0x6b, 0x65,
0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x42, 0x11, 0xf2, 0xde, 0x1f, 0x0d, 0x73, 0x73, 0x7a,
0x2d, 0x73, 0x69, 0x7a, 0x65, 0x3a, 0x22, 0x34, 0x38, 0x22, 0x52, 0x06, 0x70, 0x75, 0x62, 0x6b,
0x65, 0x79, 0x12, 0x48, 0x0a, 0x16, 0x77, 0x69, 0x74, 0x68, 0x64, 0x72, 0x61, 0x77, 0x61, 0x6c,
0x5f, 0x63, 0x72, 0x65, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x73, 0x18, 0x02, 0x20, 0x01,
0x28, 0x0c, 0x42, 0x11, 0xf2, 0xde, 0x1f, 0x0d, 0x73, 0x73, 0x7a, 0x2d, 0x73, 0x69, 0x7a, 0x65,
0x3a, 0x22, 0x33, 0x32, 0x22, 0x52, 0x15, 0x77, 0x69, 0x74, 0x68, 0x64, 0x72, 0x61, 0x77, 0x61,
0x6c, 0x43, 0x72, 0x65, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x73, 0x12, 0x16, 0x0a, 0x06,
0x61, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x04, 0x52, 0x06, 0x61, 0x6d,
0x6f, 0x75, 0x6e, 0x74, 0x22, 0xaa, 0x02, 0x0a, 0x13, 0x44, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74,
0x44, 0x61, 0x74, 0x61, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x6b, 0x0a, 0x11,
0x64, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x5f, 0x64, 0x61, 0x74, 0x61, 0x5f, 0x6c, 0x69, 0x73,
0x74, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x3f, 0x2e, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65,
0x75, 0x6d, 0x2e, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x2e, 0x61, 0x63, 0x63,
0x6f, 0x75, 0x6e, 0x74, 0x73, 0x2e, 0x76, 0x32, 0x2e, 0x44, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74,
0x44, 0x61, 0x74, 0x61, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x44, 0x65, 0x70,
0x6f, 0x73, 0x69, 0x74, 0x44, 0x61, 0x74, 0x61, 0x52, 0x0f, 0x64, 0x65, 0x70, 0x6f, 0x73, 0x69,
0x74, 0x44, 0x61, 0x74, 0x61, 0x4c, 0x69, 0x73, 0x74, 0x1a, 0xa5, 0x01, 0x0a, 0x0b, 0x44, 0x65,
0x70, 0x6f, 0x73, 0x69, 0x74, 0x44, 0x61, 0x74, 0x61, 0x12, 0x5d, 0x0a, 0x04, 0x64, 0x61, 0x74,
0x61, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x49, 0x2e, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65,
0x75, 0x6d, 0x2e, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x2e, 0x61, 0x63, 0x63,
0x6f, 0x75, 0x6e, 0x74, 0x73, 0x2e, 0x76, 0x32, 0x2e, 0x44, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74,
0x44, 0x61, 0x74, 0x61, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x44, 0x65, 0x70,
0x6f, 0x73, 0x69, 0x74, 0x44, 0x61, 0x74, 0x61, 0x2e, 0x44, 0x61, 0x74, 0x61, 0x45, 0x6e, 0x74,
0x72, 0x79, 0x52, 0x04, 0x64, 0x61, 0x74, 0x61, 0x1a, 0x37, 0x0a, 0x09, 0x44, 0x61, 0x74, 0x61,
0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01,
0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65,
0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38,
0x01, 0x22, 0x38, 0x0a, 0x15, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x41, 0x63, 0x63, 0x6f, 0x75,
0x6e, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1f, 0x0a, 0x0b, 0x70, 0x75,
0x62, 0x6c, 0x69, 0x63, 0x5f, 0x6b, 0x65, 0x79, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0c, 0x52,
0x0a, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x73, 0x22, 0x3b, 0x0a, 0x16, 0x44,
0x65, 0x6c, 0x65, 0x74, 0x65, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x73, 0x52, 0x65, 0x73,
0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x21, 0x0a, 0x0c, 0x64, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x64,
0x5f, 0x6b, 0x65, 0x79, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0c, 0x52, 0x0b, 0x64, 0x65, 0x6c,
0x65, 0x74, 0x65, 0x64, 0x4b, 0x65, 0x79, 0x73, 0x2a, 0x37, 0x0a, 0x0e, 0x4b, 0x65, 0x79, 0x6d,
0x61, 0x6e, 0x61, 0x67, 0x65, 0x72, 0x4b, 0x69, 0x6e, 0x64, 0x12, 0x0b, 0x0a, 0x07, 0x44, 0x45,
0x52, 0x49, 0x56, 0x45, 0x44, 0x10, 0x00, 0x12, 0x0c, 0x0a, 0x08, 0x49, 0x4d, 0x50, 0x4f, 0x52,
0x54, 0x45, 0x44, 0x10, 0x01, 0x12, 0x0a, 0x0a, 0x06, 0x52, 0x45, 0x4d, 0x4f, 0x54, 0x45, 0x10,
0x02, 0x32, 0x8b, 0x07, 0x0a, 0x06, 0x57, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x12, 0x7b, 0x0a, 0x09,
0x48, 0x61, 0x73, 0x57, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x12, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67,
0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74,
0x79, 0x1a, 0x31, 0x2e, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e, 0x76, 0x61, 0x6c,
0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x2e, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x73, 0x2e,
0x76, 0x32, 0x2e, 0x48, 0x61, 0x73, 0x57, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x52, 0x65, 0x73, 0x70,
0x6f, 0x6e, 0x73, 0x65, 0x22, 0x23, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x1d, 0x12, 0x1b, 0x2f, 0x76,
0x32, 0x2f, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x2f, 0x77, 0x61, 0x6c, 0x6c,
0x65, 0x74, 0x2f, 0x65, 0x78, 0x69, 0x73, 0x74, 0x73, 0x12, 0xa1, 0x01, 0x0a, 0x0c, 0x43, 0x72,
0x65, 0x61, 0x74, 0x65, 0x57, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x12, 0x33, 0x2e, 0x65, 0x74, 0x68,
0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x2e,
0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x73, 0x2e, 0x76, 0x32, 0x2e, 0x43, 0x72, 0x65, 0x61,
0x74, 0x65, 0x57, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a,
0x34, 0x2e, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e, 0x76, 0x61, 0x6c, 0x69, 0x64,
0x61, 0x74, 0x6f, 0x72, 0x2e, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x73, 0x2e, 0x76, 0x32,
0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x57, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x52, 0x65, 0x73,
0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x26, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x20, 0x22, 0x1b, 0x2f,
0x76, 0x32, 0x2f, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x2f, 0x77, 0x61, 0x6c,
0x6c, 0x65, 0x74, 0x2f, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x3a, 0x01, 0x2a, 0x12, 0xa2, 0x01,
0x0a, 0x0a, 0x45, 0x64, 0x69, 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x37, 0x2e, 0x65,
0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x73, 0x22, 0x9d, 0x01, 0x0a, 0x0e, 0x44, 0x65,
0x70, 0x6f, 0x73, 0x69, 0x74, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x29, 0x0a, 0x06,
0x70, 0x75, 0x62, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x42, 0x11, 0xf2, 0xde,
0x1f, 0x0d, 0x73, 0x73, 0x7a, 0x2d, 0x73, 0x69, 0x7a, 0x65, 0x3a, 0x22, 0x34, 0x38, 0x22, 0x52,
0x06, 0x70, 0x75, 0x62, 0x6b, 0x65, 0x79, 0x12, 0x48, 0x0a, 0x16, 0x77, 0x69, 0x74, 0x68, 0x64,
0x72, 0x61, 0x77, 0x61, 0x6c, 0x5f, 0x63, 0x72, 0x65, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x61, 0x6c,
0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x42, 0x11, 0xf2, 0xde, 0x1f, 0x0d, 0x73, 0x73, 0x7a,
0x2d, 0x73, 0x69, 0x7a, 0x65, 0x3a, 0x22, 0x33, 0x32, 0x22, 0x52, 0x15, 0x77, 0x69, 0x74, 0x68,
0x64, 0x72, 0x61, 0x77, 0x61, 0x6c, 0x43, 0x72, 0x65, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x61, 0x6c,
0x73, 0x12, 0x16, 0x0a, 0x06, 0x61, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28,
0x04, 0x52, 0x06, 0x61, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x22, 0xaa, 0x02, 0x0a, 0x13, 0x44, 0x65,
0x70, 0x6f, 0x73, 0x69, 0x74, 0x44, 0x61, 0x74, 0x61, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73,
0x65, 0x12, 0x6b, 0x0a, 0x11, 0x64, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x5f, 0x64, 0x61, 0x74,
0x61, 0x5f, 0x6c, 0x69, 0x73, 0x74, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x3f, 0x2e, 0x65,
0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f,
0x72, 0x2e, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x73, 0x2e, 0x76, 0x32, 0x2e, 0x45, 0x64,
0x69, 0x74, 0x57, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x65,
0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2e, 0x2e, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d,
0x2e, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x2e, 0x61, 0x63, 0x63, 0x6f, 0x75,
0x6e, 0x74, 0x73, 0x2e, 0x76, 0x32, 0x2e, 0x57, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x52, 0x65, 0x73,
0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x2b, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x25, 0x22, 0x20, 0x2f,
0x76, 0x32, 0x2f, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x2f, 0x77, 0x61, 0x6c,
0x6c, 0x65, 0x74, 0x2f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2f, 0x65, 0x64, 0x69, 0x74, 0x3a,
0x01, 0x2a, 0x12, 0x74, 0x0a, 0x0c, 0x57, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x43, 0x6f, 0x6e, 0x66,
0x69, 0x67, 0x12, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74,
0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x2e, 0x2e, 0x65, 0x74, 0x68,
0x72, 0x2e, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x73, 0x2e, 0x76, 0x32, 0x2e, 0x44, 0x65,
0x70, 0x6f, 0x73, 0x69, 0x74, 0x44, 0x61, 0x74, 0x61, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73,
0x65, 0x2e, 0x44, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x44, 0x61, 0x74, 0x61, 0x52, 0x0f, 0x64,
0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x44, 0x61, 0x74, 0x61, 0x4c, 0x69, 0x73, 0x74, 0x1a, 0xa5,
0x01, 0x0a, 0x0b, 0x44, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x44, 0x61, 0x74, 0x61, 0x12, 0x5d,
0x0a, 0x04, 0x64, 0x61, 0x74, 0x61, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x49, 0x2e, 0x65,
0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f,
0x72, 0x2e, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x73, 0x2e, 0x76, 0x32, 0x2e, 0x44, 0x65,
0x70, 0x6f, 0x73, 0x69, 0x74, 0x44, 0x61, 0x74, 0x61, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73,
0x65, 0x2e, 0x44, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x44, 0x61, 0x74, 0x61, 0x2e, 0x44, 0x61,
0x74, 0x61, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x04, 0x64, 0x61, 0x74, 0x61, 0x1a, 0x37, 0x0a,
0x09, 0x44, 0x61, 0x74, 0x61, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65,
0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05,
0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c,
0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x38, 0x0a, 0x15, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65,
0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12,
0x1f, 0x0a, 0x0b, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x5f, 0x6b, 0x65, 0x79, 0x73, 0x18, 0x01,
0x20, 0x03, 0x28, 0x0c, 0x52, 0x0a, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x73,
0x22, 0x3b, 0x0a, 0x16, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e,
0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x21, 0x0a, 0x0c, 0x64, 0x65,
0x6c, 0x65, 0x74, 0x65, 0x64, 0x5f, 0x6b, 0x65, 0x79, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0c,
0x52, 0x0b, 0x64, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x64, 0x4b, 0x65, 0x79, 0x73, 0x2a, 0x37, 0x0a,
0x0e, 0x4b, 0x65, 0x79, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x72, 0x4b, 0x69, 0x6e, 0x64, 0x12,
0x0b, 0x0a, 0x07, 0x44, 0x45, 0x52, 0x49, 0x56, 0x45, 0x44, 0x10, 0x00, 0x12, 0x0c, 0x0a, 0x08,
0x49, 0x4d, 0x50, 0x4f, 0x52, 0x54, 0x45, 0x44, 0x10, 0x01, 0x12, 0x0a, 0x0a, 0x06, 0x52, 0x45,
0x4d, 0x4f, 0x54, 0x45, 0x10, 0x02, 0x32, 0x8b, 0x07, 0x0a, 0x06, 0x57, 0x61, 0x6c, 0x6c, 0x65,
0x74, 0x12, 0x7b, 0x0a, 0x09, 0x48, 0x61, 0x73, 0x57, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x12, 0x16,
0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66,
0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x31, 0x2e, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75,
0x6d, 0x2e, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x2e, 0x61, 0x63, 0x63, 0x6f,
0x75, 0x6e, 0x74, 0x73, 0x2e, 0x76, 0x32, 0x2e, 0x48, 0x61, 0x73, 0x57, 0x61, 0x6c, 0x6c, 0x65,
0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x23, 0x82, 0xd3, 0xe4, 0x93, 0x02,
0x1d, 0x12, 0x1b, 0x2f, 0x76, 0x32, 0x2f, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72,
0x2f, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x2f, 0x65, 0x78, 0x69, 0x73, 0x74, 0x73, 0x12, 0xa1,
0x01, 0x0a, 0x0c, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x57, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x12,
0x33, 0x2e, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e, 0x76, 0x61, 0x6c, 0x69, 0x64,
0x61, 0x74, 0x6f, 0x72, 0x2e, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x73, 0x2e, 0x76, 0x32,
0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x57, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x52, 0x65, 0x71,
0x75, 0x65, 0x73, 0x74, 0x1a, 0x34, 0x2e, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e,
0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x2e, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e,
0x74, 0x73, 0x2e, 0x76, 0x32, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x57, 0x61, 0x6c, 0x6c,
0x65, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x26, 0x82, 0xd3, 0xe4, 0x93,
0x02, 0x20, 0x22, 0x1b, 0x2f, 0x76, 0x32, 0x2f, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f,
0x72, 0x2f, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x2f, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x3a,
0x01, 0x2a, 0x12, 0xa2, 0x01, 0x0a, 0x0a, 0x45, 0x64, 0x69, 0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69,
0x67, 0x12, 0x37, 0x2e, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e, 0x76, 0x61, 0x6c,
0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x2e, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x73, 0x2e,
0x76, 0x32, 0x2e, 0x45, 0x64, 0x69, 0x74, 0x57, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x43, 0x6f, 0x6e,
0x66, 0x69, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2e, 0x2e, 0x65, 0x74, 0x68,
0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x2e,
0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x73, 0x2e, 0x76, 0x32, 0x2e, 0x57, 0x61, 0x6c, 0x6c,
0x65, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x1c, 0x82, 0xd3, 0xe4, 0x93,
0x02, 0x16, 0x12, 0x14, 0x2f, 0x76, 0x32, 0x2f, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f,
0x72, 0x2f, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x12, 0x8d, 0x01, 0x0a, 0x10, 0x47, 0x65, 0x6e,
0x65, 0x72, 0x61, 0x74, 0x65, 0x4d, 0x6e, 0x65, 0x6d, 0x6f, 0x6e, 0x69, 0x63, 0x12, 0x16, 0x2e,
0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e,
0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x38, 0x2e, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d,
0x2e, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x2e, 0x61, 0x63, 0x63, 0x6f, 0x75,
0x6e, 0x74, 0x73, 0x2e, 0x76, 0x32, 0x2e, 0x47, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x4d,
0x6e, 0x65, 0x6d, 0x6f, 0x6e, 0x69, 0x63, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22,
0x27, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x21, 0x12, 0x1f, 0x2f, 0x76, 0x32, 0x2f, 0x76, 0x61, 0x6c,
0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x2f, 0x6d, 0x6e, 0x65, 0x6d, 0x6f, 0x6e, 0x69, 0x63, 0x2f,
0x67, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x12, 0xb4, 0x01, 0x0a, 0x0f, 0x49, 0x6d, 0x70,
0x6f, 0x72, 0x74, 0x4b, 0x65, 0x79, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x73, 0x12, 0x36, 0x2e, 0x65,
0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f,
0x72, 0x2e, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x73, 0x2e, 0x76, 0x32, 0x2e, 0x49, 0x6d,
0x70, 0x6f, 0x72, 0x74, 0x4b, 0x65, 0x79, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x73, 0x52, 0x65, 0x71,
0x75, 0x65, 0x73, 0x74, 0x1a, 0x37, 0x2e, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e,
0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x2e, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e,
0x74, 0x73, 0x2e, 0x76, 0x32, 0x2e, 0x49, 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x4b, 0x65, 0x79, 0x73,
0x74, 0x6f, 0x72, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x30, 0x82,
0xd3, 0xe4, 0x93, 0x02, 0x2a, 0x22, 0x25, 0x2f, 0x76, 0x32, 0x2f, 0x76, 0x61, 0x6c, 0x69, 0x64,
0x61, 0x74, 0x6f, 0x72, 0x2f, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x2f, 0x6b, 0x65, 0x79, 0x73,
0x74, 0x6f, 0x72, 0x65, 0x73, 0x2f, 0x69, 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x3a, 0x01, 0x2a, 0x32,
0xde, 0x03, 0x0a, 0x08, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x73, 0x12, 0xab, 0x01, 0x0a,
0x0d, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x34,
0x2e, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61,
0x74, 0x6f, 0x72, 0x2e, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x73, 0x2e, 0x76, 0x32, 0x2e,
0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x52, 0x65, 0x71,
0x75, 0x65, 0x73, 0x74, 0x1a, 0x33, 0x2e, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e,
0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x2e, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e,
0x74, 0x73, 0x2e, 0x76, 0x32, 0x2e, 0x44, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x44, 0x61, 0x74,
0x61, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x2f, 0x82, 0xd3, 0xe4, 0x93, 0x02,
0x29, 0x22, 0x24, 0x2f, 0x76, 0x32, 0x2f, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72,
0x2f, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x2f, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x73,
0x2f, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x3a, 0x01, 0x2a, 0x12, 0x99, 0x01, 0x0a, 0x0c, 0x4c,
0x69, 0x73, 0x74, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x73, 0x12, 0x33, 0x2e, 0x65, 0x74,
0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72,
0x2e, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x73, 0x2e, 0x76, 0x32, 0x2e, 0x4c, 0x69, 0x73,
0x74, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74,
0x1a, 0x34, 0x2e, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e, 0x76, 0x61, 0x6c, 0x69,
0x64, 0x61, 0x74, 0x6f, 0x72, 0x2e, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x73, 0x2e, 0x76,
0x32, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x73, 0x52, 0x65,
0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x1e, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x18, 0x12, 0x16,
0x2f, 0x76, 0x32, 0x2f, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x2f, 0x61, 0x63,
0x63, 0x6f, 0x75, 0x6e, 0x74, 0x73, 0x12, 0x87, 0x01, 0x0a, 0x0e, 0x43, 0x68, 0x61, 0x6e, 0x67,
0x65, 0x50, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x12, 0x35, 0x2e, 0x65, 0x74, 0x68, 0x65,
0x72, 0x65, 0x75, 0x6d, 0x2e, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x2e, 0x61,
0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x73, 0x2e, 0x76, 0x32, 0x2e, 0x43, 0x68, 0x61, 0x6e, 0x67,
0x65, 0x50, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74,
0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62,
0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x22, 0x26, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x20,
0x22, 0x1b, 0x2f, 0x76, 0x32, 0x2f, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x2f,
0x70, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x2f, 0x65, 0x64, 0x69, 0x74, 0x3a, 0x01, 0x2a,
0x32, 0xa2, 0x01, 0x0a, 0x06, 0x48, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x12, 0x97, 0x01, 0x0a, 0x17,
0x47, 0x65, 0x74, 0x42, 0x65, 0x61, 0x63, 0x6f, 0x6e, 0x4e, 0x6f, 0x64, 0x65, 0x43, 0x6f, 0x6e,
0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65,
0x65, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x2b, 0x82, 0xd3, 0xe4, 0x93,
0x02, 0x25, 0x22, 0x20, 0x2f, 0x76, 0x32, 0x2f, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f,
0x72, 0x2f, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x2f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x2f,
0x65, 0x64, 0x69, 0x74, 0x3a, 0x01, 0x2a, 0x12, 0x74, 0x0a, 0x0c, 0x57, 0x61, 0x6c, 0x6c, 0x65,
0x74, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65,
0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a,
0x36, 0x2e, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e, 0x76, 0x61, 0x6c, 0x69, 0x64,
0x2e, 0x2e, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e, 0x76, 0x61, 0x6c, 0x69, 0x64,
0x61, 0x74, 0x6f, 0x72, 0x2e, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x73, 0x2e, 0x76, 0x32,
0x2e, 0x4e, 0x6f, 0x64, 0x65, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x52,
0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x2c, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x26, 0x12,
0x24, 0x2f, 0x76, 0x32, 0x2f, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x2f, 0x68,
0x65, 0x61, 0x6c, 0x74, 0x68, 0x2f, 0x6e, 0x6f, 0x64, 0x65, 0x5f, 0x63, 0x6f, 0x6e, 0x6e, 0x65,
0x63, 0x74, 0x69, 0x6f, 0x6e, 0x32, 0xed, 0x02, 0x0a, 0x04, 0x41, 0x75, 0x74, 0x68, 0x12, 0x82,
0x01, 0x0a, 0x05, 0x4c, 0x6f, 0x67, 0x69, 0x6e, 0x12, 0x2b, 0x2e, 0x65, 0x74, 0x68, 0x65, 0x72,
0x65, 0x75, 0x6d, 0x2e, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x2e, 0x61, 0x63,
0x63, 0x6f, 0x75, 0x6e, 0x74, 0x73, 0x2e, 0x76, 0x32, 0x2e, 0x41, 0x75, 0x74, 0x68, 0x52, 0x65,
0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2c, 0x2e, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d,
0x2e, 0x57, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22,
0x1c, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x16, 0x12, 0x14, 0x2f, 0x76, 0x32, 0x2f, 0x76, 0x61, 0x6c,
0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x2f, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x12, 0x8d, 0x01,
0x0a, 0x10, 0x47, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x4d, 0x6e, 0x65, 0x6d, 0x6f, 0x6e,
0x69, 0x63, 0x12, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74,
0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x38, 0x2e, 0x65, 0x74, 0x68,
0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x2e,
0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x73, 0x2e, 0x76, 0x32, 0x2e, 0x47, 0x65, 0x6e, 0x65,
0x72, 0x61, 0x74, 0x65, 0x4d, 0x6e, 0x65, 0x6d, 0x6f, 0x6e, 0x69, 0x63, 0x52, 0x65, 0x73, 0x70,
0x6f, 0x6e, 0x73, 0x65, 0x22, 0x27, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x21, 0x12, 0x1f, 0x2f, 0x76,
0x32, 0x2f, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x2f, 0x6d, 0x6e, 0x65, 0x6d,
0x6f, 0x6e, 0x69, 0x63, 0x2f, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x12, 0xb4, 0x01,
0x0a, 0x0f, 0x49, 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x4b, 0x65, 0x79, 0x73, 0x74, 0x6f, 0x72, 0x65,
0x73, 0x12, 0x36, 0x2e, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e, 0x76, 0x61, 0x6c,
0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x2e, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x73, 0x2e,
0x76, 0x32, 0x2e, 0x49, 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x4b, 0x65, 0x79, 0x73, 0x74, 0x6f, 0x72,
0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x37, 0x2e, 0x65, 0x74, 0x68, 0x65,
0x72, 0x65, 0x75, 0x6d, 0x2e, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x2e, 0x61,
0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x73, 0x2e, 0x76, 0x32, 0x2e, 0x49, 0x6d, 0x70, 0x6f, 0x72,
0x74, 0x4b, 0x65, 0x79, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e,
0x73, 0x65, 0x22, 0x30, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x2a, 0x22, 0x25, 0x2f, 0x76, 0x32, 0x2f,
0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x2f, 0x77, 0x61, 0x6c, 0x6c, 0x65, 0x74,
0x2f, 0x6b, 0x65, 0x79, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x73, 0x2f, 0x69, 0x6d, 0x70, 0x6f, 0x72,
0x74, 0x3a, 0x01, 0x2a, 0x32, 0xb0, 0x02, 0x0a, 0x08, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74,
0x73, 0x12, 0x99, 0x01, 0x0a, 0x0c, 0x4c, 0x69, 0x73, 0x74, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e,
0x74, 0x73, 0x12, 0x33, 0x2e, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e, 0x76, 0x61,
0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x2e, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x73,
0x2e, 0x76, 0x32, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x73,
0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x34, 0x2e, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65,
0x75, 0x6d, 0x2e, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x2e, 0x61, 0x63, 0x63,
0x6f, 0x75, 0x6e, 0x74, 0x73, 0x2e, 0x76, 0x32, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x41, 0x63, 0x63,
0x6f, 0x75, 0x6e, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x1e, 0x82,
0xd3, 0xe4, 0x93, 0x02, 0x18, 0x12, 0x16, 0x2f, 0x76, 0x32, 0x2f, 0x76, 0x61, 0x6c, 0x69, 0x64,
0x61, 0x74, 0x6f, 0x72, 0x2f, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x73, 0x12, 0x87, 0x01,
0x0a, 0x0e, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x50, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64,
0x12, 0x35, 0x2e, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e, 0x76, 0x61, 0x6c, 0x69,
0x64, 0x61, 0x74, 0x6f, 0x72, 0x2e, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x73, 0x2e, 0x76,
0x32, 0x2e, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x50, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64,
0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65,
0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x22,
0x26, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x20, 0x22, 0x1b, 0x2f, 0x76, 0x32, 0x2f, 0x76, 0x61, 0x6c,
0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x2f, 0x70, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x2f,
0x65, 0x64, 0x69, 0x74, 0x3a, 0x01, 0x2a, 0x32, 0xa2, 0x01, 0x0a, 0x06, 0x48, 0x65, 0x61, 0x6c,
0x74, 0x68, 0x12, 0x97, 0x01, 0x0a, 0x17, 0x47, 0x65, 0x74, 0x42, 0x65, 0x61, 0x63, 0x6f, 0x6e,
0x4e, 0x6f, 0x64, 0x65, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x16,
0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66,
0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x36, 0x2e, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75,
0x6d, 0x2e, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x2e, 0x61, 0x63, 0x63, 0x6f,
0x75, 0x6e, 0x74, 0x73, 0x2e, 0x76, 0x32, 0x2e, 0x4e, 0x6f, 0x64, 0x65, 0x43, 0x6f, 0x6e, 0x6e,
0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x2c,
0x82, 0xd3, 0xe4, 0x93, 0x02, 0x26, 0x12, 0x24, 0x2f, 0x76, 0x32, 0x2f, 0x76, 0x61, 0x6c, 0x69,
0x64, 0x61, 0x74, 0x6f, 0x72, 0x2f, 0x68, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x2f, 0x6e, 0x6f, 0x64,
0x65, 0x5f, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x32, 0xed, 0x02, 0x0a,
0x04, 0x41, 0x75, 0x74, 0x68, 0x12, 0x82, 0x01, 0x0a, 0x05, 0x4c, 0x6f, 0x67, 0x69, 0x6e, 0x12,
0x2b, 0x2e, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e, 0x76, 0x61, 0x6c, 0x69, 0x64,
0x61, 0x74, 0x6f, 0x72, 0x2e, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x73, 0x2e, 0x76, 0x32,
0x2e, 0x41, 0x75, 0x74, 0x68, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2c, 0x2e, 0x65,
0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f,
0x72, 0x2e, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x73, 0x2e, 0x76, 0x32, 0x2e, 0x41, 0x75,
0x74, 0x68, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x1e, 0x82, 0xd3, 0xe4, 0x93,
0x02, 0x18, 0x22, 0x13, 0x2f, 0x76, 0x32, 0x2f, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f,
0x72, 0x2f, 0x6c, 0x6f, 0x67, 0x69, 0x6e, 0x3a, 0x01, 0x2a, 0x12, 0x84, 0x01, 0x0a, 0x06, 0x53,
0x69, 0x67, 0x6e, 0x75, 0x70, 0x12, 0x2b, 0x2e, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d,
0x2e, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x2e, 0x61, 0x63, 0x63, 0x6f, 0x75,
0x6e, 0x74, 0x73, 0x2e, 0x76, 0x32, 0x2e, 0x41, 0x75, 0x74, 0x68, 0x52, 0x65, 0x73, 0x70, 0x6f,
0x6e, 0x73, 0x65, 0x22, 0x1e, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x18, 0x22, 0x13, 0x2f, 0x76, 0x32,
0x2f, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x2f, 0x6c, 0x6f, 0x67, 0x69, 0x6e,
0x3a, 0x01, 0x2a, 0x12, 0x84, 0x01, 0x0a, 0x06, 0x53, 0x69, 0x67, 0x6e, 0x75, 0x70, 0x12, 0x2b,
0x2e, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61,
0x74, 0x6f, 0x72, 0x2e, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x73, 0x2e, 0x76, 0x32, 0x2e,
0x41, 0x75, 0x74, 0x68, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2c, 0x2e, 0x65, 0x74,
0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72,
0x2e, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x73, 0x2e, 0x76, 0x32, 0x2e, 0x41, 0x75, 0x74,
0x68, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x1f, 0x82, 0xd3, 0xe4, 0x93, 0x02,
0x19, 0x22, 0x14, 0x2f, 0x76, 0x32, 0x2f, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72,
0x2f, 0x73, 0x69, 0x67, 0x6e, 0x75, 0x70, 0x3a, 0x01, 0x2a, 0x12, 0x59, 0x0a, 0x06, 0x4c, 0x6f,
0x67, 0x6f, 0x75, 0x74, 0x12, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72,
0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x16, 0x2e, 0x67,
0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45,
0x6d, 0x70, 0x74, 0x79, 0x22, 0x1f, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x19, 0x22, 0x14, 0x2f, 0x76,
0x32, 0x2f, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x2f, 0x6c, 0x6f, 0x67, 0x6f,
0x75, 0x74, 0x3a, 0x01, 0x2a, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
0x6e, 0x74, 0x73, 0x2e, 0x76, 0x32, 0x2e, 0x41, 0x75, 0x74, 0x68, 0x52, 0x65, 0x71, 0x75, 0x65,
0x73, 0x74, 0x1a, 0x2c, 0x2e, 0x65, 0x74, 0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x2e, 0x76, 0x61,
0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x2e, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x73,
0x2e, 0x76, 0x32, 0x2e, 0x41, 0x75, 0x74, 0x68, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65,
0x22, 0x1f, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x19, 0x22, 0x14, 0x2f, 0x76, 0x32, 0x2f, 0x76, 0x61,
0x6c, 0x69, 0x64, 0x61, 0x74, 0x6f, 0x72, 0x2f, 0x73, 0x69, 0x67, 0x6e, 0x75, 0x70, 0x3a, 0x01,
0x2a, 0x12, 0x59, 0x0a, 0x06, 0x4c, 0x6f, 0x67, 0x6f, 0x75, 0x74, 0x12, 0x16, 0x2e, 0x67, 0x6f,
0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d,
0x70, 0x74, 0x79, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f,
0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x22, 0x1f, 0x82, 0xd3, 0xe4,
0x93, 0x02, 0x19, 0x22, 0x14, 0x2f, 0x76, 0x32, 0x2f, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74,
0x6f, 0x72, 0x2f, 0x6c, 0x6f, 0x67, 0x6f, 0x75, 0x74, 0x3a, 0x01, 0x2a, 0x62, 0x06, 0x70, 0x72,
0x6f, 0x74, 0x6f, 0x33,
}
var (
@@ -1739,7 +1678,7 @@ func file_proto_validator_accounts_v2_web_api_proto_rawDescGZIP() []byte {
}
var file_proto_validator_accounts_v2_web_api_proto_enumTypes = make([]protoimpl.EnumInfo, 1)
var file_proto_validator_accounts_v2_web_api_proto_msgTypes = make([]protoimpl.MessageInfo, 24)
var file_proto_validator_accounts_v2_web_api_proto_msgTypes = make([]protoimpl.MessageInfo, 23)
var file_proto_validator_accounts_v2_web_api_proto_goTypes = []interface{}{
(KeymanagerKind)(0), // 0: ethereum.validator.accounts.v2.KeymanagerKind
(*CreateWalletRequest)(nil), // 1: ethereum.validator.accounts.v2.CreateWalletRequest
@@ -1758,53 +1697,50 @@ var file_proto_validator_accounts_v2_web_api_proto_goTypes = []interface{}{
(*HasWalletResponse)(nil), // 14: ethereum.validator.accounts.v2.HasWalletResponse
(*ImportKeystoresRequest)(nil), // 15: ethereum.validator.accounts.v2.ImportKeystoresRequest
(*ImportKeystoresResponse)(nil), // 16: ethereum.validator.accounts.v2.ImportKeystoresResponse
(*CreateAccountRequest)(nil), // 17: ethereum.validator.accounts.v2.CreateAccountRequest
(*DepositMessage)(nil), // 18: ethereum.validator.accounts.v2.DepositMessage
(*DepositDataResponse)(nil), // 19: ethereum.validator.accounts.v2.DepositDataResponse
(*DeleteAccountsRequest)(nil), // 20: ethereum.validator.accounts.v2.DeleteAccountsRequest
(*DeleteAccountsResponse)(nil), // 21: ethereum.validator.accounts.v2.DeleteAccountsResponse
nil, // 22: ethereum.validator.accounts.v2.WalletResponse.KeymanagerConfigEntry
(*DepositDataResponse_DepositData)(nil), // 23: ethereum.validator.accounts.v2.DepositDataResponse.DepositData
nil, // 24: ethereum.validator.accounts.v2.DepositDataResponse.DepositData.DataEntry
(*empty.Empty)(nil), // 25: google.protobuf.Empty
(*DepositMessage)(nil), // 17: ethereum.validator.accounts.v2.DepositMessage
(*DepositDataResponse)(nil), // 18: ethereum.validator.accounts.v2.DepositDataResponse
(*DeleteAccountsRequest)(nil), // 19: ethereum.validator.accounts.v2.DeleteAccountsRequest
(*DeleteAccountsResponse)(nil), // 20: ethereum.validator.accounts.v2.DeleteAccountsResponse
nil, // 21: ethereum.validator.accounts.v2.WalletResponse.KeymanagerConfigEntry
(*DepositDataResponse_DepositData)(nil), // 22: ethereum.validator.accounts.v2.DepositDataResponse.DepositData
nil, // 23: ethereum.validator.accounts.v2.DepositDataResponse.DepositData.DataEntry
(*empty.Empty)(nil), // 24: google.protobuf.Empty
}
var file_proto_validator_accounts_v2_web_api_proto_depIdxs = []int32{
0, // 0: ethereum.validator.accounts.v2.CreateWalletRequest.keymanager:type_name -> ethereum.validator.accounts.v2.KeymanagerKind
5, // 1: ethereum.validator.accounts.v2.CreateWalletResponse.wallet:type_name -> ethereum.validator.accounts.v2.WalletResponse
19, // 2: ethereum.validator.accounts.v2.CreateWalletResponse.accounts_created:type_name -> ethereum.validator.accounts.v2.DepositDataResponse
18, // 2: ethereum.validator.accounts.v2.CreateWalletResponse.accounts_created:type_name -> ethereum.validator.accounts.v2.DepositDataResponse
0, // 3: ethereum.validator.accounts.v2.WalletResponse.keymanager_kind:type_name -> ethereum.validator.accounts.v2.KeymanagerKind
22, // 4: ethereum.validator.accounts.v2.WalletResponse.keymanager_config:type_name -> ethereum.validator.accounts.v2.WalletResponse.KeymanagerConfigEntry
21, // 4: ethereum.validator.accounts.v2.WalletResponse.keymanager_config:type_name -> ethereum.validator.accounts.v2.WalletResponse.KeymanagerConfigEntry
8, // 5: ethereum.validator.accounts.v2.ListAccountsResponse.accounts:type_name -> ethereum.validator.accounts.v2.Account
23, // 6: ethereum.validator.accounts.v2.DepositDataResponse.deposit_data_list:type_name -> ethereum.validator.accounts.v2.DepositDataResponse.DepositData
24, // 7: ethereum.validator.accounts.v2.DepositDataResponse.DepositData.data:type_name -> ethereum.validator.accounts.v2.DepositDataResponse.DepositData.DataEntry
25, // 8: ethereum.validator.accounts.v2.Wallet.HasWallet:input_type -> google.protobuf.Empty
22, // 6: ethereum.validator.accounts.v2.DepositDataResponse.deposit_data_list:type_name -> ethereum.validator.accounts.v2.DepositDataResponse.DepositData
23, // 7: ethereum.validator.accounts.v2.DepositDataResponse.DepositData.data:type_name -> ethereum.validator.accounts.v2.DepositDataResponse.DepositData.DataEntry
24, // 8: ethereum.validator.accounts.v2.Wallet.HasWallet:input_type -> google.protobuf.Empty
1, // 9: ethereum.validator.accounts.v2.Wallet.CreateWallet:input_type -> ethereum.validator.accounts.v2.CreateWalletRequest
3, // 10: ethereum.validator.accounts.v2.Wallet.EditConfig:input_type -> ethereum.validator.accounts.v2.EditWalletConfigRequest
25, // 11: ethereum.validator.accounts.v2.Wallet.WalletConfig:input_type -> google.protobuf.Empty
25, // 12: ethereum.validator.accounts.v2.Wallet.GenerateMnemonic:input_type -> google.protobuf.Empty
24, // 11: ethereum.validator.accounts.v2.Wallet.WalletConfig:input_type -> google.protobuf.Empty
24, // 12: ethereum.validator.accounts.v2.Wallet.GenerateMnemonic:input_type -> google.protobuf.Empty
15, // 13: ethereum.validator.accounts.v2.Wallet.ImportKeystores:input_type -> ethereum.validator.accounts.v2.ImportKeystoresRequest
17, // 14: ethereum.validator.accounts.v2.Accounts.CreateAccount:input_type -> ethereum.validator.accounts.v2.CreateAccountRequest
6, // 15: ethereum.validator.accounts.v2.Accounts.ListAccounts:input_type -> ethereum.validator.accounts.v2.ListAccountsRequest
13, // 16: ethereum.validator.accounts.v2.Accounts.ChangePassword:input_type -> ethereum.validator.accounts.v2.ChangePasswordRequest
25, // 17: ethereum.validator.accounts.v2.Health.GetBeaconNodeConnection:input_type -> google.protobuf.Empty
10, // 18: ethereum.validator.accounts.v2.Auth.Login:input_type -> ethereum.validator.accounts.v2.AuthRequest
10, // 19: ethereum.validator.accounts.v2.Auth.Signup:input_type -> ethereum.validator.accounts.v2.AuthRequest
25, // 20: ethereum.validator.accounts.v2.Auth.Logout:input_type -> google.protobuf.Empty
14, // 21: ethereum.validator.accounts.v2.Wallet.HasWallet:output_type -> ethereum.validator.accounts.v2.HasWalletResponse
2, // 22: ethereum.validator.accounts.v2.Wallet.CreateWallet:output_type -> ethereum.validator.accounts.v2.CreateWalletResponse
5, // 23: ethereum.validator.accounts.v2.Wallet.EditConfig:output_type -> ethereum.validator.accounts.v2.WalletResponse
5, // 24: ethereum.validator.accounts.v2.Wallet.WalletConfig:output_type -> ethereum.validator.accounts.v2.WalletResponse
4, // 25: ethereum.validator.accounts.v2.Wallet.GenerateMnemonic:output_type -> ethereum.validator.accounts.v2.GenerateMnemonicResponse
16, // 26: ethereum.validator.accounts.v2.Wallet.ImportKeystores:output_type -> ethereum.validator.accounts.v2.ImportKeystoresResponse
19, // 27: ethereum.validator.accounts.v2.Accounts.CreateAccount:output_type -> ethereum.validator.accounts.v2.DepositDataResponse
7, // 28: ethereum.validator.accounts.v2.Accounts.ListAccounts:output_type -> ethereum.validator.accounts.v2.ListAccountsResponse
25, // 29: ethereum.validator.accounts.v2.Accounts.ChangePassword:output_type -> google.protobuf.Empty
12, // 30: ethereum.validator.accounts.v2.Health.GetBeaconNodeConnection:output_type -> ethereum.validator.accounts.v2.NodeConnectionResponse
11, // 31: ethereum.validator.accounts.v2.Auth.Login:output_type -> ethereum.validator.accounts.v2.AuthResponse
11, // 32: ethereum.validator.accounts.v2.Auth.Signup:output_type -> ethereum.validator.accounts.v2.AuthResponse
25, // 33: ethereum.validator.accounts.v2.Auth.Logout:output_type -> google.protobuf.Empty
21, // [21:34] is the sub-list for method output_type
8, // [8:21] is the sub-list for method input_type
6, // 14: ethereum.validator.accounts.v2.Accounts.ListAccounts:input_type -> ethereum.validator.accounts.v2.ListAccountsRequest
13, // 15: ethereum.validator.accounts.v2.Accounts.ChangePassword:input_type -> ethereum.validator.accounts.v2.ChangePasswordRequest
24, // 16: ethereum.validator.accounts.v2.Health.GetBeaconNodeConnection:input_type -> google.protobuf.Empty
10, // 17: ethereum.validator.accounts.v2.Auth.Login:input_type -> ethereum.validator.accounts.v2.AuthRequest
10, // 18: ethereum.validator.accounts.v2.Auth.Signup:input_type -> ethereum.validator.accounts.v2.AuthRequest
24, // 19: ethereum.validator.accounts.v2.Auth.Logout:input_type -> google.protobuf.Empty
14, // 20: ethereum.validator.accounts.v2.Wallet.HasWallet:output_type -> ethereum.validator.accounts.v2.HasWalletResponse
2, // 21: ethereum.validator.accounts.v2.Wallet.CreateWallet:output_type -> ethereum.validator.accounts.v2.CreateWalletResponse
5, // 22: ethereum.validator.accounts.v2.Wallet.EditConfig:output_type -> ethereum.validator.accounts.v2.WalletResponse
5, // 23: ethereum.validator.accounts.v2.Wallet.WalletConfig:output_type -> ethereum.validator.accounts.v2.WalletResponse
4, // 24: ethereum.validator.accounts.v2.Wallet.GenerateMnemonic:output_type -> ethereum.validator.accounts.v2.GenerateMnemonicResponse
16, // 25: ethereum.validator.accounts.v2.Wallet.ImportKeystores:output_type -> ethereum.validator.accounts.v2.ImportKeystoresResponse
7, // 26: ethereum.validator.accounts.v2.Accounts.ListAccounts:output_type -> ethereum.validator.accounts.v2.ListAccountsResponse
24, // 27: ethereum.validator.accounts.v2.Accounts.ChangePassword:output_type -> google.protobuf.Empty
12, // 28: ethereum.validator.accounts.v2.Health.GetBeaconNodeConnection:output_type -> ethereum.validator.accounts.v2.NodeConnectionResponse
11, // 29: ethereum.validator.accounts.v2.Auth.Login:output_type -> ethereum.validator.accounts.v2.AuthResponse
11, // 30: ethereum.validator.accounts.v2.Auth.Signup:output_type -> ethereum.validator.accounts.v2.AuthResponse
24, // 31: ethereum.validator.accounts.v2.Auth.Logout:output_type -> google.protobuf.Empty
20, // [20:32] is the sub-list for method output_type
8, // [8:20] is the sub-list for method input_type
8, // [8:8] is the sub-list for extension type_name
8, // [8:8] is the sub-list for extension extendee
0, // [0:8] is the sub-list for field type_name
@@ -2009,18 +1945,6 @@ func file_proto_validator_accounts_v2_web_api_proto_init() {
}
}
file_proto_validator_accounts_v2_web_api_proto_msgTypes[16].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*CreateAccountRequest); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_proto_validator_accounts_v2_web_api_proto_msgTypes[17].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*DepositMessage); i {
case 0:
return &v.state
@@ -2032,7 +1956,7 @@ func file_proto_validator_accounts_v2_web_api_proto_init() {
return nil
}
}
file_proto_validator_accounts_v2_web_api_proto_msgTypes[18].Exporter = func(v interface{}, i int) interface{} {
file_proto_validator_accounts_v2_web_api_proto_msgTypes[17].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*DepositDataResponse); i {
case 0:
return &v.state
@@ -2044,7 +1968,7 @@ func file_proto_validator_accounts_v2_web_api_proto_init() {
return nil
}
}
file_proto_validator_accounts_v2_web_api_proto_msgTypes[19].Exporter = func(v interface{}, i int) interface{} {
file_proto_validator_accounts_v2_web_api_proto_msgTypes[18].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*DeleteAccountsRequest); i {
case 0:
return &v.state
@@ -2056,7 +1980,7 @@ func file_proto_validator_accounts_v2_web_api_proto_init() {
return nil
}
}
file_proto_validator_accounts_v2_web_api_proto_msgTypes[20].Exporter = func(v interface{}, i int) interface{} {
file_proto_validator_accounts_v2_web_api_proto_msgTypes[19].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*DeleteAccountsResponse); i {
case 0:
return &v.state
@@ -2068,7 +1992,7 @@ func file_proto_validator_accounts_v2_web_api_proto_init() {
return nil
}
}
file_proto_validator_accounts_v2_web_api_proto_msgTypes[22].Exporter = func(v interface{}, i int) interface{} {
file_proto_validator_accounts_v2_web_api_proto_msgTypes[21].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*DepositDataResponse_DepositData); i {
case 0:
return &v.state
@@ -2087,7 +2011,7 @@ func file_proto_validator_accounts_v2_web_api_proto_init() {
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
RawDescriptor: file_proto_validator_accounts_v2_web_api_proto_rawDesc,
NumEnums: 1,
NumMessages: 24,
NumMessages: 23,
NumExtensions: 0,
NumServices: 4,
},
@@ -2366,7 +2290,6 @@ var _Wallet_serviceDesc = grpc.ServiceDesc{
//
// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream.
type AccountsClient interface {
CreateAccount(ctx context.Context, in *CreateAccountRequest, opts ...grpc.CallOption) (*DepositDataResponse, error)
ListAccounts(ctx context.Context, in *ListAccountsRequest, opts ...grpc.CallOption) (*ListAccountsResponse, error)
ChangePassword(ctx context.Context, in *ChangePasswordRequest, opts ...grpc.CallOption) (*empty.Empty, error)
}
@@ -2379,15 +2302,6 @@ func NewAccountsClient(cc grpc.ClientConnInterface) AccountsClient {
return &accountsClient{cc}
}
func (c *accountsClient) CreateAccount(ctx context.Context, in *CreateAccountRequest, opts ...grpc.CallOption) (*DepositDataResponse, error) {
out := new(DepositDataResponse)
err := c.cc.Invoke(ctx, "/ethereum.validator.accounts.v2.Accounts/CreateAccount", in, out, opts...)
if err != nil {
return nil, err
}
return out, nil
}
func (c *accountsClient) ListAccounts(ctx context.Context, in *ListAccountsRequest, opts ...grpc.CallOption) (*ListAccountsResponse, error) {
out := new(ListAccountsResponse)
err := c.cc.Invoke(ctx, "/ethereum.validator.accounts.v2.Accounts/ListAccounts", in, out, opts...)
@@ -2408,7 +2322,6 @@ func (c *accountsClient) ChangePassword(ctx context.Context, in *ChangePasswordR
// AccountsServer is the server API for Accounts service.
type AccountsServer interface {
CreateAccount(context.Context, *CreateAccountRequest) (*DepositDataResponse, error)
ListAccounts(context.Context, *ListAccountsRequest) (*ListAccountsResponse, error)
ChangePassword(context.Context, *ChangePasswordRequest) (*empty.Empty, error)
}
@@ -2417,9 +2330,6 @@ type AccountsServer interface {
type UnimplementedAccountsServer struct {
}
func (*UnimplementedAccountsServer) CreateAccount(context.Context, *CreateAccountRequest) (*DepositDataResponse, error) {
return nil, status.Errorf(codes.Unimplemented, "method CreateAccount not implemented")
}
func (*UnimplementedAccountsServer) ListAccounts(context.Context, *ListAccountsRequest) (*ListAccountsResponse, error) {
return nil, status.Errorf(codes.Unimplemented, "method ListAccounts not implemented")
}
@@ -2431,24 +2341,6 @@ func RegisterAccountsServer(s *grpc.Server, srv AccountsServer) {
s.RegisterService(&_Accounts_serviceDesc, srv)
}
func _Accounts_CreateAccount_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(CreateAccountRequest)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(AccountsServer).CreateAccount(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: "/ethereum.validator.accounts.v2.Accounts/CreateAccount",
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(AccountsServer).CreateAccount(ctx, req.(*CreateAccountRequest))
}
return interceptor(ctx, in, info, handler)
}
func _Accounts_ListAccounts_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(ListAccountsRequest)
if err := dec(in); err != nil {
@@ -2489,10 +2381,6 @@ var _Accounts_serviceDesc = grpc.ServiceDesc{
ServiceName: "ethereum.validator.accounts.v2.Accounts",
HandlerType: (*AccountsServer)(nil),
Methods: []grpc.MethodDesc{
{
MethodName: "CreateAccount",
Handler: _Accounts_CreateAccount_Handler,
},
{
MethodName: "ListAccounts",
Handler: _Accounts_ListAccounts_Handler,

View File

@@ -188,40 +188,6 @@ func local_request_Wallet_ImportKeystores_0(ctx context.Context, marshaler runti
}
func request_Accounts_CreateAccount_0(ctx context.Context, marshaler runtime.Marshaler, client AccountsClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
var protoReq CreateAccountRequest
var metadata runtime.ServerMetadata
newReader, berr := utilities.IOReaderFactory(req.Body)
if berr != nil {
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", berr)
}
if err := marshaler.NewDecoder(newReader()).Decode(&protoReq); err != nil && err != io.EOF {
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
}
msg, err := client.CreateAccount(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
return msg, metadata, err
}
func local_request_Accounts_CreateAccount_0(ctx context.Context, marshaler runtime.Marshaler, server AccountsServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
var protoReq CreateAccountRequest
var metadata runtime.ServerMetadata
newReader, berr := utilities.IOReaderFactory(req.Body)
if berr != nil {
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", berr)
}
if err := marshaler.NewDecoder(newReader()).Decode(&protoReq); err != nil && err != io.EOF {
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
}
msg, err := server.CreateAccount(ctx, &protoReq)
return msg, metadata, err
}
var (
filter_Accounts_ListAccounts_0 = &utilities.DoubleArray{Encoding: map[string]int{}, Base: []int(nil), Check: []int(nil)}
)
@@ -545,26 +511,6 @@ func RegisterWalletHandlerServer(ctx context.Context, mux *runtime.ServeMux, ser
// StreamingRPC :currently unsupported pending https://github.com/grpc/grpc-go/issues/906.
func RegisterAccountsHandlerServer(ctx context.Context, mux *runtime.ServeMux, server AccountsServer) error {
mux.Handle("POST", pattern_Accounts_CreateAccount_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
ctx, cancel := context.WithCancel(req.Context())
defer cancel()
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req)
if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
}
resp, md, err := local_request_Accounts_CreateAccount_0(rctx, inboundMarshaler, server, req, pathParams)
ctx = runtime.NewServerMetadataContext(ctx, md)
if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
}
forward_Accounts_CreateAccount_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
})
mux.Handle("GET", pattern_Accounts_ListAccounts_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
ctx, cancel := context.WithCancel(req.Context())
defer cancel()
@@ -931,26 +877,6 @@ func RegisterAccountsHandler(ctx context.Context, mux *runtime.ServeMux, conn *g
// "AccountsClient" to call the correct interceptors.
func RegisterAccountsHandlerClient(ctx context.Context, mux *runtime.ServeMux, client AccountsClient) error {
mux.Handle("POST", pattern_Accounts_CreateAccount_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
ctx, cancel := context.WithCancel(req.Context())
defer cancel()
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
rctx, err := runtime.AnnotateContext(ctx, mux, req)
if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
}
resp, md, err := request_Accounts_CreateAccount_0(rctx, inboundMarshaler, client, req, pathParams)
ctx = runtime.NewServerMetadataContext(ctx, md)
if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
}
forward_Accounts_CreateAccount_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
})
mux.Handle("GET", pattern_Accounts_ListAccounts_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
ctx, cancel := context.WithCancel(req.Context())
defer cancel()
@@ -995,16 +921,12 @@ func RegisterAccountsHandlerClient(ctx context.Context, mux *runtime.ServeMux, c
}
var (
pattern_Accounts_CreateAccount_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3, 2, 4}, []string{"v2", "validator", "wallet", "accounts", "create"}, "", runtime.AssumeColonVerbOpt(true)))
pattern_Accounts_ListAccounts_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2}, []string{"v2", "validator", "accounts"}, "", runtime.AssumeColonVerbOpt(true)))
pattern_Accounts_ChangePassword_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3}, []string{"v2", "validator", "password", "edit"}, "", runtime.AssumeColonVerbOpt(true)))
)
var (
forward_Accounts_CreateAccount_0 = runtime.ForwardResponseMessage
forward_Accounts_ListAccounts_0 = runtime.ForwardResponseMessage
forward_Accounts_ChangePassword_0 = runtime.ForwardResponseMessage

View File

@@ -6,7 +6,6 @@ go_library(
srcs = [
"accounts.go",
"accounts_backup.go",
"accounts_create.go",
"accounts_delete.go",
"accounts_enable_disable.go",
"accounts_exit.go",
@@ -27,17 +26,14 @@ go_library(
],
deps = [
"//beacon-chain/core/blocks:go_default_library",
"//proto/validator/accounts/v2:go_default_library",
"//shared/bls:go_default_library",
"//shared/bytesutil:go_default_library",
"//shared/cmd:go_default_library",
"//shared/featureconfig:go_default_library",
"//shared/fileutil:go_default_library",
"//shared/params:go_default_library",
"//shared/petnames:go_default_library",
"//shared/promptutil:go_default_library",
"//shared/tos:go_default_library",
"//validator/accounts/iface:go_default_library",
"//validator/accounts/prompt:go_default_library",
"//validator/accounts/wallet:go_default_library",
"//validator/client:go_default_library",
@@ -64,7 +60,6 @@ go_test(
name = "go_default_test",
srcs = [
"accounts_backup_test.go",
"accounts_create_test.go",
"accounts_delete_test.go",
"accounts_enable_disable_test.go",
"accounts_exit_test.go",
@@ -86,7 +81,6 @@ go_test(
"//shared/testutil/assert:go_default_library",
"//shared/testutil/require:go_default_library",
"//shared/timeutils:go_default_library",
"//validator/accounts/iface:go_default_library",
"//validator/accounts/wallet:go_default_library",
"//validator/flags:go_default_library",
"//validator/keymanager:go_default_library",

View File

@@ -3,8 +3,11 @@ package accounts
import (
"github.com/prysmaticlabs/prysm/validator/accounts/wallet"
"github.com/prysmaticlabs/prysm/validator/keymanager"
"github.com/sirupsen/logrus"
)
var log = logrus.WithField("prefix", "accounts")
// AccountsConfig specifies parameters to run to delete, enable, disable accounts.
type AccountsConfig struct {
Wallet *wallet.Wallet

View File

@@ -17,7 +17,6 @@ import (
"github.com/prysmaticlabs/prysm/shared/fileutil"
"github.com/prysmaticlabs/prysm/shared/petnames"
"github.com/prysmaticlabs/prysm/shared/promptutil"
"github.com/prysmaticlabs/prysm/validator/accounts/iface"
"github.com/prysmaticlabs/prysm/validator/accounts/prompt"
"github.com/prysmaticlabs/prysm/validator/accounts/wallet"
"github.com/prysmaticlabs/prysm/validator/flags"
@@ -52,9 +51,7 @@ func BackupAccountsCli(cliCtx *cli.Context) error {
"remote wallets cannot backup accounts",
)
}
km, err := w.InitializeKeymanager(cliCtx.Context, &iface.InitializeKeymanagerConfig{
SkipMnemonicConfirm: false,
})
km, err := w.InitializeKeymanager(cliCtx.Context)
if err != nil {
return errors.Wrap(err, "could not initialize keymanager")
}

View File

@@ -16,9 +16,13 @@ import (
"github.com/prysmaticlabs/prysm/shared/params"
"github.com/prysmaticlabs/prysm/shared/testutil/assert"
"github.com/prysmaticlabs/prysm/shared/testutil/require"
"github.com/prysmaticlabs/prysm/validator/accounts/iface"
"github.com/prysmaticlabs/prysm/validator/accounts/wallet"
"github.com/prysmaticlabs/prysm/validator/keymanager"
"github.com/prysmaticlabs/prysm/validator/keymanager/derived"
)
var (
testMnemonic = "tumble turn jewel sudden social great water general cabin jacket bounce dry flip monster advance problem social half flee inform century chicken hard reason"
)
func TestBackupAccounts_Noninteractive_Derived(t *testing.T) {
@@ -59,19 +63,12 @@ func TestBackupAccounts_Noninteractive_Derived(t *testing.T) {
})
require.NoError(t, err)
// Create 2 accounts
err = CreateAccount(cliCtx.Context, &CreateAccountConfig{
Wallet: w,
NumAccounts: 2,
})
km, err := w.InitializeKeymanager(cliCtx.Context)
require.NoError(t, err)
km, err := w.InitializeKeymanager(
cliCtx.Context,
&iface.InitializeKeymanagerConfig{
SkipMnemonicConfirm: true,
},
)
// Create 2 accounts
derivedKM, ok := km.(*derived.Keymanager)
require.Equal(t, true, ok)
err = derivedKM.RecoverAccountsFromMnemonic(cliCtx.Context, testMnemonic, "", 2)
require.NoError(t, err)
// Obtain the public keys of the accounts we created

View File

@@ -1,119 +0,0 @@
package accounts
import (
"context"
"fmt"
"strings"
"github.com/pkg/errors"
ethpb "github.com/prysmaticlabs/ethereumapis/eth/v1alpha1"
pb "github.com/prysmaticlabs/prysm/proto/validator/accounts/v2"
"github.com/prysmaticlabs/prysm/shared/params"
"github.com/prysmaticlabs/prysm/validator/accounts/iface"
"github.com/prysmaticlabs/prysm/validator/accounts/wallet"
"github.com/prysmaticlabs/prysm/validator/flags"
"github.com/prysmaticlabs/prysm/validator/keymanager"
"github.com/prysmaticlabs/prysm/validator/keymanager/derived"
"github.com/sirupsen/logrus"
"github.com/urfave/cli/v2"
)
var log = logrus.WithField("prefix", "accounts")
// CreateAccountConfig to run the create account function.
type CreateAccountConfig struct {
Wallet *wallet.Wallet
NumAccounts int64
}
// CreateAccountCli creates a new validator account from user input by opening
// a wallet from the user's specified path. This uses the CLI to extract information
// to perform account creation.
func CreateAccountCli(cliCtx *cli.Context) error {
w, err := wallet.OpenWalletOrElseCli(cliCtx, CreateAndSaveWalletCli)
if err != nil {
return err
}
numAccounts := cliCtx.Int64(flags.NumAccountsFlag.Name)
log.Info("Creating a new account...")
return CreateAccount(cliCtx.Context, &CreateAccountConfig{
Wallet: w,
NumAccounts: numAccounts,
})
}
// CreateAccount creates a new validator account from user input by opening
// a wallet from the user's specified path.
func CreateAccount(ctx context.Context, cfg *CreateAccountConfig) error {
km, err := cfg.Wallet.InitializeKeymanager(ctx, &iface.InitializeKeymanagerConfig{
SkipMnemonicConfirm: false,
})
if err != nil && strings.Contains(err.Error(), "invalid checksum") {
return errors.New("wrong wallet password entered")
}
if err != nil {
return errors.Wrap(err, "could not initialize keymanager")
}
switch cfg.Wallet.KeymanagerKind() {
case keymanager.Remote:
return errors.New("cannot create a new account for a remote keymanager")
case keymanager.Imported:
return errors.New("cannot create a new account for an imported wallet")
case keymanager.Derived:
km, ok := km.(*derived.Keymanager)
if !ok {
return errors.New("not a derived keymanager")
}
startNum := km.NextAccountNumber()
if cfg.NumAccounts == 1 {
if _, _, err := km.CreateAccount(ctx); err != nil {
return errors.Wrap(err, "could not create account in wallet")
}
} else {
for i := 0; i < int(cfg.NumAccounts); i++ {
if _, _, err := km.CreateAccount(ctx); err != nil {
return errors.Wrap(err, "could not create account in wallet")
}
}
log.Infof(
"Successfully created %d accounts. Please use accounts list to view details for accounts %d through %d",
cfg.NumAccounts,
startNum,
startNum+uint64(cfg.NumAccounts)-1,
)
}
default:
return fmt.Errorf("keymanager kind %s not supported", cfg.Wallet.KeymanagerKind())
}
return nil
}
// DepositDataJSON creates a raw map to match the deposit_data.json file format
// from the official eth2.0-deposit-cli https://github.com/ethereum/eth2.0-deposit-cli.
// The reason we utilize this map is to ensure we match the format of
// the eth2 deposit cli, which utilizes snake case and hex strings to represent binary data.
// Our gRPC gateway instead uses camel case and base64, which is why we use this workaround.
func DepositDataJSON(depositData *ethpb.Deposit_Data) (map[string]string, error) {
depositMessage := &pb.DepositMessage{
Pubkey: depositData.PublicKey,
WithdrawalCredentials: depositData.WithdrawalCredentials,
Amount: depositData.Amount,
}
depositMessageRoot, err := depositMessage.HashTreeRoot()
if err != nil {
return nil, err
}
depositDataRoot, err := depositData.HashTreeRoot()
if err != nil {
return nil, err
}
data := make(map[string]string)
data["pubkey"] = fmt.Sprintf("%x", depositData.PublicKey)
data["withdrawal_credentials"] = fmt.Sprintf("%x", depositData.WithdrawalCredentials)
data["amount"] = fmt.Sprintf("%d", depositData.Amount)
data["signature"] = fmt.Sprintf("%x", depositData.Signature)
data["deposit_message_root"] = fmt.Sprintf("%x", depositMessageRoot)
data["deposit_data_root"] = fmt.Sprintf("%x", depositDataRoot)
data["fork_version"] = fmt.Sprintf("%x", params.BeaconConfig().GenesisForkVersion)
return data, nil
}

View File

@@ -1,93 +0,0 @@
package accounts
import (
"context"
"encoding/hex"
"fmt"
"testing"
ethpb "github.com/prysmaticlabs/ethereumapis/eth/v1alpha1"
"github.com/prysmaticlabs/prysm/shared/params"
"github.com/prysmaticlabs/prysm/shared/testutil/assert"
"github.com/prysmaticlabs/prysm/shared/testutil/require"
"github.com/prysmaticlabs/prysm/validator/accounts/iface"
"github.com/prysmaticlabs/prysm/validator/accounts/wallet"
"github.com/prysmaticlabs/prysm/validator/keymanager"
"github.com/prysmaticlabs/prysm/validator/keymanager/derived"
)
func TestCreateAccount_Derived(t *testing.T) {
walletDir, passwordsDir, passwordFile := setupWalletAndPasswordsDir(t)
numAccounts := int64(5)
cliCtx := setupWalletCtx(t, &testWalletConfig{
walletDir: walletDir,
passwordsDir: passwordsDir,
walletPasswordFile: passwordFile,
accountPasswordFile: passwordFile,
keymanagerKind: keymanager.Derived,
numAccounts: numAccounts,
})
// We attempt to create the wallet.
_, err := CreateAndSaveWalletCli(cliCtx)
require.NoError(t, err)
// We attempt to open the newly created wallet.
ctx := context.Background()
w, err := wallet.OpenWallet(cliCtx.Context, &wallet.Config{
WalletDir: walletDir,
WalletPassword: password,
})
assert.NoError(t, err)
// We read the keymanager config for the newly created wallet.
encoded, err := w.ReadKeymanagerConfigFromDisk(ctx)
assert.NoError(t, err)
opts, err := derived.UnmarshalOptionsFile(encoded)
assert.NoError(t, err)
// We assert the created configuration was as desired.
assert.DeepEqual(t, derived.DefaultKeymanagerOpts(), opts)
require.NoError(t, CreateAccountCli(cliCtx))
keymanager, err := w.InitializeKeymanager(cliCtx.Context, &iface.InitializeKeymanagerConfig{
SkipMnemonicConfirm: true,
})
require.NoError(t, err)
km, ok := keymanager.(*derived.Keymanager)
if !ok {
t.Fatal("not a derived keymanager")
}
names, err := km.ValidatingAccountNames(ctx)
assert.NoError(t, err)
require.Equal(t, len(names), int(numAccounts))
}
func TestDepositDataJSON(t *testing.T) {
// Use a real deposit data JSON fixture generated by the eth2 deposit cli
fixture := make(map[string]string)
fixture["pubkey"] = "a611f309b4a24853e0b04bd70e35fbac887e099b9f81c2fac2bb2cde9f6f58bd37d947be552ec515b1f45d406f61de27"
fixture["withdrawal_credentials"] = "003561705197f621bfaa59add59ee066e6f2fe356201d00c610ed5d6cd7fcb83"
fixture["amount"] = "32000000000"
fixture["signature"] = "b0a27f2e7684fc1aa6403e2e76dcbcf29568ba02e9076e61b4c926bccec25ec636a1fdc8d08457cf23a1715ea9ee4fe20b030820e2fcf6dee07a3ce5e6ec65a824027f4cb01c143db74b34f5ca54f7e011d84fe89ce55b0e75f39003e2c9afe9"
fixture["deposit_message_root"] = "12c267fdc80fb07b47770f8fcf5e25ed2280df391d7de224cc6486e925b7d7f9"
fixture["deposit_data_root"] = "3b3c62bcff04d0249209c79a76cea98520932609986c11cb4ff62a4f54b76548"
fixture["fork_version"] = fmt.Sprintf("%x", params.BeaconConfig().GenesisForkVersion)
pubKey, err := hex.DecodeString(fixture["pubkey"])
require.NoError(t, err)
credentials, err := hex.DecodeString(fixture["withdrawal_credentials"])
require.NoError(t, err)
sig, err := hex.DecodeString(fixture["signature"])
require.NoError(t, err)
depositData := &ethpb.Deposit_Data{
PublicKey: pubKey,
WithdrawalCredentials: credentials,
Amount: 32000000000,
Signature: sig,
}
got, err := DepositDataJSON(depositData)
require.NoError(t, err)
assert.DeepEqual(t, fixture, got)
}

View File

@@ -9,11 +9,11 @@ import (
"github.com/pkg/errors"
"github.com/prysmaticlabs/prysm/shared/bytesutil"
"github.com/prysmaticlabs/prysm/shared/promptutil"
"github.com/prysmaticlabs/prysm/validator/accounts/iface"
"github.com/prysmaticlabs/prysm/validator/accounts/prompt"
"github.com/prysmaticlabs/prysm/validator/accounts/wallet"
"github.com/prysmaticlabs/prysm/validator/flags"
"github.com/prysmaticlabs/prysm/validator/keymanager"
"github.com/prysmaticlabs/prysm/validator/keymanager/derived"
"github.com/prysmaticlabs/prysm/validator/keymanager/imported"
"github.com/urfave/cli/v2"
)
@@ -27,9 +27,7 @@ func DeleteAccountCli(cliCtx *cli.Context) error {
if err != nil {
return errors.Wrap(err, "could not open wallet")
}
keymanager, err := w.InitializeKeymanager(cliCtx.Context, &iface.InitializeKeymanagerConfig{
SkipMnemonicConfirm: false,
})
keymanager, err := w.InitializeKeymanager(cliCtx.Context)
if err != nil {
return errors.Wrap(err, "could not initialize keymanager")
}
@@ -120,7 +118,18 @@ func DeleteAccount(ctx context.Context, cfg *AccountsConfig) error {
return errors.Wrap(err, "could not delete accounts")
}
case keymanager.Derived:
return errors.New("cannot delete accounts for a derived keymanager")
km, ok := cfg.Keymanager.(*derived.Keymanager)
if !ok {
return errors.New("not a derived keymanager")
}
if len(cfg.DeletePublicKeys) == 1 {
log.Info("Deleting account...")
} else {
log.Info("Deleting accounts...")
}
if err := km.DeleteAccounts(ctx, cfg.DeletePublicKeys); err != nil {
return errors.Wrap(err, "could not delete accounts")
}
default:
return fmt.Errorf("keymanager kind %s not supported", cfg.Wallet.KeymanagerKind())
}

View File

@@ -9,7 +9,6 @@ import (
"github.com/pkg/errors"
"github.com/prysmaticlabs/prysm/shared/bytesutil"
"github.com/prysmaticlabs/prysm/shared/promptutil"
"github.com/prysmaticlabs/prysm/validator/accounts/iface"
"github.com/prysmaticlabs/prysm/validator/accounts/prompt"
"github.com/prysmaticlabs/prysm/validator/accounts/wallet"
"github.com/prysmaticlabs/prysm/validator/flags"
@@ -26,9 +25,7 @@ func DisableAccountsCli(cliCtx *cli.Context) error {
if err != nil {
return errors.Wrap(err, "could not open wallet")
}
keymanager, err := w.InitializeKeymanager(cliCtx.Context, &iface.InitializeKeymanagerConfig{
SkipMnemonicConfirm: false,
})
keymanager, err := w.InitializeKeymanager(cliCtx.Context)
if err != nil {
return errors.Wrap(err, "could not initialize keymanager")
}
@@ -105,9 +102,7 @@ func EnableAccountsCli(cliCtx *cli.Context) error {
if err != nil {
return errors.Wrap(err, "could not open wallet")
}
ikeymanager, err := w.InitializeKeymanager(cliCtx.Context, &iface.InitializeKeymanagerConfig{
SkipMnemonicConfirm: false,
})
ikeymanager, err := w.InitializeKeymanager(cliCtx.Context)
if err != nil {
return errors.Wrap(err, "could not initialize keymanager")
}

View File

@@ -14,7 +14,6 @@ import (
"github.com/prysmaticlabs/prysm/shared/bytesutil"
"github.com/prysmaticlabs/prysm/shared/testutil/assert"
"github.com/prysmaticlabs/prysm/shared/testutil/require"
"github.com/prysmaticlabs/prysm/validator/accounts/iface"
"github.com/prysmaticlabs/prysm/validator/accounts/wallet"
"github.com/prysmaticlabs/prysm/validator/keymanager"
)
@@ -64,7 +63,7 @@ func TestDisableAccounts_Noninteractive(t *testing.T) {
// We attempt to disable the accounts specified.
require.NoError(t, DisableAccountsCli(cliCtx))
keymanager, err := w.InitializeKeymanager(cliCtx.Context, &iface.InitializeKeymanagerConfig{SkipMnemonicConfirm: false})
keymanager, err := w.InitializeKeymanager(cliCtx.Context)
require.NoError(t, err)
remainingAccounts, err := keymanager.FetchValidatingPublicKeys(cliCtx.Context)
require.NoError(t, err)
@@ -120,7 +119,7 @@ func TestEnableAccounts_Noninteractive(t *testing.T) {
// We attempt to disable the accounts specified.
require.NoError(t, DisableAccountsCli(cliCtx))
km, err := w.InitializeKeymanager(cliCtx.Context, &iface.InitializeKeymanagerConfig{SkipMnemonicConfirm: false})
km, err := w.InitializeKeymanager(cliCtx.Context)
require.NoError(t, err)
remainingAccounts, err := km.FetchValidatingPublicKeys(cliCtx.Context)
require.NoError(t, err)
@@ -129,7 +128,7 @@ func TestEnableAccounts_Noninteractive(t *testing.T) {
// We attempt to enable the accounts specified.
require.NoError(t, EnableAccountsCli(cliCtx))
km, err = w.InitializeKeymanager(cliCtx.Context, &iface.InitializeKeymanagerConfig{SkipMnemonicConfirm: false})
km, err = w.InitializeKeymanager(cliCtx.Context)
require.NoError(t, err)
remainingAccounts, err = km.FetchValidatingPublicKeys(cliCtx.Context)
require.NoError(t, err)

View File

@@ -12,7 +12,6 @@ import (
"github.com/prysmaticlabs/prysm/shared/bytesutil"
"github.com/prysmaticlabs/prysm/shared/cmd"
"github.com/prysmaticlabs/prysm/shared/promptutil"
"github.com/prysmaticlabs/prysm/validator/accounts/iface"
"github.com/prysmaticlabs/prysm/validator/accounts/prompt"
"github.com/prysmaticlabs/prysm/validator/accounts/wallet"
"github.com/prysmaticlabs/prysm/validator/client"
@@ -83,9 +82,7 @@ func prepareWallet(cliCtx *cli.Context) ([][48]byte, keymanager.IKeymanager, err
return nil, nil, errors.Wrap(err, "could not open wallet")
}
keymanager, err := w.InitializeKeymanager(cliCtx.Context, &iface.InitializeKeymanagerConfig{
SkipMnemonicConfirm: false,
})
keymanager, err := w.InitializeKeymanager(cliCtx.Context)
if err != nil {
return nil, nil, errors.Wrap(err, "could not initialize keymanager")
}

View File

@@ -18,7 +18,6 @@ import (
"github.com/prysmaticlabs/prysm/shared/bytesutil"
"github.com/prysmaticlabs/prysm/shared/fileutil"
"github.com/prysmaticlabs/prysm/shared/promptutil"
"github.com/prysmaticlabs/prysm/validator/accounts/iface"
"github.com/prysmaticlabs/prysm/validator/accounts/prompt"
"github.com/prysmaticlabs/prysm/validator/accounts/wallet"
"github.com/prysmaticlabs/prysm/validator/flags"
@@ -100,9 +99,7 @@ func ImportAccountsCli(cliCtx *cli.Context) error {
return errors.Wrap(err, "could not initialize wallet")
}
km, err := w.InitializeKeymanager(cliCtx.Context, &iface.InitializeKeymanagerConfig{
SkipMnemonicConfirm: true,
})
km, err := w.InitializeKeymanager(cliCtx.Context)
if err != nil {
return err
}

View File

@@ -19,7 +19,6 @@ import (
"github.com/prysmaticlabs/prysm/shared/testutil/assert"
"github.com/prysmaticlabs/prysm/shared/testutil/require"
"github.com/prysmaticlabs/prysm/shared/timeutils"
"github.com/prysmaticlabs/prysm/validator/accounts/iface"
"github.com/prysmaticlabs/prysm/validator/accounts/wallet"
"github.com/prysmaticlabs/prysm/validator/keymanager"
"github.com/prysmaticlabs/prysm/validator/keymanager/imported"
@@ -74,9 +73,7 @@ func TestImport_Noninteractive(t *testing.T) {
WalletPassword: password,
})
require.NoError(t, err)
km, err := w.InitializeKeymanager(cliCtx.Context, &iface.InitializeKeymanagerConfig{
SkipMnemonicConfirm: true,
})
km, err := w.InitializeKeymanager(cliCtx.Context)
require.NoError(t, err)
keys, err := km.FetchValidatingPublicKeys(cliCtx.Context)
require.NoError(t, err)
@@ -132,9 +129,7 @@ func TestImport_Noninteractive_RandomName(t *testing.T) {
WalletPassword: password,
})
require.NoError(t, err)
km, err := w.InitializeKeymanager(cliCtx.Context, &iface.InitializeKeymanagerConfig{
SkipMnemonicConfirm: true,
})
km, err := w.InitializeKeymanager(cliCtx.Context)
require.NoError(t, err)
keys, err := km.FetchValidatingPublicKeys(cliCtx.Context)
require.NoError(t, err)
@@ -186,9 +181,7 @@ func TestImport_Noninteractive_Filepath(t *testing.T) {
WalletPassword: password,
})
require.NoError(t, err)
km, err := w.InitializeKeymanager(cliCtx.Context, &iface.InitializeKeymanagerConfig{
SkipMnemonicConfirm: true,
})
km, err := w.InitializeKeymanager(cliCtx.Context)
require.NoError(t, err)
keys, err := km.FetchValidatingPublicKeys(cliCtx.Context)
require.NoError(t, err)

View File

@@ -9,7 +9,6 @@ import (
"github.com/logrusorgru/aurora"
"github.com/pkg/errors"
"github.com/prysmaticlabs/prysm/shared/petnames"
"github.com/prysmaticlabs/prysm/validator/accounts/iface"
"github.com/prysmaticlabs/prysm/validator/accounts/wallet"
"github.com/prysmaticlabs/prysm/validator/flags"
"github.com/prysmaticlabs/prysm/validator/keymanager"
@@ -27,9 +26,7 @@ func ListAccountsCli(cliCtx *cli.Context) error {
if err != nil {
return errors.Wrap(err, "could not open wallet")
}
km, err := w.InitializeKeymanager(cliCtx.Context, &iface.InitializeKeymanagerConfig{
SkipMnemonicConfirm: true,
})
km, err := w.InitializeKeymanager(cliCtx.Context)
if err != nil && strings.Contains(err.Error(), "invalid checksum") {
return errors.New("wrong wallet password entered")
}
@@ -145,22 +142,6 @@ func listDerivedKeymanagerAccounts(
return errors.Wrap(err, "could not fetch validating private keys")
}
}
withdrawalPublicKeys, err := keymanager.FetchWithdrawalPublicKeys(ctx)
if err != nil {
return errors.Wrap(err, "could not fetch validating public keys")
}
var withdrawalPrivateKeys [][32]byte
if showPrivateKeys {
withdrawalPrivateKeys, err = keymanager.FetchWithdrawalPrivateKeys(ctx)
if err != nil {
return errors.Wrap(err, "could not fetch withdrawal private keys")
}
}
nextAccountNumber := keymanager.NextAccountNumber()
currentAccountNumber := nextAccountNumber
if nextAccountNumber > 0 {
currentAccountNumber--
}
accountNames, err := keymanager.ValidatingAccountNames(ctx)
if err != nil {
return err
@@ -173,39 +154,18 @@ func listDerivedKeymanagerAccounts(
} else {
fmt.Printf("Showing %d validator accounts\n", len(accountNames))
}
for i := uint64(0); i <= currentAccountNumber; i++ {
for i := 0; i < len(accountNames); i++ {
fmt.Println("")
validatingKeyPath := fmt.Sprintf(derived.ValidatingKeyDerivationPathTemplate, i)
withdrawalKeyPath := fmt.Sprintf(derived.WithdrawalKeyDerivationPathTemplate, i)
// Retrieve the withdrawal key account metadata.
fmt.Printf("%s | %s\n", au.BrightBlue(fmt.Sprintf("Account %d", i)).Bold(), au.BrightGreen(accountNames[i]).Bold())
fmt.Printf("%s %#x\n", au.BrightMagenta("[withdrawal public key]").Bold(), withdrawalPublicKeys[i])
if showPrivateKeys {
fmt.Printf("%s %#x\n", au.BrightRed("[withdrawal private key]").Bold(), withdrawalPrivateKeys[i])
}
fmt.Printf("%s %s\n", au.BrightMagenta("[derivation path]").Bold(), withdrawalKeyPath)
// Retrieve the validating key account metadata.
fmt.Printf("%s %#x\n", au.BrightCyan("[validating public key]").Bold(), validatingPubKeys[i])
if showPrivateKeys {
if showPrivateKeys && validatingPrivateKeys != nil {
fmt.Printf("%s %#x\n", au.BrightRed("[validating private key]").Bold(), validatingPrivateKeys[i])
}
fmt.Printf("%s %s\n", au.BrightCyan("[derivation path]").Bold(), validatingKeyPath)
if !showDepositData {
continue
}
enc, err := keymanager.DepositDataForAccount(i)
if err != nil {
return errors.Wrapf(err, "could not deposit data for account: %s", accountNames[i])
}
fmt.Printf(`
======================Eth1 Deposit Transaction Data=====================
%#x
===================================================================`, enc)
fmt.Println(" ")
}
return nil

View File

@@ -232,22 +232,15 @@ func TestListAccounts_DerivedKeymanager(t *testing.T) {
keymanager, err := derived.NewKeymanager(
cliCtx.Context,
&derived.SetupConfig{
Opts: derived.DefaultKeymanagerOpts(),
Wallet: w,
SkipMnemonicConfirm: true,
Opts: derived.DefaultKeymanagerOpts(),
Wallet: w,
},
)
require.NoError(t, err)
numAccounts := 5
depositDataForAccounts := make([][]byte, numAccounts)
for i := 0; i < numAccounts; i++ {
_, _, err := keymanager.CreateAccount(cliCtx.Context)
require.NoError(t, err)
enc, err := keymanager.DepositDataForAccount(uint64(i))
require.NoError(t, err)
depositDataForAccounts[i] = enc
}
err = keymanager.RecoverAccountsFromMnemonic(cliCtx.Context, testMnemonic, "", numAccounts)
require.NoError(t, err)
rescueStdout := os.Stdout
r, writer, err := os.Pipe()
@@ -305,13 +298,11 @@ func TestListAccounts_DerivedKeymanager(t *testing.T) {
// Expected output format definition
const prologLength = 3
const accountLength = 14
const accountLength = 6
const epilogLength = 1
const nameOffset = 1
const keyOffset = 5
const validatingPrivateKeyOffset = 6
const withdrawalPrivateKeyOffset = 3
const depositOffset = 11
const keyOffset = 2
const validatingPrivateKeyOffset = 3
// Require the output has correct number of lines
lineCount := prologLength + accountLength*numAccounts + epilogLength
@@ -359,27 +350,6 @@ func TestListAccounts_DerivedKeymanager(t *testing.T) {
keyFound := strings.Contains(lines[lineNumber], keyString)
assert.Equal(t, true, keyFound, "Validating Private Key %s not found on line number %d", keyString, lineNumber)
}
// Get withdrawal private keys and require the correct count
withdrawalPrivKeys, err := keymanager.FetchWithdrawalPrivateKeys(cliCtx.Context)
require.NoError(t, err)
require.Equal(t, numAccounts, len(pubKeys))
// Assert that withdrawal private keys are printed on the correct lines
for i, key := range withdrawalPrivKeys {
lineNumber := prologLength + accountLength*i + withdrawalPrivateKeyOffset
keyString := fmt.Sprintf("%#x", key)
keyFound := strings.Contains(lines[lineNumber], keyString)
assert.Equal(t, true, keyFound, "Withdrawal Private Key %s not found on line number %d", keyString, lineNumber)
}
// Assert that deposit data are printed on the correct lines
for i, deposit := range depositDataForAccounts {
lineNumber := prologLength + accountLength*i + depositOffset
depositString := fmt.Sprintf("%#x", deposit)
depositFound := strings.Contains(lines[lineNumber], depositString)
assert.Equal(t, true, depositFound, "Deposit data %s not found on line number %d", depositString, lineNumber)
}
}
func TestListAccounts_RemoteKeymanager(t *testing.T) {

View File

@@ -16,35 +16,6 @@ var AccountCommands = &cli.Command{
Category: "accounts",
Usage: "defines commands for interacting with eth2 validator accounts (work in progress)",
Subcommands: []*cli.Command{
{
Name: "create",
Description: `creates a new validator account for eth2. If no wallet exists at the given wallet path, creates a new wallet for a user based on
specified input, capable of creating a imported, derived, or remote wallet.
this command outputs a deposit data string which is required to become a validator in eth2.`,
Flags: cmd.WrapFlags([]cli.Flag{
flags.Mnemonic25thWordFileFlag,
flags.SkipMnemonic25thWordCheckFlag,
flags.WalletDirFlag,
flags.WalletPasswordFileFlag,
flags.NumAccountsFlag,
featureconfig.ToledoTestnet,
featureconfig.PyrmontTestnet,
cmd.AcceptTosFlag,
}),
Before: func(cliCtx *cli.Context) error {
if err := cmd.LoadFlagsFromConfig(cliCtx, cliCtx.Command.Flags); err != nil {
return err
}
return tos.VerifyTosAcceptedOrPrompt(cliCtx)
},
Action: func(cliCtx *cli.Context) error {
featureconfig.ConfigureValidator(cliCtx)
if err := CreateAccountCli(cliCtx); err != nil {
log.Fatalf("Could not create new account: %v", err)
}
return nil
},
},
{
Name: "delete",
Description: `deletes the selected accounts from a users wallet.`,

View File

@@ -2,7 +2,6 @@ package iface
import (
"context"
"io"
"github.com/prysmaticlabs/prysm/validator/keymanager"
)
@@ -15,16 +14,9 @@ type Wallet interface {
AccountsDir() string
Password() string
// Read methods for important wallet and accounts-related files.
ReadEncryptedSeedFromDisk(ctx context.Context) (io.ReadCloser, error)
ReadFileAtPath(ctx context.Context, filePath string, fileName string) ([]byte, error)
// Write methods to persist important wallet and accounts-related files to disk.
WriteFileAtPath(ctx context.Context, pathName string, fileName string, data []byte) error
WriteEncryptedSeedToDisk(ctx context.Context, encoded []byte) error
// Method for initializing a new keymanager.
InitializeKeymanager(ctx context.Context, cfg *InitializeKeymanagerConfig) (keymanager.IKeymanager, error)
}
type InitializeKeymanagerConfig struct {
SkipMnemonicConfirm bool
Mnemonic25thWord string
InitializeKeymanager(ctx context.Context) (keymanager.IKeymanager, error)
}

View File

@@ -9,8 +9,5 @@ go_library(
"//validator:__pkg__",
"//validator:__subpackages__",
],
deps = [
"//validator/accounts/iface:go_default_library",
"//validator/keymanager:go_default_library",
],
deps = ["//validator/keymanager:go_default_library"],
)

View File

@@ -9,7 +9,6 @@ import (
"strings"
"sync"
"github.com/prysmaticlabs/prysm/validator/accounts/iface"
"github.com/prysmaticlabs/prysm/validator/keymanager"
)
@@ -90,6 +89,6 @@ func (m *Wallet) WriteEncryptedSeedToDisk(_ context.Context, encoded []byte) err
}
// InitializeKeymanager --
func (m *Wallet) InitializeKeymanager(_ context.Context, _ *iface.InitializeKeymanagerConfig) (keymanager.IKeymanager, error) {
func (m *Wallet) InitializeKeymanager(_ context.Context) (keymanager.IKeymanager, error) {
return nil, nil
}

View File

@@ -9,7 +9,6 @@ go_library(
deps = [
"//shared/fileutil:go_default_library",
"//shared/promptutil:go_default_library",
"//validator/accounts/iface:go_default_library",
"//validator/accounts/prompt:go_default_library",
"//validator/flags:go_default_library",
"//validator/keymanager:go_default_library",
@@ -33,7 +32,6 @@ go_test(
"//shared/testutil/assertions:go_default_library",
"//shared/testutil/require:go_default_library",
"//validator/accounts:go_default_library",
"//validator/accounts/iface:go_default_library",
"//validator/flags:go_default_library",
"//validator/keymanager:go_default_library",
"@com_github_sirupsen_logrus//:go_default_library",

View File

@@ -13,7 +13,6 @@ import (
"github.com/pkg/errors"
"github.com/prysmaticlabs/prysm/shared/fileutil"
"github.com/prysmaticlabs/prysm/shared/promptutil"
"github.com/prysmaticlabs/prysm/validator/accounts/iface"
"github.com/prysmaticlabs/prysm/validator/accounts/prompt"
"github.com/prysmaticlabs/prysm/validator/flags"
"github.com/prysmaticlabs/prysm/validator/keymanager"
@@ -56,7 +55,7 @@ var (
// KeymanagerKindSelections as friendly text.
KeymanagerKindSelections = map[keymanager.Kind]string{
keymanager.Imported: "Imported Wallet (Recommended)",
keymanager.Derived: "HD Wallet (Least secure)",
keymanager.Derived: "HD Wallet",
keymanager.Remote: "Remote Signing Wallet (Advanced)",
}
// ValidateExistingPass checks that an input cannot be empty.
@@ -258,10 +257,7 @@ func (w *Wallet) Password() string {
// InitializeKeymanager reads a keymanager config from disk at the wallet path,
// unmarshals it based on the wallet's keymanager kind, and returns its value.
func (w *Wallet) InitializeKeymanager(
ctx context.Context,
cfg *iface.InitializeKeymanagerConfig,
) (keymanager.IKeymanager, error) {
func (w *Wallet) InitializeKeymanager(ctx context.Context) (keymanager.IKeymanager, error) {
configFile, err := w.ReadKeymanagerConfigFromDisk(ctx)
if err != nil {
return nil, errors.Wrap(err, "could not read keymanager config")
@@ -286,10 +282,8 @@ func (w *Wallet) InitializeKeymanager(
return nil, errors.Wrap(err, "could not unmarshal keymanager config file")
}
km, err = derived.NewKeymanager(ctx, &derived.SetupConfig{
Opts: opts,
Wallet: w,
SkipMnemonicConfirm: cfg.SkipMnemonicConfirm,
Mnemonic25thWord: cfg.Mnemonic25thWord,
Opts: opts,
Wallet: w,
})
if err != nil {
return nil, errors.Wrap(err, "could not initialize derived keymanager")
@@ -429,28 +423,6 @@ func (w *Wallet) WriteKeymanagerConfigToDisk(_ context.Context, encoded []byte)
return nil
}
// ReadEncryptedSeedFromDisk reads the encrypted wallet seed configuration from
// within the wallet path.
func (w *Wallet) ReadEncryptedSeedFromDisk(_ context.Context) (io.ReadCloser, error) {
configFilePath := filepath.Join(w.accountsPath, derived.EncryptedSeedFileName)
if !fileutil.FileExists(configFilePath) {
return nil, fmt.Errorf("no encrypted seed file found at path: %s", w.accountsPath)
}
return os.Open(configFilePath)
}
// WriteEncryptedSeedToDisk writes the encrypted wallet seed configuration
// within the wallet path.
func (w *Wallet) WriteEncryptedSeedToDisk(_ context.Context, encoded []byte) error {
seedFilePath := filepath.Join(w.accountsPath, derived.EncryptedSeedFileName)
// Write the config file to disk.
if err := fileutil.WriteFile(seedFilePath, encoded); err != nil {
return errors.Wrapf(err, "could not write %s", seedFilePath)
}
log.WithField("seedFilePath", seedFilePath).Debug("Wrote wallet encrypted seed file to disk")
return nil
}
func readKeymanagerKindFromWalletPath(walletPath string) (keymanager.Kind, error) {
walletItem, err := os.Open(walletPath)
if err != nil {

View File

@@ -13,7 +13,6 @@ import (
"github.com/prysmaticlabs/prysm/shared/testutil/assertions"
"github.com/prysmaticlabs/prysm/shared/testutil/require"
"github.com/prysmaticlabs/prysm/validator/accounts"
"github.com/prysmaticlabs/prysm/validator/accounts/iface"
"github.com/prysmaticlabs/prysm/validator/accounts/wallet"
"github.com/prysmaticlabs/prysm/validator/flags"
"github.com/prysmaticlabs/prysm/validator/keymanager"
@@ -152,9 +151,7 @@ func Test_LockUnlockFile(t *testing.T) {
})
require.NoError(t, err)
defer unlock(t, w)
_, err = w.InitializeKeymanager(cliCtx.Context, &iface.InitializeKeymanagerConfig{
SkipMnemonicConfirm: true,
})
_, err = w.InitializeKeymanager(cliCtx.Context)
require.NoError(t, err)
assert.NoError(t, err)
err = w.LockWalletConfigFile(cliCtx.Context)

View File

@@ -9,7 +9,6 @@ import (
"github.com/manifoldco/promptui"
"github.com/pkg/errors"
"github.com/prysmaticlabs/prysm/shared/promptutil"
"github.com/prysmaticlabs/prysm/validator/accounts/iface"
"github.com/prysmaticlabs/prysm/validator/accounts/prompt"
"github.com/prysmaticlabs/prysm/validator/accounts/wallet"
"github.com/prysmaticlabs/prysm/validator/flags"
@@ -26,6 +25,7 @@ type CreateWalletConfig struct {
RemoteKeymanagerOpts *remote.KeymanagerOpts
SkipMnemonicConfirm bool
Mnemonic25thWord string
NumAccounts int
}
// CreateAndSaveWalletCli from user input with a desired keymanager. If a
@@ -69,23 +69,27 @@ func CreateWalletWithKeymanager(ctx context.Context, cfg *CreateWalletConfig) (*
switch w.KeymanagerKind() {
case keymanager.Imported:
if err = createImportedKeymanagerWallet(ctx, w); err != nil {
return nil, errors.Wrap(err, "could not initialize wallet with imported keymanager")
return nil, errors.Wrap(err, "could not initialize wallet")
}
log.WithField("--wallet-dir", cfg.WalletCfg.WalletDir).Info(
"Successfully created wallet with on-disk keymanager configuration. " +
"Make a new validator account with ./prysm.sh validator accounts create",
"Successfully created wallet with ability to import keystores",
)
case keymanager.Derived:
if err = createDerivedKeymanagerWallet(ctx, w, cfg.SkipMnemonicConfirm, cfg.Mnemonic25thWord); err != nil {
return nil, errors.Wrap(err, "could not initialize wallet with derived keymanager")
if err = createDerivedKeymanagerWallet(
ctx,
w,
cfg.Mnemonic25thWord,
cfg.SkipMnemonicConfirm,
cfg.NumAccounts,
); err != nil {
return nil, errors.Wrap(err, "could not initialize wallet")
}
log.WithField("--wallet-dir", cfg.WalletCfg.WalletDir).Info(
"Successfully created HD wallet and saved configuration to disk. " +
"Make a new validator account with ./prysm.sh validator accounts create",
"Successfully created HD wallet from mnemonic and regenerated accounts",
)
case keymanager.Remote:
if err = createRemoteKeymanagerWallet(ctx, w, cfg.RemoteKeymanagerOpts); err != nil {
return nil, errors.Wrap(err, "could not initialize wallet with remote keymanager")
return nil, errors.Wrap(err, "could not initialize wallet")
}
log.WithField("--wallet-dir", cfg.WalletCfg.WalletDir).Info(
"Successfully created wallet with remote keymanager configuration",
@@ -126,6 +130,13 @@ func extractWalletCreationConfigFromCli(cliCtx *cli.Context, keymanagerKind keym
}
skipMnemonic25thWord := cliCtx.IsSet(flags.SkipMnemonic25thWordCheckFlag.Name)
has25thWordFile := cliCtx.IsSet(flags.Mnemonic25thWordFileFlag.Name)
if keymanagerKind == keymanager.Derived {
numAccounts, err := inputNumAccounts(cliCtx)
if err != nil {
return nil, errors.Wrap(err, "could not get number of accounts to generate")
}
createWalletConfig.NumAccounts = int(numAccounts)
}
if keymanagerKind == keymanager.Derived && !skipMnemonic25thWord && !has25thWordFile {
resp, err := promptutil.ValidatePrompt(
os.Stdin, newMnemonicPassphraseYesNoText, promptutil.ValidateYesOrNo,
@@ -184,25 +195,37 @@ func createImportedKeymanagerWallet(ctx context.Context, wallet *wallet.Wallet)
func createDerivedKeymanagerWallet(
ctx context.Context,
wallet *wallet.Wallet,
skipMnemonicConfirm bool,
mnemonicPassphrase string,
skipMnemonicConfirm bool,
numAccounts int,
) error {
keymanagerConfig, err := derived.MarshalOptionsFile(ctx, derived.DefaultKeymanagerOpts())
if err != nil {
return errors.Wrap(err, "could not marshal keymanager config file")
if wallet == nil {
return errors.New("nil wallet")
}
if err := wallet.SaveWallet(); err != nil {
return errors.Wrap(err, "could not save wallet to disk")
}
opts := derived.DefaultKeymanagerOpts()
keymanagerConfig, err := derived.MarshalOptionsFile(ctx, opts)
if err != nil {
return errors.Wrap(err, "could not marshal keymanager config file")
}
if err := wallet.WriteKeymanagerConfigToDisk(ctx, keymanagerConfig); err != nil {
return errors.Wrap(err, "could not write keymanager config to disk")
}
_, err = wallet.InitializeKeymanager(ctx, &iface.InitializeKeymanagerConfig{
SkipMnemonicConfirm: skipMnemonicConfirm,
Mnemonic25thWord: mnemonicPassphrase,
km, err := derived.NewKeymanager(ctx, &derived.SetupConfig{
Opts: opts,
Wallet: wallet,
})
if err != nil {
return errors.Wrap(err, "could not initialize keymanager")
return errors.Wrap(err, "could not initialize HD keymanager")
}
mnemonic, err := derived.GenerateAndConfirmMnemonic(skipMnemonicConfirm)
if err != nil {
return errors.Wrap(err, "could not confirm mnemonic")
}
if err := km.RecoverAccountsFromMnemonic(ctx, mnemonic, mnemonicPassphrase, numAccounts); err != nil {
return errors.Wrap(err, "could not recover accounts from mnemonic")
}
return nil
}

View File

@@ -2,7 +2,6 @@ package accounts
import (
"context"
"encoding/json"
"flag"
"io/ioutil"
"os"
@@ -23,7 +22,6 @@ import (
"github.com/sirupsen/logrus"
logTest "github.com/sirupsen/logrus/hooks/test"
"github.com/urfave/cli/v2"
keystorev4 "github.com/wealdtech/go-eth2-wallet-encryptor-keystorev4"
)
const (
@@ -186,6 +184,7 @@ func TestCreateWallet_Derived(t *testing.T) {
passwordsDir: passwordsDir,
walletPasswordFile: passwordFile,
keymanagerKind: keymanager.Derived,
numAccounts: 1,
})
// We attempt to create the wallet.
@@ -217,6 +216,7 @@ func TestCreateWallet_WalletAlreadyExists(t *testing.T) {
passwordsDir: passwordsDir,
walletPasswordFile: passwordFile,
keymanagerKind: keymanager.Derived,
numAccounts: 1,
})
// We attempt to create the wallet.
@@ -239,48 +239,6 @@ func TestCreateWallet_WalletAlreadyExists(t *testing.T) {
require.ErrorContains(t, "already exists", err)
}
// TestCorrectPassphrase_Derived makes sure the wallet created uses the provided passphrase
func TestCorrectPassphrase_Derived(t *testing.T) {
walletDir, _, passwordFile := setupWalletAndPasswordsDir(t)
//Specify the password locally to this file for convenience.
password := "Pa$sW0rD0__Fo0xPr"
require.NoError(t, ioutil.WriteFile(passwordFile, []byte(password), os.ModePerm))
cliCtx := setupWalletCtx(t, &testWalletConfig{
walletDir: walletDir,
walletPasswordFile: passwordFile,
keymanagerKind: keymanager.Derived,
skipDepositConfirm: true,
})
// We attempt to create the wallet.
_, err := CreateAndSaveWalletCli(cliCtx)
require.Equal(t, nil, err, "error in CreateAndSaveWalletCli()")
w := wallet.New(&wallet.Config{
WalletDir: walletDir,
KeymanagerKind: keymanager.Derived,
})
seedConfigFile, err := w.ReadEncryptedSeedFromDisk(cliCtx.Context)
require.Equal(t, nil, err, "could not read encrypted seed file from disk")
defer func() {
err := seedConfigFile.Close()
require.Equal(t, nil, err, "Could not close encrypted seed file")
}()
encodedSeedFile, err := ioutil.ReadAll(seedConfigFile)
require.Equal(t, nil, err, "could not read seed configuration file contents")
seedConfig := &derived.SeedConfig{}
err = json.Unmarshal(encodedSeedFile, seedConfig)
require.Equal(t, nil, err, "could not unmarshal seed configuration")
decryptor := keystorev4.New()
_, err = decryptor.Decrypt(seedConfig.Crypto, password)
require.Equal(t, nil, err, "could not decrypt seed configuration with password")
}
func TestCreateWallet_Remote(t *testing.T) {
walletDir, _, walletPasswordFile := setupWalletAndPasswordsDir(t)
wantCfg := &remote.KeymanagerOpts{

View File

@@ -10,7 +10,6 @@ import (
"strings"
"github.com/pkg/errors"
ethpb "github.com/prysmaticlabs/ethereumapis/eth/v1alpha1"
"github.com/prysmaticlabs/prysm/shared/promptutil"
"github.com/prysmaticlabs/prysm/validator/accounts/prompt"
"github.com/prysmaticlabs/prysm/validator/accounts/wallet"
@@ -36,7 +35,7 @@ type RecoverWalletConfig struct {
WalletDir string
WalletPassword string
Mnemonic string
NumAccounts int64
NumAccounts int
Mnemonic25thWord string
}
@@ -100,27 +99,25 @@ func RecoverWalletCli(cliCtx *cli.Context) error {
}
config.WalletDir = walletDir
config.WalletPassword = walletPassword
config.NumAccounts = numAccounts
_, _, err = RecoverWallet(cliCtx.Context, config)
if err != nil {
config.NumAccounts = int(numAccounts)
if _, err = RecoverWallet(cliCtx.Context, config); err != nil {
return err
}
log.Infof(
"Successfully recovered HD wallet and saved configuration to disk. " +
"Make a new validator account with ./prysm.sh validator accounts create",
"Successfully recovered HD wallet with accounts and saved configuration to disk",
)
return nil
}
// RecoverWallet uses a menmonic seed phrase to recover a wallet into the path provided.
func RecoverWallet(ctx context.Context, cfg *RecoverWalletConfig) (*wallet.Wallet, []*ethpb.Deposit_Data, error) {
func RecoverWallet(ctx context.Context, cfg *RecoverWalletConfig) (*wallet.Wallet, error) {
// Ensure that the wallet directory does not contain a wallet already
dirExists, err := wallet.Exists(cfg.WalletDir)
if err != nil {
return nil, nil, err
return nil, err
}
if dirExists {
return nil, nil, errors.New("a wallet already exists at this location. Please input an" +
return nil, errors.New("a wallet already exists at this location. Please input an" +
" alternative location for the new wallet or remove the current wallet")
}
w := wallet.New(&wallet.Config{
@@ -130,47 +127,29 @@ func RecoverWallet(ctx context.Context, cfg *RecoverWalletConfig) (*wallet.Walle
})
keymanagerConfig, err := derived.MarshalOptionsFile(ctx, derived.DefaultKeymanagerOpts())
if err != nil {
return nil, nil, errors.Wrap(err, "could not marshal keymanager config file")
return nil, errors.Wrap(err, "could not marshal keymanager config file")
}
if err := w.SaveWallet(); err != nil {
return nil, nil, errors.Wrap(err, "could not save wallet to disk")
return nil, errors.Wrap(err, "could not save wallet to disk")
}
if err := w.WriteKeymanagerConfigToDisk(ctx, keymanagerConfig); err != nil {
return nil, nil, errors.Wrap(err, "could not write keymanager config to disk")
return nil, errors.Wrap(err, "could not write keymanager config to disk")
}
km, err := derived.KeymanagerForPhrase(ctx, &derived.SetupConfig{
Opts: derived.DefaultKeymanagerOpts(),
Wallet: w,
Mnemonic: cfg.Mnemonic,
Mnemonic25thWord: cfg.Mnemonic25thWord,
km, err := derived.NewKeymanager(ctx, &derived.SetupConfig{
Opts: derived.DefaultKeymanagerOpts(),
Wallet: w,
})
if err != nil {
return nil, nil, errors.Wrap(err, "could not make keymanager for given phrase")
return nil, errors.Wrap(err, "could not make keymanager for given phrase")
}
if err := km.WriteEncryptedSeedToWallet(ctx, cfg.Mnemonic, ""); err != nil {
return nil, nil, err
}
depositDataList := make([]*ethpb.Deposit_Data, cfg.NumAccounts)
if cfg.NumAccounts == 1 {
_, depositData, err := km.CreateAccount(ctx)
if err != nil {
return nil, nil, errors.Wrap(err, "could not create account in wallet")
}
depositDataList[0] = depositData
return w, nil, nil
}
for i := int64(0); i < cfg.NumAccounts; i++ {
_, depositData, err := km.CreateAccount(ctx)
if err != nil {
return nil, nil, errors.Wrap(err, "could not create account in wallet")
}
depositDataList[i] = depositData
if err := km.RecoverAccountsFromMnemonic(ctx, cfg.Mnemonic, cfg.Mnemonic25thWord, cfg.NumAccounts); err != nil {
return nil, err
}
log.WithField("wallet-path", w.AccountsDir()).Infof(
"Successfully recovered HD wallet with %d accounts. Please use accounts list to view details for your accounts",
cfg.NumAccounts,
)
return w, depositDataList, nil
return w, nil
}
func inputMnemonic(cliCtx *cli.Context) (string, error) {
@@ -228,9 +207,12 @@ func inputMnemonic(cliCtx *cli.Context) (string, error) {
func inputNumAccounts(cliCtx *cli.Context) (int64, error) {
if cliCtx.IsSet(flags.NumAccountsFlag.Name) {
numAccounts := cliCtx.Int64(flags.NumAccountsFlag.Name)
if numAccounts <= 0 {
return 0, errors.New("must recover at least 1 account")
}
return numAccounts, nil
}
numAccounts, err := promptutil.DefaultAndValidatePrompt("Enter how many accounts you would like to recover", "0", promptutil.ValidateNumber)
numAccounts, err := promptutil.ValidatePrompt(os.Stdin, "Enter how many accounts you would like to recover", promptutil.ValidateNumber)
if err != nil {
return 0, err
}
@@ -238,6 +220,9 @@ func inputNumAccounts(cliCtx *cli.Context) (int64, error) {
if err != nil {
return 0, err
}
if numAccountsInt <= 0 {
return 0, errors.New("must recover at least 1 account")
}
return int64(numAccountsInt), nil
}

View File

@@ -11,7 +11,6 @@ import (
"github.com/prysmaticlabs/prysm/shared/testutil/assert"
"github.com/prysmaticlabs/prysm/shared/testutil/require"
"github.com/prysmaticlabs/prysm/validator/accounts/iface"
"github.com/prysmaticlabs/prysm/validator/accounts/wallet"
"github.com/prysmaticlabs/prysm/validator/flags"
"github.com/prysmaticlabs/prysm/validator/keymanager"
@@ -80,9 +79,7 @@ func TestRecoverDerivedWallet(t *testing.T) {
wantCfg := derived.DefaultKeymanagerOpts()
assert.DeepEqual(t, wantCfg, walletCfg)
keymanager, err := w.InitializeKeymanager(cliCtx.Context, &iface.InitializeKeymanagerConfig{
SkipMnemonicConfirm: true,
})
keymanager, err := w.InitializeKeymanager(cliCtx.Context)
require.NoError(t, err)
km, ok := keymanager.(*derived.Keymanager)
if !ok {

View File

@@ -32,7 +32,6 @@ go_library(
"//shared/params:go_default_library",
"//shared/slotutil:go_default_library",
"//shared/timeutils:go_default_library",
"//validator/accounts/iface:go_default_library",
"//validator/accounts/wallet:go_default_library",
"//validator/db:go_default_library",
"//validator/db/kv:go_default_library",

View File

@@ -19,7 +19,6 @@ import (
"github.com/prysmaticlabs/prysm/shared/event"
"github.com/prysmaticlabs/prysm/shared/grpcutils"
"github.com/prysmaticlabs/prysm/shared/params"
"github.com/prysmaticlabs/prysm/validator/accounts/iface"
"github.com/prysmaticlabs/prysm/validator/accounts/wallet"
"github.com/prysmaticlabs/prysm/validator/db"
"github.com/prysmaticlabs/prysm/validator/keymanager"
@@ -210,11 +209,7 @@ func (v *ValidatorService) recheckKeys(ctx context.Context) {
cleanup := sub.Unsubscribe
defer cleanup()
w := <-initializedChan
keyManager, err := w.InitializeKeymanager(
ctx, &iface.InitializeKeymanagerConfig{
SkipMnemonicConfirm: true,
},
)
keyManager, err := w.InitializeKeymanager(ctx)
if err != nil {
// log.Fatalf will prevent defer from being called
cleanup()

View File

@@ -26,7 +26,6 @@ import (
"github.com/prysmaticlabs/prysm/shared/hashutil"
"github.com/prysmaticlabs/prysm/shared/params"
"github.com/prysmaticlabs/prysm/shared/slotutil"
"github.com/prysmaticlabs/prysm/validator/accounts/iface"
"github.com/prysmaticlabs/prysm/validator/accounts/wallet"
vdb "github.com/prysmaticlabs/prysm/validator/db"
"github.com/prysmaticlabs/prysm/validator/db/kv"
@@ -100,11 +99,7 @@ func (v *validator) WaitForWalletInitialization(ctx context.Context) error {
for {
select {
case w := <-walletChan:
keyManager, err := w.InitializeKeymanager(
ctx, &iface.InitializeKeymanagerConfig{
SkipMnemonicConfirm: true,
},
)
keyManager, err := w.InitializeKeymanager(ctx)
if err != nil {
return errors.Wrap(err, "could not read keymanager")
}

View File

@@ -4,43 +4,29 @@ load("@prysm//tools/go:def.bzl", "go_library")
go_library(
name = "go_default_library",
srcs = [
"backup.go",
"keymanager.go",
"mnemonic.go",
],
importpath = "github.com/prysmaticlabs/prysm/validator/keymanager/derived",
visibility = [
"//validator:__pkg__",
"//validator:__subpackages__",
],
visibility = ["//validator:__subpackages__"],
deps = [
"//beacon-chain/core/helpers:go_default_library",
"//proto/validator/accounts/v2:go_default_library",
"//shared/bls:go_default_library",
"//shared/bytesutil:go_default_library",
"//shared/depositutil:go_default_library",
"//shared/fileutil:go_default_library",
"//shared/params:go_default_library",
"//shared/petnames:go_default_library",
"//shared/promptutil:go_default_library",
"//shared/rand:go_default_library",
"//validator/accounts/iface:go_default_library",
"//validator/keymanager:go_default_library",
"@com_github_google_uuid//:go_default_library",
"//validator/keymanager/imported:go_default_library",
"@com_github_pkg_errors//:go_default_library",
"@com_github_prysmaticlabs_ethereumapis//eth/v1alpha1:go_default_library",
"@com_github_sirupsen_logrus//:go_default_library",
"@com_github_tyler_smith_go_bip39//:go_default_library",
"@com_github_wealdtech_go_eth2_types_v2//:go_default_library",
"@com_github_wealdtech_go_eth2_util//:go_default_library",
"@com_github_wealdtech_go_eth2_wallet_encryptor_keystorev4//:go_default_library",
],
)
go_test(
name = "go_default_test",
srcs = [
"backup_test.go",
"eip_test.go",
"keymanager_test.go",
"mnemonic_test.go",
@@ -49,15 +35,11 @@ go_test(
deps = [
"//proto/validator/accounts/v2:go_default_library",
"//shared/bls:go_default_library",
"//shared/bytesutil:go_default_library",
"//shared/rand:go_default_library",
"//shared/testutil/assert:go_default_library",
"//shared/testutil/require:go_default_library",
"//validator/accounts/testing:go_default_library",
"@com_github_google_uuid//:go_default_library",
"@com_github_sirupsen_logrus//hooks/test:go_default_library",
"@com_github_tyler_smith_go_bip39//:go_default_library",
"@com_github_wealdtech_go_eth2_util//:go_default_library",
"@com_github_wealdtech_go_eth2_wallet_encryptor_keystorev4//:go_default_library",
],
)

View File

@@ -1,55 +0,0 @@
package derived
import (
"context"
"fmt"
"github.com/google/uuid"
"github.com/pkg/errors"
"github.com/prysmaticlabs/prysm/shared/bls"
"github.com/prysmaticlabs/prysm/shared/bytesutil"
"github.com/prysmaticlabs/prysm/validator/keymanager"
keystorev4 "github.com/wealdtech/go-eth2-wallet-encryptor-keystorev4"
)
// ExtractKeystores retrieves the secret keys for specified public keys
// in the function input, encrypts them using the specified password,
// and returns their respective EIP-2335 keystores.
func (dr *Keymanager) ExtractKeystores(
_ context.Context, publicKeys []bls.PublicKey, password string,
) ([]*keymanager.Keystore, error) {
encryptor := keystorev4.New()
keystores := make([]*keymanager.Keystore, len(publicKeys))
lock.RLock()
defer lock.RUnlock()
for i, pk := range publicKeys {
pubKeyBytes := pk.Marshal()
secretKey, ok := secretKeysCache[bytesutil.ToBytes48(pubKeyBytes)]
if !ok {
return nil, fmt.Errorf(
"secret key for public key %#x not found in cache",
pubKeyBytes,
)
}
cryptoFields, err := encryptor.Encrypt(secretKey.Marshal(), password)
if err != nil {
return nil, errors.Wrapf(
err,
"could not encrypt secret key for public key %#x",
pubKeyBytes,
)
}
id, err := uuid.NewRandom()
if err != nil {
return nil, err
}
keystores[i] = &keymanager.Keystore{
Crypto: cryptoFields,
ID: id.String(),
Pubkey: fmt.Sprintf("%x", pubKeyBytes),
Version: encryptor.Version(),
Name: encryptor.Name(),
}
}
return keystores, nil
}

View File

@@ -1,56 +0,0 @@
package derived
import (
"context"
"encoding/hex"
"testing"
"github.com/prysmaticlabs/prysm/shared/bls"
"github.com/prysmaticlabs/prysm/shared/bytesutil"
"github.com/prysmaticlabs/prysm/shared/testutil/assert"
"github.com/prysmaticlabs/prysm/shared/testutil/require"
)
func TestDerivedKeymanager_ExtractKeystores(t *testing.T) {
secretKeysCache = make(map[[48]byte]bls.SecretKey)
dr := &Keymanager{}
validatingKeys := make([]bls.SecretKey, 10)
lock.Lock()
for i := 0; i < len(validatingKeys); i++ {
secretKey, err := bls.RandKey()
require.NoError(t, err)
validatingKeys[i] = secretKey
secretKeysCache[bytesutil.ToBytes48(secretKey.PublicKey().Marshal())] = secretKey
}
lock.Unlock()
ctx := context.Background()
password := "password"
// Extracting 0 public keys should return 0 keystores.
keystores, err := dr.ExtractKeystores(ctx, nil, password)
require.NoError(t, err)
assert.Equal(t, 0, len(keystores))
// We attempt to extract a few indices.
keystores, err = dr.ExtractKeystores(
ctx,
[]bls.PublicKey{
validatingKeys[3].PublicKey(),
validatingKeys[5].PublicKey(),
validatingKeys[7].PublicKey(),
},
password,
)
require.NoError(t, err)
receivedPubKeys := make([][]byte, len(keystores))
for i, k := range keystores {
pubKeyBytes, err := hex.DecodeString(k.Pubkey)
require.NoError(t, err)
receivedPubKeys[i] = pubKeyBytes
}
assert.DeepEqual(t, receivedPubKeys, [][]byte{
validatingKeys[3].PublicKey().Marshal(),
validatingKeys[5].PublicKey().Marshal(),
validatingKeys[7].PublicKey().Marshal(),
})
}

View File

@@ -1,7 +1,6 @@
package derived
import (
"context"
"encoding/hex"
"fmt"
"testing"
@@ -9,38 +8,26 @@ import (
"github.com/prysmaticlabs/prysm/shared/bls"
"github.com/prysmaticlabs/prysm/shared/testutil/assert"
"github.com/prysmaticlabs/prysm/shared/testutil/require"
mock "github.com/prysmaticlabs/prysm/validator/accounts/testing"
util "github.com/wealdtech/go-eth2-util"
)
func TestDerivationFromMnemonic(t *testing.T) {
secretKeysCache = make(map[[48]byte]bls.SecretKey)
mnemonic := "abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about"
passphrase := "TREZOR"
seed := "c55257c360c07c72029aebc1b53c05ed0362ada38ead3e3e9efa3708e53495531f09a6987599d18264c1e1c92f2cf141630c7a3c4ab7c81b2f001698e7463b04"
masterSK := "6083874454709270928345386274498605044986640685124978867557563392430687146096"
childIndex := 0
childSK := "20397789859736650942317412262472558107875392172444076792671091975210932703118"
ctx := context.Background()
wallet := &mock.Wallet{
Files: make(map[string]map[string][]byte),
AccountPasswords: make(map[string]string),
WalletPassword: "secretPassw0rd$1999",
}
km, err := KeymanagerForPhrase(ctx, &SetupConfig{
Opts: DefaultKeymanagerOpts(),
Wallet: wallet,
Mnemonic: mnemonic,
Mnemonic25thWord: passphrase,
})
require.NoError(t, err)
seedBytes, err := hex.DecodeString(seed)
require.NoError(t, err)
assert.DeepEqual(t, seedBytes, km.seed)
derivedSeed, err := seedFromMnemonic(mnemonic, passphrase)
require.NoError(t, err)
assert.DeepEqual(t, seedBytes, derivedSeed)
// We derive keys, then check the master SK and the child SK.
withdrawalKey, err := km.deriveKey("m")
withdrawalKey, err := util.PrivateKeyFromSeedAndPath(seedBytes, "m")
require.NoError(t, err)
validatingKey, err := km.deriveKey(fmt.Sprintf("m/%d", childIndex))
validatingKey, err := util.PrivateKeyFromSeedAndPath(seedBytes, fmt.Sprintf("m/%d", childIndex))
require.NoError(t, err)
expectedMasterSK, err := bls.SecretKeyFromBigNum(masterSK)
@@ -103,14 +90,11 @@ func TestDerivationFromSeed(t *testing.T) {
t.Run(tt.name, func(t *testing.T) {
seedBytes, err := hex.DecodeString(tt.fields.seed)
require.NoError(t, err)
km := &Keymanager{
seed: seedBytes,
opts: DefaultKeymanagerOpts(),
}
// We derive keys, then check the master SK and the child SK.
masterSK, err := km.deriveKey("m")
masterSK, err := util.PrivateKeyFromSeedAndPath(seedBytes, "m")
require.NoError(t, err)
childSK, err := km.deriveKey(fmt.Sprintf("m/%d", tt.fields.childIndex))
childSK, err := util.PrivateKeyFromSeedAndPath(seedBytes, fmt.Sprintf("m/%d", tt.fields.childIndex))
require.NoError(t, err)
expectedMasterSK, err := bls.SecretKeyFromBigNum(tt.want.masterSK)

View File

@@ -6,61 +6,30 @@ import (
"fmt"
"io"
"io/ioutil"
"path"
"path/filepath"
"sync"
"github.com/google/uuid"
"github.com/pkg/errors"
pb "github.com/prysmaticlabs/ethereumapis/eth/v1alpha1"
"github.com/prysmaticlabs/prysm/beacon-chain/core/helpers"
validatorpb "github.com/prysmaticlabs/prysm/proto/validator/accounts/v2"
"github.com/prysmaticlabs/prysm/shared/bls"
"github.com/prysmaticlabs/prysm/shared/bytesutil"
"github.com/prysmaticlabs/prysm/shared/depositutil"
"github.com/prysmaticlabs/prysm/shared/fileutil"
"github.com/prysmaticlabs/prysm/shared/params"
"github.com/prysmaticlabs/prysm/shared/petnames"
"github.com/prysmaticlabs/prysm/shared/rand"
"github.com/prysmaticlabs/prysm/validator/accounts/iface"
"github.com/prysmaticlabs/prysm/validator/keymanager"
"github.com/prysmaticlabs/prysm/validator/keymanager/imported"
"github.com/sirupsen/logrus"
"github.com/tyler-smith/go-bip39"
types "github.com/wealdtech/go-eth2-types/v2"
util "github.com/wealdtech/go-eth2-util"
keystorev4 "github.com/wealdtech/go-eth2-wallet-encryptor-keystorev4"
)
var (
log = logrus.WithField("prefix", "derived-keymanager")
lock sync.RWMutex
orderedPublicKeys = make([][48]byte, 0)
secretKeysCache = make(map[[48]byte]bls.SecretKey)
log = logrus.WithField("prefix", "derived-keymanager")
)
const (
// EIPVersion used by this derived keymanager implementation.
EIPVersion = "EIP-2334"
// WithdrawalKeyDerivationPathTemplate defining the hierarchical path for withdrawal
// keys for Prysm eth2 validators. According to EIP-2334, the format is as follows:
// m / purpose / coin_type / account_index / withdrawal_key
WithdrawalKeyDerivationPathTemplate = "m/12381/3600/%d/0"
// ValidatingKeyDerivationPathTemplate defining the hierarchical path for validating
// keys for Prysm eth2 validators. According to EIP-2334, the format is as follows:
// m / purpose / coin_type / account_index / withdrawal_key / validating_key
ValidatingKeyDerivationPathTemplate = "m/12381/3600/%d/0/0"
// EncryptedSeedFileName for persisting a wallet's seed when using a derived keymanager.
EncryptedSeedFileName = "seed.encrypted.json"
)
// SeedConfig json file representation as a Go struct.
type SeedConfig struct {
Crypto map[string]interface{} `json:"crypto"`
ID string `json:"uuid"`
NextAccount uint64 `json:"next_account"`
Version uint `json:"version"`
Name string `json:"name"`
}
// KeymanagerOpts defines options for the keymanager that
// are stored to disk in the wallet.
type KeymanagerOpts struct {
@@ -72,28 +41,14 @@ type KeymanagerOpts struct {
// SetupConfig includes configuration values for initializing
// a keymanager, such as passwords, the wallet, and more.
type SetupConfig struct {
Opts *KeymanagerOpts
Wallet iface.Wallet
SkipMnemonicConfirm bool
Mnemonic string
Mnemonic25thWord string // A '25th' word in the mnemonic, which is a user-defined passphrase.
Opts *KeymanagerOpts
Wallet iface.Wallet
}
// Keymanager implementation for derived, HD keymanager using EIP-2333 and EIP-2334.
type Keymanager struct {
wallet iface.Wallet
opts *KeymanagerOpts
mnemonicGenerator SeedPhraseFactory
seedCfg *SeedConfig
seed []byte
}
// ResetCaches for the keymanager.
func ResetCaches() {
lock.Lock()
orderedPublicKeys = make([][48]byte, 0)
secretKeysCache = make(map[[48]byte]bls.SecretKey)
lock.Unlock()
importedKM *imported.Keymanager
opts *KeymanagerOpts
}
// DefaultKeymanagerOpts for a derived keymanager implementation.
@@ -110,84 +65,17 @@ func NewKeymanager(
ctx context.Context,
cfg *SetupConfig,
) (*Keymanager, error) {
// Check if the wallet seed file exists. If it does not, we initialize one
// by creating a new mnemonic and writing the encrypted file to disk.
encodedSeedFile, err := checkEncodedKeyFile(ctx, cfg.Wallet, cfg.SkipMnemonicConfirm, cfg.Mnemonic25thWord)
importedKM, err := imported.NewKeymanager(ctx, &imported.SetupConfig{
Wallet: cfg.Wallet,
Opts: imported.DefaultKeymanagerOpts(),
})
if err != nil {
return nil, err
}
seedConfig := &SeedConfig{}
if err := json.Unmarshal(encodedSeedFile, seedConfig); err != nil {
return nil, errors.Wrap(err, "could not unmarshal seed configuration")
}
decryptor := keystorev4.New()
seed, err := decryptor.Decrypt(seedConfig.Crypto, cfg.Wallet.Password())
if err != nil {
return nil, errors.Wrap(err, "could not decrypt seed configuration with password")
}
k := &Keymanager{
wallet: cfg.Wallet,
opts: cfg.Opts,
mnemonicGenerator: &EnglishMnemonicGenerator{
skipMnemonicConfirm: cfg.SkipMnemonicConfirm,
},
seedCfg: seedConfig,
seed: seed,
}
// Initialize public and secret key caches that are used to speed up the functions
// FetchValidatingPublicKeys and Sign
err = k.initializeKeysCachesFromSeed()
if err != nil {
return nil, errors.Wrap(err, "failed to initialize keys caches from seed")
}
if cfg.Opts.DerivedVersion != "2" {
if err := k.rewriteSeedConfig(ctx); err != nil {
return nil, err
}
}
return k, nil
}
// KeymanagerForPhrase instantiates a new derived keymanager from configuration and an existing mnemonic phrase provided.
func KeymanagerForPhrase(
ctx context.Context,
cfg *SetupConfig,
) (*Keymanager, error) {
// Check if the wallet seed file exists. If it does not, we initialize one
// by creating a new mnemonic and writing the encrypted file to disk.
var encodedSeedFile []byte
seedConfig, err := seedFileFromMnemonic(cfg.Mnemonic, cfg.Wallet.Password(), cfg.Mnemonic25thWord)
if err != nil {
return nil, errors.Wrap(err, "could not initialize new wallet seed file")
}
encodedSeedFile, err = marshalEncryptedSeedFile(seedConfig)
if err != nil {
return nil, errors.Wrap(err, "could not marshal encrypted wallet seed file")
}
if err = cfg.Wallet.WriteEncryptedSeedToDisk(ctx, encodedSeedFile); err != nil {
return nil, errors.Wrap(err, "could not write encrypted wallet seed config to disk")
}
decryptor := keystorev4.New()
seed, err := decryptor.Decrypt(seedConfig.Crypto, cfg.Wallet.Password())
if err != nil {
return nil, errors.Wrap(err, "could not decrypt seed configuration with password")
}
k := &Keymanager{
wallet: cfg.Wallet,
opts: cfg.Opts,
mnemonicGenerator: &EnglishMnemonicGenerator{
skipMnemonicConfirm: true,
},
seedCfg: seedConfig,
seed: seed,
}
// Initialize public and secret key caches that are used to speed up the functions
// FetchValidatingPublicKeys and Sign
err = k.initializeKeysCachesFromSeed()
if err != nil {
return nil, errors.Wrap(err, "failed to initialize keys caches from seed")
}
return k, nil
return &Keymanager{
importedKM: importedKM,
opts: cfg.Opts,
}, nil
}
// UnmarshalOptionsFile attempts to JSON unmarshal a derived keymanager
@@ -219,385 +107,66 @@ func (dr *Keymanager) KeymanagerOpts() *KeymanagerOpts {
return dr.opts
}
// NextAccountNumber managed by the derived keymanager.
func (dr *Keymanager) NextAccountNumber() uint64 {
return dr.seedCfg.NextAccount
}
// WriteEncryptedSeedToWallet given a mnemonic phrase, is able to regenerate a wallet seed
// encrypt it, and write it to the wallet's path.
func (dr *Keymanager) WriteEncryptedSeedToWallet(
ctx context.Context, mnemonic, mnemonicPassphrase string,
// RecoverAccountsFromMnemonic given a mnemonic phrase, is able to regenerate N accounts
// from a derived seed, encrypt them according to the EIP-2334 JSON standard, and write them
// to disk. Then, the mnemonic is never stored nor used by the validator.
func (dr *Keymanager) RecoverAccountsFromMnemonic(
ctx context.Context, mnemonic, mnemonicPassphrase string, numAccounts int,
) error {
seedConfig, err := seedFileFromMnemonic(mnemonic, dr.wallet.Password(), mnemonicPassphrase)
seed, err := seedFromMnemonic(mnemonic, mnemonicPassphrase)
if err != nil {
return errors.Wrap(err, "could not initialize new wallet seed file")
}
seedConfigFile, err := marshalEncryptedSeedFile(seedConfig)
if err != nil {
return errors.Wrap(err, "could not marshal encrypted wallet seed file")
privKeys := make([][]byte, numAccounts)
pubKeys := make([][]byte, numAccounts)
for i := 0; i < numAccounts; i++ {
privKey, err := util.PrivateKeyFromSeedAndPath(
seed, fmt.Sprintf(ValidatingKeyDerivationPathTemplate, i),
)
if err != nil {
return err
}
privKeys[i] = privKey.Marshal()
pubKeys[i] = privKey.PublicKey().Marshal()
}
if err := dr.wallet.WriteEncryptedSeedToDisk(ctx, seedConfigFile); err != nil {
return errors.Wrap(err, "could not write encrypted wallet seed config to disk")
}
return nil
return dr.importedKM.ImportKeypairs(ctx, privKeys, pubKeys)
}
// ExtractKeystores retrieves the secret keys for specified public keys
// in the function input, encrypts them using the specified password,
// and returns their respective EIP-2335 keystores.
func (dr *Keymanager) ExtractKeystores(
ctx context.Context, publicKeys []bls.PublicKey, password string,
) ([]*keymanager.Keystore, error) {
return dr.importedKM.ExtractKeystores(ctx, publicKeys, password)
}
// ValidatingAccountNames for the derived keymanager.
func (dr *Keymanager) ValidatingAccountNames(_ context.Context) ([]string, error) {
lock.RLock()
names := make([]string, len(orderedPublicKeys))
for i, pubKey := range orderedPublicKeys {
names[i] = petnames.DeterministicName(bytesutil.FromBytes48(pubKey), "-")
}
lock.RUnlock()
return names, nil
}
// CreateAccount for a derived keymanager implementation. This utilizes
// the EIP-2335 keystore standard for BLS12-381 keystores. It uses the EIP-2333 and EIP-2334
// for hierarchical derivation of BLS secret keys and a common derivation path structure for
// persisting accounts to disk. Each account stores the generated keystore.json file.
// The entire derived wallet seed phrase can be recovered from a BIP-39 english mnemonic.
func (dr *Keymanager) CreateAccount(ctx context.Context) ([]byte, *pb.Deposit_Data, error) {
withdrawalKeyPath := fmt.Sprintf(WithdrawalKeyDerivationPathTemplate, dr.seedCfg.NextAccount)
validatingKeyPath := fmt.Sprintf(ValidatingKeyDerivationPathTemplate, dr.seedCfg.NextAccount)
withdrawalKey, err := dr.deriveKey(withdrawalKeyPath)
if err != nil {
return nil, nil, errors.Wrapf(err, "failed to create withdrawal key for account %d", dr.seedCfg.NextAccount)
}
validatingKey, err := dr.deriveKey(validatingKeyPath)
if err != nil {
return nil, nil, errors.Wrapf(err, "failed to create validating key for account %d", dr.seedCfg.NextAccount)
}
// Upon confirmation of the withdrawal key, proceed to display
// and write associated deposit data to disk.
blsValidatingKey, err := bls.SecretKeyFromBytes(validatingKey.Marshal())
if err != nil {
return nil, nil, err
}
blsWithdrawalKey, err := bls.SecretKeyFromBytes(withdrawalKey.Marshal())
if err != nil {
return nil, nil, err
}
// Upon confirmation of the withdrawal key, proceed to display
// and write associated deposit data to disk.
tx, data, err := depositutil.GenerateDepositTransaction(blsValidatingKey, blsWithdrawalKey)
if err != nil {
return nil, nil, errors.Wrap(err, "could not generate deposit transaction data")
}
domain, err := helpers.ComputeDomain(
params.BeaconConfig().DomainDeposit,
nil, /*forkVersion*/
nil, /*genesisValidatorsRoot*/
)
if err != nil {
return nil, nil, err
}
if err := depositutil.VerifyDepositSignature(data, domain); err != nil {
return nil, nil, errors.Wrap(err, "failed to verify deposit signature, please make sure your account was created properly")
}
// Log the deposit transaction data to the user.
fmt.Printf(`
==================Eth1 Deposit Transaction Data=================
%#x
================Verified for the %s network================`, tx.Data(), params.BeaconConfig().NetworkName)
fmt.Println("")
// Finally, write the account creation timestamps as a files.
newAccountNumber := dr.seedCfg.NextAccount
log.WithFields(logrus.Fields{
"accountNumber": newAccountNumber,
"withdrawalPublicKey": fmt.Sprintf("%#x", withdrawalKey.PublicKey().Marshal()),
"validatingPublicKey": fmt.Sprintf("%#x", validatingKey.PublicKey().Marshal()),
"withdrawalKeyPath": path.Join(dr.wallet.AccountsDir(), withdrawalKeyPath),
"validatingKeyPath": path.Join(dr.wallet.AccountsDir(), validatingKeyPath),
}).Info("Successfully created new validator account")
lock.Lock()
dr.seedCfg.NextAccount++
// Append the new account keys to the account keys caches
publicKey := bytesutil.ToBytes48(blsValidatingKey.PublicKey().Marshal())
orderedPublicKeys = append(orderedPublicKeys, publicKey)
secretKeysCache[publicKey] = blsValidatingKey
lock.Unlock()
encodedCfg, err := marshalEncryptedSeedFile(dr.seedCfg)
if err != nil {
return nil, nil, errors.Wrap(err, "could not marshal encrypted seed file")
}
if err := dr.wallet.WriteEncryptedSeedToDisk(ctx, encodedCfg); err != nil {
return nil, nil, errors.Wrap(err, "could not write encrypted seed file to disk")
}
return publicKey[:], data, nil
return dr.importedKM.ValidatingAccountNames()
}
// Sign signs a message using a validator key.
func (dr *Keymanager) Sign(_ context.Context, req *validatorpb.SignRequest) (bls.Signature, error) {
rawPubKey := req.PublicKey
if rawPubKey == nil {
return nil, errors.New("nil public key in request")
}
lock.RLock()
secretKey, ok := secretKeysCache[bytesutil.ToBytes48(rawPubKey)]
lock.RUnlock()
if !ok {
return nil, errors.New("no signing key found in keys cache")
}
return secretKey.Sign(req.SigningRoot), nil
func (dr *Keymanager) Sign(ctx context.Context, req *validatorpb.SignRequest) (bls.Signature, error) {
return dr.importedKM.Sign(ctx, req)
}
// FetchValidatingPublicKeys fetches the list of validating public keys from the keymanager.
func (dr *Keymanager) FetchValidatingPublicKeys(_ context.Context) ([][48]byte, error) {
lock.RLock()
keys := orderedPublicKeys
result := make([][48]byte, len(keys))
copy(result, keys)
lock.RUnlock()
return result, nil
func (dr *Keymanager) FetchValidatingPublicKeys(ctx context.Context) ([][48]byte, error) {
return dr.importedKM.FetchValidatingPublicKeys(ctx)
}
// FetchAllValidatingPublicKeys fetches the list of all public keys (including disabled ones) from the keymanager.
func (dr *Keymanager) FetchAllValidatingPublicKeys(ctx context.Context) ([][48]byte, error) {
return dr.FetchValidatingPublicKeys(ctx)
return dr.importedKM.FetchAllValidatingPublicKeys(ctx)
}
// FetchValidatingPrivateKeys fetches the list of validating private keys from the keymanager.
func (dr *Keymanager) FetchValidatingPrivateKeys(ctx context.Context) ([][32]byte, error) {
lock.RLock()
defer lock.RUnlock()
privKeys := make([][32]byte, len(secretKeysCache))
pubKeys, err := dr.FetchValidatingPublicKeys(ctx)
if err != nil {
return nil, errors.Wrap(err, "could not retrieve public keys")
}
for i, pk := range pubKeys {
seckey, ok := secretKeysCache[pk]
if !ok {
return nil, errors.New("Could not fetch private key")
}
privKeys[i] = bytesutil.ToBytes32(seckey.Marshal())
}
return privKeys, nil
return dr.importedKM.FetchValidatingPrivateKeys(ctx)
}
// FetchWithdrawalPublicKeys fetches the list of withdrawal public keys from keymanager
func (dr *Keymanager) FetchWithdrawalPublicKeys(_ context.Context) ([][48]byte, error) {
publicKeys := make([][48]byte, 0)
for i := uint64(0); i < dr.seedCfg.NextAccount; i++ {
withdrawalKeyPath := fmt.Sprintf(WithdrawalKeyDerivationPathTemplate, i)
withdrawalKey, err := dr.deriveKey(withdrawalKeyPath)
if err != nil {
return nil, errors.Wrapf(err, "failed to create withdrawal key for account %d", i)
}
publicKeys = append(publicKeys, bytesutil.ToBytes48(withdrawalKey.PublicKey().Marshal()))
}
return publicKeys, nil
}
// FetchWithdrawalPrivateKeys fetches the list of withdrawal private keys from the keymanager.
func (dr *Keymanager) FetchWithdrawalPrivateKeys(ctx context.Context) ([][32]byte, error) {
privKeys := make([][32]byte, 0)
for i := uint64(0); i < dr.seedCfg.NextAccount; i++ {
withdrawalKeyPath := fmt.Sprintf(WithdrawalKeyDerivationPathTemplate, i)
withdrawalKey, err := dr.deriveKey(withdrawalKeyPath)
if err != nil {
return nil, errors.Wrapf(err, "failed to create withdrawal key for account %d", i)
}
privKeys = append(privKeys, bytesutil.ToBytes32(withdrawalKey.Marshal()))
}
return privKeys, nil
}
// DepositDataForAccount with a given index returns the RLP encoded eth1 deposit transaction data.
func (dr *Keymanager) DepositDataForAccount(accountIndex uint64) ([]byte, error) {
withdrawalKeyPath := fmt.Sprintf(WithdrawalKeyDerivationPathTemplate, accountIndex)
validatingKeyPath := fmt.Sprintf(ValidatingKeyDerivationPathTemplate, accountIndex)
withdrawalKey, err := dr.deriveKey(withdrawalKeyPath)
if err != nil {
return nil, errors.Wrapf(err, "failed to create withdrawal key for account %d", accountIndex)
}
validatingKey, err := dr.deriveKey(validatingKeyPath)
if err != nil {
return nil, errors.Wrapf(err, "failed to create validating key for account %d", accountIndex)
}
// Upon confirmation of the withdrawal key, proceed to display
// and write associated deposit data to disk.
blsValidatingKey, err := bls.SecretKeyFromBytes(validatingKey.Marshal())
if err != nil {
return nil, err
}
blsWithdrawalKey, err := bls.SecretKeyFromBytes(withdrawalKey.Marshal())
if err != nil {
return nil, err
}
tx, _, err := depositutil.GenerateDepositTransaction(blsValidatingKey, blsWithdrawalKey)
if err != nil {
return nil, errors.Wrap(err, "could not generate deposit transaction data")
}
return tx.Data(), nil
}
func (dr *Keymanager) rewriteSeedConfig(ctx context.Context) error {
encryptor := keystorev4.New()
encryptedFields, err := encryptor.Encrypt(dr.seed, dr.wallet.Password())
if err != nil {
return err
}
newConfig := &SeedConfig{
Crypto: encryptedFields,
ID: dr.seedCfg.ID,
NextAccount: dr.seedCfg.NextAccount,
Version: dr.seedCfg.Version,
Name: dr.seedCfg.Name,
}
dr.seedCfg = newConfig
encodedSeedFile, err := marshalEncryptedSeedFile(newConfig)
if err != nil {
return errors.Wrap(err, "could not marshal encrypted wallet seed file")
}
if err = dr.wallet.WriteEncryptedSeedToDisk(ctx, encodedSeedFile); err != nil {
return errors.Wrap(err, "could not write encrypted wallet seed config to disk")
}
return nil
}
// Initialize public and secret key caches used to speed up the functions
// FetchValidatingPublicKeys and Sign as part of the Keymanager instance initialization
func (dr *Keymanager) initializeKeysCachesFromSeed() error {
lock.Lock()
defer lock.Unlock()
count := dr.seedCfg.NextAccount
orderedPublicKeys = make([][48]byte, count)
secretKeysCache = make(map[[48]byte]bls.SecretKey, count)
for i := uint64(0); i < count; i++ {
validatingKeyPath := fmt.Sprintf(ValidatingKeyDerivationPathTemplate, i)
derivedKey, err := dr.deriveKey(validatingKeyPath)
if err != nil {
return errors.Wrapf(err, "failed to derive validating key for account %s", validatingKeyPath)
}
secretKey, err := bls.SecretKeyFromBytes(derivedKey.Marshal())
if err != nil {
return errors.Wrapf(
err,
"could not instantiate bls secret key from bytes for account: %s",
validatingKeyPath,
)
}
publicKey := bytesutil.ToBytes48(secretKey.PublicKey().Marshal())
orderedPublicKeys[i] = publicKey
secretKeysCache[publicKey] = secretKey
}
return nil
}
func (dr *Keymanager) deriveKey(path string) (*types.BLSPrivateKey, error) {
return util.PrivateKeyFromSeedAndPath(dr.seed, path)
}
func checkEncodedKeyFile(
ctx context.Context,
wallet iface.Wallet,
skipMnemonicConfirm bool,
mnemonicPassphrase string,
) ([]byte, error) {
if !fileutil.FileExists(filepath.Join(wallet.AccountsDir(), EncryptedSeedFileName)) {
seedConfig, err := initializeWalletSeedFile(wallet.Password(), skipMnemonicConfirm, mnemonicPassphrase)
if err != nil {
return nil, errors.Wrap(err, "could not initialize new wallet seed file")
}
encodedSeedFile, err := marshalEncryptedSeedFile(seedConfig)
if err != nil {
return nil, errors.Wrap(err, "could not marshal encrypted wallet seed file")
}
if err = wallet.WriteEncryptedSeedToDisk(ctx, encodedSeedFile); err != nil {
return nil, errors.Wrap(err, "could not write encrypted wallet seed config to disk")
}
return encodedSeedFile, nil
}
seedConfigFile, err := wallet.ReadEncryptedSeedFromDisk(ctx)
if err != nil {
return nil, errors.Wrap(err, "could not read encrypted seed file from disk")
}
defer func() {
if err := seedConfigFile.Close(); err != nil {
log.Errorf("Could not close keymanager config file: %v", err)
}
}()
encodedSeedFile, err := ioutil.ReadAll(seedConfigFile)
if err != nil {
return nil, errors.Wrap(err, "could not read seed configuration file contents")
}
return encodedSeedFile, nil
}
// Creates a new, encrypted seed using a password input
// and persists its encrypted file metadata to disk under the wallet path.
func initializeWalletSeedFile(
password string,
skipMnemonicConfirm bool,
mnemonicPassphrase string,
) (*SeedConfig, error) {
mnemonicRandomness := make([]byte, 32)
if _, err := rand.NewGenerator().Read(mnemonicRandomness); err != nil {
return nil, errors.Wrap(err, "could not initialize mnemonic source of randomness")
}
m := &EnglishMnemonicGenerator{
skipMnemonicConfirm: skipMnemonicConfirm,
}
phrase, err := m.Generate(mnemonicRandomness)
if err != nil {
return nil, errors.Wrap(err, "could not generate wallet seed")
}
if err := m.ConfirmAcknowledgement(phrase); err != nil {
return nil, errors.Wrap(err, "could not confirm mnemonic acknowledgement")
}
walletSeed := bip39.NewSeed(phrase, mnemonicPassphrase)
encryptor := keystorev4.New()
cryptoFields, err := encryptor.Encrypt(walletSeed, password)
if err != nil {
return nil, errors.Wrap(err, "could not encrypt seed phrase into keystore")
}
id, err := uuid.NewRandom()
if err != nil {
return nil, errors.Wrap(err, "could not generate unique UUID")
}
return &SeedConfig{
Crypto: cryptoFields,
ID: id.String(),
NextAccount: 0,
Version: encryptor.Version(),
Name: encryptor.Name(),
}, nil
}
// Uses the provided mnemonic seed phrase to generate the
// appropriate seed file for recovering a derived wallets.
func seedFileFromMnemonic(mnemonic, password string, mnemonicPassphrase string) (*SeedConfig, error) {
if ok := bip39.IsMnemonicValid(mnemonic); !ok {
return nil, bip39.ErrInvalidMnemonic
}
walletSeed := bip39.NewSeed(mnemonic, mnemonicPassphrase)
encryptor := keystorev4.New()
cryptoFields, err := encryptor.Encrypt(walletSeed, password)
if err != nil {
return nil, errors.Wrap(err, "could not encrypt seed phrase into keystore")
}
id, err := uuid.NewRandom()
if err != nil {
return nil, errors.Wrap(err, "could not generate unique UUID")
}
return &SeedConfig{
Crypto: cryptoFields,
ID: id.String(),
NextAccount: 0,
Version: encryptor.Version(),
Name: encryptor.Name(),
}, nil
}
// marshalEncryptedSeedFile json encodes the seed configuration for a derived keymanager.
func marshalEncryptedSeedFile(seedCfg *SeedConfig) ([]byte, error) {
return json.MarshalIndent(seedCfg, "", "\t")
// DeleteAccounts for a derived keymanager.
func (dr *Keymanager) DeleteAccounts(ctx context.Context, publicKeys [][]byte) error {
return dr.importedKM.DeleteAccounts(ctx, publicKeys)
}

View File

@@ -2,23 +2,17 @@ package derived
import (
"context"
"encoding/json"
"fmt"
"io/ioutil"
"testing"
"github.com/google/uuid"
validatorpb "github.com/prysmaticlabs/prysm/proto/validator/accounts/v2"
"github.com/prysmaticlabs/prysm/shared/bls"
"github.com/prysmaticlabs/prysm/shared/bytesutil"
"github.com/prysmaticlabs/prysm/shared/rand"
"github.com/prysmaticlabs/prysm/shared/testutil/assert"
"github.com/prysmaticlabs/prysm/shared/testutil/require"
mock "github.com/prysmaticlabs/prysm/validator/accounts/testing"
logTest "github.com/sirupsen/logrus/hooks/test"
"github.com/tyler-smith/go-bip39"
util "github.com/wealdtech/go-eth2-util"
keystorev4 "github.com/wealdtech/go-eth2-wallet-encryptor-keystorev4"
)
// We test that using a '25th word' mnemonic passphrase leads to different
@@ -31,19 +25,14 @@ func TestDerivedKeymanager_MnemnonicPassphrase_DifferentResults(t *testing.T) {
AccountPasswords: make(map[string]string),
WalletPassword: "secretPassw0rd$1999",
}
km, err := KeymanagerForPhrase(ctx, &SetupConfig{
Opts: DefaultKeymanagerOpts(),
Wallet: wallet,
SkipMnemonicConfirm: true,
Mnemonic: sampleMnemonic,
Mnemonic25thWord: "",
km, err := NewKeymanager(ctx, &SetupConfig{
Opts: DefaultKeymanagerOpts(),
Wallet: wallet,
})
require.NoError(t, err)
numAccounts := 5
for i := 0; i < numAccounts; i++ {
_, _, err = km.CreateAccount(ctx)
require.NoError(t, err)
}
err = km.RecoverAccountsFromMnemonic(ctx, sampleMnemonic, "mnemonicpass", numAccounts)
require.NoError(t, err)
without25thWord, err := km.FetchValidatingPublicKeys(ctx)
require.NoError(t, err)
wallet = &mock.Wallet{
@@ -51,18 +40,14 @@ func TestDerivedKeymanager_MnemnonicPassphrase_DifferentResults(t *testing.T) {
AccountPasswords: make(map[string]string),
WalletPassword: "secretPassw0rd$1999",
}
km, err = KeymanagerForPhrase(ctx, &SetupConfig{
Opts: DefaultKeymanagerOpts(),
Wallet: wallet,
SkipMnemonicConfirm: true,
Mnemonic: sampleMnemonic,
Mnemonic25thWord: "mnemonicpass",
km, err = NewKeymanager(ctx, &SetupConfig{
Opts: DefaultKeymanagerOpts(),
Wallet: wallet,
})
require.NoError(t, err)
for i := 0; i < numAccounts; i++ {
_, _, err = km.CreateAccount(ctx)
require.NoError(t, err)
}
// No mnemonic passphrase this time.
err = km.RecoverAccountsFromMnemonic(ctx, sampleMnemonic, "", numAccounts)
require.NoError(t, err)
with25thWord, err := km.FetchValidatingPublicKeys(ctx)
require.NoError(t, err)
for i, k := range with25thWord {
@@ -78,223 +63,124 @@ func TestDerivedKeymanager_RecoverSeedRoundTrip(t *testing.T) {
require.Equal(t, n, len(mnemonicEntropy))
mnemonic, err := bip39.NewMnemonic(mnemonicEntropy)
require.NoError(t, err)
walletSeed := bip39.NewSeed(mnemonic, "")
encryptor := keystorev4.New()
password := "Passwz0rdz2020%"
cryptoFields, err := encryptor.Encrypt(walletSeed, password)
require.NoError(t, err)
id, err := uuid.NewRandom()
require.NoError(t, err)
cfg := &SeedConfig{
Crypto: cryptoFields,
ID: id.String(),
NextAccount: 0,
Version: encryptor.Version(),
Name: encryptor.Name(),
}
wanted := bip39.NewSeed(mnemonic, "")
// Ensure we can decrypt the newly recovered config.
decryptor := keystorev4.New()
seed, err := decryptor.Decrypt(cfg.Crypto, password)
assert.NoError(t, err)
// Ensure the decrypted seed matches the old wallet seed and the new wallet seed.
assert.DeepEqual(t, walletSeed, seed)
}
func TestDerivedKeymanager_CreateAccount(t *testing.T) {
hook := logTest.NewGlobal()
wallet := &mock.Wallet{
Files: make(map[string]map[string][]byte),
AccountPasswords: make(map[string]string),
WalletPassword: "secretPassw0rd$1999",
}
seed := make([]byte, 32)
copy(seed, "hello world")
dr := &Keymanager{
wallet: wallet,
seed: seed,
seedCfg: &SeedConfig{
NextAccount: 0,
},
opts: DefaultKeymanagerOpts(),
}
require.NoError(t, dr.initializeKeysCachesFromSeed())
ctx := context.Background()
_, _, err := dr.CreateAccount(ctx)
got, err := seedFromMnemonic(mnemonic, "" /* no passphrase */)
require.NoError(t, err)
// Assert the new value for next account increased and also
// check the config file was updated on disk with this new value.
assert.Equal(t, uint64(1), dr.seedCfg.NextAccount, "Wrong value for next account")
encryptedSeedFile, err := wallet.ReadEncryptedSeedFromDisk(ctx)
require.NoError(t, err)
enc, err := ioutil.ReadAll(encryptedSeedFile)
require.NoError(t, err)
defer func() {
assert.NoError(t, encryptedSeedFile.Close())
}()
seedConfig := &SeedConfig{}
require.NoError(t, json.Unmarshal(enc, seedConfig))
assert.Equal(t, uint64(1), seedConfig.NextAccount, "Wrong value for next account")
// Ensure the new account information is displayed to stdout.
require.LogsContain(t, hook, "Successfully created new validator account")
// Ensure the derived seed matches.
assert.DeepEqual(t, wanted, got)
}
func TestDerivedKeymanager_FetchValidatingPublicKeys(t *testing.T) {
sampleMnemonic := "tumble turn jewel sudden social great water general cabin jacket bounce dry flip monster advance problem social half flee inform century chicken hard reason"
derivedSeed, err := seedFromMnemonic(sampleMnemonic, "")
require.NoError(t, err)
wallet := &mock.Wallet{
Files: make(map[string]map[string][]byte),
AccountPasswords: make(map[string]string),
WalletPassword: "secretPassw0rd$1999",
}
dr := &Keymanager{
wallet: wallet,
seedCfg: &SeedConfig{
NextAccount: 0,
},
seed: make([]byte, 32),
opts: DefaultKeymanagerOpts(),
}
require.NoError(t, dr.initializeKeysCachesFromSeed())
// First, generate accounts and their keystore.json files.
ctx := context.Background()
numAccounts := 20
wantedPublicKeys := make([][48]byte, numAccounts)
for i := 0; i < numAccounts; i++ {
_, _, err := dr.CreateAccount(ctx)
require.NoError(t, err)
validatingKeyPath := fmt.Sprintf(ValidatingKeyDerivationPathTemplate, i)
validatingKey, err := util.PrivateKeyFromSeedAndPath(dr.seed, validatingKeyPath)
require.NoError(t, err)
wantedPublicKeys[i] = bytesutil.ToBytes48(validatingKey.PublicKey().Marshal())
}
dr, err := NewKeymanager(ctx, &SetupConfig{
Opts: DefaultKeymanagerOpts(),
Wallet: wallet,
})
require.NoError(t, err)
numAccounts := 5
err = dr.RecoverAccountsFromMnemonic(ctx, sampleMnemonic, "", numAccounts)
require.NoError(t, err)
// Fetch the public keys.
publicKeys, err := dr.FetchValidatingPublicKeys(ctx)
require.NoError(t, err)
require.Equal(t, numAccounts, len(publicKeys))
wantedPubKeys := make([][48]byte, numAccounts)
for i := 0; i < numAccounts; i++ {
privKey, err := util.PrivateKeyFromSeedAndPath(derivedSeed, fmt.Sprintf(ValidatingKeyDerivationPathTemplate, i))
require.NoError(t, err)
pubKey := [48]byte{}
copy(pubKey[:], privKey.PublicKey().Marshal())
wantedPubKeys[i] = pubKey
}
// FetchValidatingPublicKeys is also used in generating the output of account list
// therefore the results must be in the same order as the order in which the accounts were derived
for i, key := range wantedPublicKeys {
for i, key := range wantedPubKeys {
assert.Equal(t, key, publicKeys[i])
}
}
func TestDerivedKeymanager_FetchValidatingPrivateKeys(t *testing.T) {
sampleMnemonic := "tumble turn jewel sudden social great water general cabin jacket bounce dry flip monster advance problem social half flee inform century chicken hard reason"
derivedSeed, err := seedFromMnemonic(sampleMnemonic, "")
require.NoError(t, err)
wallet := &mock.Wallet{
Files: make(map[string]map[string][]byte),
AccountPasswords: make(map[string]string),
WalletPassword: "secretPassw0rd$1999",
}
dr := &Keymanager{
wallet: wallet,
seedCfg: &SeedConfig{
NextAccount: 0,
},
seed: make([]byte, 32),
opts: DefaultKeymanagerOpts(),
}
require.NoError(t, dr.initializeKeysCachesFromSeed())
// First, generate accounts and their keystore.json files.
ctx := context.Background()
numAccounts := 20
wantedPrivateKeys := make([][32]byte, numAccounts)
for i := 0; i < numAccounts; i++ {
_, _, err := dr.CreateAccount(ctx)
require.NoError(t, err)
validatingKeyPath := fmt.Sprintf(ValidatingKeyDerivationPathTemplate, i)
validatingKey, err := util.PrivateKeyFromSeedAndPath(dr.seed, validatingKeyPath)
require.NoError(t, err)
wantedPrivateKeys[i] = bytesutil.ToBytes32(validatingKey.Marshal())
}
dr, err := NewKeymanager(ctx, &SetupConfig{
Opts: DefaultKeymanagerOpts(),
Wallet: wallet,
})
require.NoError(t, err)
numAccounts := 5
err = dr.RecoverAccountsFromMnemonic(ctx, sampleMnemonic, "", numAccounts)
require.NoError(t, err)
// Fetch the private keys.
privateKeys, err := dr.FetchValidatingPrivateKeys(ctx)
require.NoError(t, err)
require.Equal(t, numAccounts, len(privateKeys))
wantedPrivKeys := make([][32]byte, numAccounts)
for i := 0; i < numAccounts; i++ {
privKey, err := util.PrivateKeyFromSeedAndPath(derivedSeed, fmt.Sprintf(ValidatingKeyDerivationPathTemplate, i))
require.NoError(t, err)
privKeyBytes := [32]byte{}
copy(privKeyBytes[:], privKey.Marshal())
wantedPrivKeys[i] = privKeyBytes
}
// FetchValidatingPrivateKeys is also used in generating the output of account list
// therefore the results must be in the same order as the order in which the accounts were derived
for i, key := range wantedPrivateKeys {
assert.Equal(t, key, privateKeys[i])
}
}
func TestDerivedKeymanager_FetchWithdrawalPrivateKeys(t *testing.T) {
wallet := &mock.Wallet{
Files: make(map[string]map[string][]byte),
AccountPasswords: make(map[string]string),
WalletPassword: "secretPassw0rd$1999",
}
dr := &Keymanager{
wallet: wallet,
seedCfg: &SeedConfig{
NextAccount: 0,
},
seed: make([]byte, 32),
opts: DefaultKeymanagerOpts(),
}
require.NoError(t, dr.initializeKeysCachesFromSeed())
// First, generate accounts and their keystore.json files.
ctx := context.Background()
numAccounts := 20
wantedPrivateKeys := make([][32]byte, numAccounts)
for i := 0; i < numAccounts; i++ {
_, _, err := dr.CreateAccount(ctx)
require.NoError(t, err)
withdrawalKeyPath := fmt.Sprintf(WithdrawalKeyDerivationPathTemplate, i)
withdrawalKey, err := util.PrivateKeyFromSeedAndPath(dr.seed, withdrawalKeyPath)
require.NoError(t, err)
wantedPrivateKeys[i] = bytesutil.ToBytes32(withdrawalKey.Marshal())
}
privateKeys, err := dr.FetchWithdrawalPrivateKeys(ctx)
require.NoError(t, err)
require.Equal(t, numAccounts, len(privateKeys))
// FetchWithdrawalPrivateKeys is also used in generating the output of account list
// therefore the results must be in the same order as the order in which the accounts were derived
for i, key := range wantedPrivateKeys {
for i, key := range wantedPrivKeys {
assert.Equal(t, key, privateKeys[i])
}
}
func TestDerivedKeymanager_Sign(t *testing.T) {
sampleMnemonic := "tumble turn jewel sudden social great water general cabin jacket bounce dry flip monster advance problem social half flee inform century chicken hard reason"
wallet := &mock.Wallet{
Files: make(map[string]map[string][]byte),
AccountPasswords: make(map[string]string),
WalletPassword: "secretPassw0rd$1999",
}
seed := make([]byte, 32)
copy(seed, "hello world")
dr := &Keymanager{
wallet: wallet,
seed: seed,
seedCfg: &SeedConfig{
NextAccount: 0,
},
opts: DefaultKeymanagerOpts(),
}
require.NoError(t, dr.initializeKeysCachesFromSeed())
// First, generate some accounts.
numAccounts := 2
ctx := context.Background()
for i := 0; i < numAccounts; i++ {
_, _, err := dr.CreateAccount(ctx)
require.NoError(t, err)
}
publicKeys, err := dr.FetchValidatingPublicKeys(ctx)
dr, err := NewKeymanager(ctx, &SetupConfig{
Opts: DefaultKeymanagerOpts(),
Wallet: wallet,
})
require.NoError(t, err)
numAccounts := 5
err = dr.RecoverAccountsFromMnemonic(ctx, sampleMnemonic, "", numAccounts)
require.NoError(t, err)
pubKeys, err := dr.FetchAllValidatingPublicKeys(ctx)
require.NoError(t, err)
// We prepare naive data to sign.
data := []byte("eth2data")
signRequest := &validatorpb.SignRequest{
PublicKey: publicKeys[0][:],
PublicKey: pubKeys[0][:],
SigningRoot: data,
}
sig, err := dr.Sign(ctx, signRequest)
require.NoError(t, err)
pubKey, err := bls.PublicKeyFromBytes(publicKeys[0][:])
pubKey, err := bls.PublicKeyFromBytes(pubKeys[0][:])
require.NoError(t, err)
wrongPubKey, err := bls.PublicKeyFromBytes(publicKeys[1][:])
wrongPubKey, err := bls.PublicKeyFromBytes(pubKeys[1][:])
require.NoError(t, err)
// Check if the signature verifies.

View File

@@ -4,22 +4,14 @@ import (
"fmt"
"os"
"github.com/pkg/errors"
"github.com/prysmaticlabs/prysm/shared/promptutil"
"github.com/prysmaticlabs/prysm/shared/rand"
"github.com/tyler-smith/go-bip39"
)
const confirmationText = "Confirm you have written down the recovery words somewhere safe (offline) [y|Y]"
// SeedPhraseFactory defines a struct which
// can generate new seed phrases in human-readable
// format from a source of entropy in raw bytes. It
// also provides methods for verifying a user has successfully
// acknowledged the mnemonic phrase and written it down offline.
type SeedPhraseFactory interface {
Generate(data []byte) (string, error)
ConfirmAcknowledgement(phrase string) error
}
// EnglishMnemonicGenerator implements methods for creating
// mnemonic seed phrases in english using a given
// source of entropy such as a private key.
@@ -27,6 +19,26 @@ type EnglishMnemonicGenerator struct {
skipMnemonicConfirm bool
}
func GenerateAndConfirmMnemonic(
skipMnemonicConfirm bool,
) (string, error) {
mnemonicRandomness := make([]byte, 32)
if _, err := rand.NewGenerator().Read(mnemonicRandomness); err != nil {
return "", errors.Wrap(err, "could not initialize mnemonic source of randomness")
}
m := &EnglishMnemonicGenerator{
skipMnemonicConfirm: skipMnemonicConfirm,
}
phrase, err := m.Generate(mnemonicRandomness)
if err != nil {
return "", errors.Wrap(err, "could not generate wallet seed")
}
if err := m.ConfirmAcknowledgement(phrase); err != nil {
return "", errors.Wrap(err, "could not confirm mnemonic acknowledgement")
}
return phrase, nil
}
// Generate a mnemonic seed phrase in english using a source of
// entropy given as raw bytes.
func (m *EnglishMnemonicGenerator) Generate(data []byte) (string, error) {
@@ -58,3 +70,12 @@ func (m *EnglishMnemonicGenerator) ConfirmAcknowledgement(phrase string) error {
}
return nil
}
//Uses the provided mnemonic seed phrase to generate the
//appropriate seed file for recovering a derived wallets.
func seedFromMnemonic(mnemonic, mnemonicPassphrase string) ([]byte, error) {
if ok := bip39.IsMnemonicValid(mnemonic); !ok {
return nil, bip39.ErrInvalidMnemonic
}
return bip39.NewSeed(mnemonic, mnemonicPassphrase), nil
}

View File

@@ -60,6 +60,20 @@ func (dr *Keymanager) ImportKeystores(
return dr.wallet.WriteFileAtPath(ctx, AccountsPath, accountsKeystoreFileName, encodedAccounts)
}
// ImportKeypairs directly into the keymanager.
func (dr *Keymanager) ImportKeypairs(ctx context.Context, privKeys [][]byte, pubKeys [][]byte) error {
// Write the accounts to disk into a single keystore.
accountsKeystore, err := dr.createAccountsKeystore(ctx, privKeys, pubKeys)
if err != nil {
return errors.Wrap(err, "could not import account keypairs")
}
encodedAccounts, err := json.MarshalIndent(accountsKeystore, "", "\t")
if err != nil {
return errors.Wrap(err, "could not marshal accounts keystore into JSON")
}
return dr.wallet.WriteFileAtPath(ctx, AccountsPath, accountsKeystoreFileName, encodedAccounts)
}
// Retrieves the private key and public key from an EIP-2335 keystore file
// by decrypting using a specified password. If the password fails,
// it prompts the user for the correct password until it confirms.

View File

@@ -34,7 +34,6 @@ go_library(
"//shared/prometheus:go_default_library",
"//shared/tracing:go_default_library",
"//shared/version:go_default_library",
"//validator/accounts/iface:go_default_library",
"//validator/accounts/wallet:go_default_library",
"//validator/client:go_default_library",
"//validator/db/kv:go_default_library",

View File

@@ -24,7 +24,6 @@ import (
"github.com/prysmaticlabs/prysm/shared/prometheus"
"github.com/prysmaticlabs/prysm/shared/tracing"
"github.com/prysmaticlabs/prysm/shared/version"
"github.com/prysmaticlabs/prysm/validator/accounts/iface"
"github.com/prysmaticlabs/prysm/validator/accounts/wallet"
"github.com/prysmaticlabs/prysm/validator/client"
"github.com/prysmaticlabs/prysm/validator/db/kv"
@@ -183,9 +182,7 @@ func (s *ValidatorClient) initializeFromCLI(cliCtx *cli.Context) error {
"wallet": w.AccountsDir(),
"keymanager-kind": w.KeymanagerKind().String(),
}).Info("Opened validator wallet")
keyManager, err = w.InitializeKeymanager(cliCtx.Context, &iface.InitializeKeymanagerConfig{
SkipMnemonicConfirm: false,
})
keyManager, err = w.InitializeKeymanager(cliCtx.Context)
if err != nil {
return errors.Wrap(err, "could not read keymanager for wallet")
}
@@ -271,9 +268,7 @@ func (s *ValidatorClient) initializeForWeb(cliCtx *cli.Context) error {
"wallet": w.AccountsDir(),
"keymanager-kind": w.KeymanagerKind().String(),
}).Info("Opened validator wallet")
keyManager, err = w.InitializeKeymanager(cliCtx.Context, &iface.InitializeKeymanagerConfig{
SkipMnemonicConfirm: false,
})
keyManager, err = w.InitializeKeymanager(cliCtx.Context)
if err != nil {
return errors.Wrap(err, "could not read keymanager for wallet")
}

View File

@@ -25,7 +25,6 @@ go_library(
"//shared/timeutils:go_default_library",
"//shared/traceutil:go_default_library",
"//validator/accounts:go_default_library",
"//validator/accounts/iface:go_default_library",
"//validator/accounts/wallet:go_default_library",
"//validator/client:go_default_library",
"//validator/db:go_default_library",
@@ -39,7 +38,6 @@ go_library(
"@com_github_grpc_ecosystem_go_grpc_middleware//tracing/opentracing:go_default_library",
"@com_github_grpc_ecosystem_go_grpc_prometheus//:go_default_library",
"@com_github_pkg_errors//:go_default_library",
"@com_github_prysmaticlabs_ethereumapis//eth/v1alpha1:go_default_library",
"@com_github_sirupsen_logrus//:go_default_library",
"@com_github_tyler_smith_go_bip39//:go_default_library",
"@io_opencensus_go//plugin/ocgrpc:go_default_library",
@@ -69,12 +67,10 @@ go_test(
"//shared/bls:go_default_library",
"//shared/event:go_default_library",
"//shared/fileutil:go_default_library",
"//shared/params:go_default_library",
"//shared/testutil/assert:go_default_library",
"//shared/testutil/require:go_default_library",
"//shared/timeutils:go_default_library",
"//validator/accounts:go_default_library",
"//validator/accounts/iface:go_default_library",
"//validator/accounts/wallet:go_default_library",
"//validator/client:go_default_library",
"//validator/db/testing:go_default_library",

View File

@@ -4,45 +4,16 @@ import (
"context"
"fmt"
"github.com/pkg/errors"
ethpb "github.com/prysmaticlabs/ethereumapis/eth/v1alpha1"
pb "github.com/prysmaticlabs/prysm/proto/validator/accounts/v2"
"github.com/prysmaticlabs/prysm/shared/cmd"
"github.com/prysmaticlabs/prysm/shared/pagination"
"github.com/prysmaticlabs/prysm/shared/petnames"
"github.com/prysmaticlabs/prysm/validator/accounts"
"github.com/prysmaticlabs/prysm/validator/keymanager"
"github.com/prysmaticlabs/prysm/validator/keymanager/derived"
"google.golang.org/grpc/codes"
"google.golang.org/grpc/status"
)
type accountCreator interface {
CreateAccount(ctx context.Context) ([]byte, *ethpb.Deposit_Data, error)
}
// CreateAccount allows creation of a new account in a user's wallet via RPC.
func (s *Server) CreateAccount(ctx context.Context, req *pb.CreateAccountRequest) (*pb.DepositDataResponse, error) {
if !s.walletInitialized {
return nil, status.Error(codes.FailedPrecondition, "Wallet not yet initialized")
}
km, ok := s.keymanager.(*derived.Keymanager)
if !ok {
return nil, status.Error(codes.InvalidArgument, "Only HD wallets can create accounts")
}
dataList := make([]*pb.DepositDataResponse_DepositData, req.NumAccounts)
for i := uint64(0); i < req.NumAccounts; i++ {
data, err := createAccountWithDepositData(ctx, km)
if err != nil {
return nil, err
}
dataList[i] = data
}
return &pb.DepositDataResponse{
DepositDataList: dataList,
}, nil
}
// ListAccounts allows retrieval of validating keys and their petnames
// for a user's wallet via RPC.
func (s *Server) ListAccounts(ctx context.Context, req *pb.ListAccountsRequest) (*pb.ListAccountsResponse, error) {
@@ -88,18 +59,3 @@ func (s *Server) ListAccounts(ctx context.Context, req *pb.ListAccountsRequest)
NextPageToken: nextPageToken,
}, nil
}
func createAccountWithDepositData(ctx context.Context, km accountCreator) (*pb.DepositDataResponse_DepositData, error) {
// Create a new validator account using the specified keymanager.
_, depositData, err := km.CreateAccount(ctx)
if err != nil {
return nil, errors.Wrap(err, "could not create account in wallet")
}
data, err := accounts.DepositDataJSON(depositData)
if err != nil {
return nil, errors.Wrap(err, "could not create deposit data JSON")
}
return &pb.DepositDataResponse_DepositData{
Data: data,
}, nil
}

View File

@@ -2,62 +2,23 @@ package rpc
import (
"context"
"fmt"
"path/filepath"
"testing"
ethpb "github.com/prysmaticlabs/ethereumapis/eth/v1alpha1"
pb "github.com/prysmaticlabs/prysm/proto/validator/accounts/v2"
"github.com/prysmaticlabs/prysm/shared/bls"
"github.com/prysmaticlabs/prysm/shared/params"
"github.com/prysmaticlabs/prysm/shared/testutil/assert"
"github.com/prysmaticlabs/prysm/shared/testutil/require"
"github.com/prysmaticlabs/prysm/validator/accounts"
"github.com/prysmaticlabs/prysm/validator/accounts/iface"
"github.com/prysmaticlabs/prysm/validator/accounts/wallet"
"github.com/prysmaticlabs/prysm/validator/flags"
"github.com/prysmaticlabs/prysm/validator/keymanager"
"github.com/prysmaticlabs/prysm/validator/keymanager/derived"
)
var defaultWalletPath = filepath.Join(flags.DefaultValidatorDir(), flags.WalletDefaultDirName)
type mockAccountCreator struct {
data *ethpb.Deposit_Data
pubKey []byte
}
func (m *mockAccountCreator) CreateAccount(ctx context.Context) ([]byte, *ethpb.Deposit_Data, error) {
return m.pubKey, m.data, nil
}
func TestServer_CreateAccount(t *testing.T) {
ctx := context.Background()
localWalletDir := setupWalletDir(t)
defaultWalletPath = localWalletDir
strongPass := "29384283xasjasd32%%&*@*#*"
// We attempt to create the wallet.
w, err := accounts.CreateWalletWithKeymanager(ctx, &accounts.CreateWalletConfig{
WalletCfg: &wallet.Config{
WalletDir: defaultWalletPath,
KeymanagerKind: keymanager.Derived,
WalletPassword: strongPass,
},
SkipMnemonicConfirm: true,
})
require.NoError(t, err)
km, err := w.InitializeKeymanager(ctx, &iface.InitializeKeymanagerConfig{
SkipMnemonicConfirm: true,
})
require.NoError(t, err)
s := &Server{
keymanager: km,
walletInitialized: true,
wallet: w,
}
_, err = s.CreateAccount(ctx, &pb.CreateAccountRequest{})
require.NoError(t, err)
}
var (
defaultWalletPath = filepath.Join(flags.DefaultValidatorDir(), flags.WalletDefaultDirName)
testMnemonic = "tumble turn jewel sudden social great water general cabin jacket bounce dry flip monster advance problem social half flee inform century chicken hard reason"
)
func TestServer_ListAccounts(t *testing.T) {
ctx := context.Background()
@@ -74,9 +35,7 @@ func TestServer_ListAccounts(t *testing.T) {
SkipMnemonicConfirm: true,
})
require.NoError(t, err)
km, err := w.InitializeKeymanager(ctx, &iface.InitializeKeymanagerConfig{
SkipMnemonicConfirm: true,
})
km, err := w.InitializeKeymanager(ctx)
require.NoError(t, err)
s := &Server{
keymanager: km,
@@ -84,20 +43,15 @@ func TestServer_ListAccounts(t *testing.T) {
wallet: w,
}
numAccounts := 50
keys := make([][]byte, numAccounts)
for i := 0; i < numAccounts; i++ {
key, _, err := km.(*derived.Keymanager).CreateAccount(ctx)
require.NoError(t, err)
keys[i] = key
}
dr, ok := km.(*derived.Keymanager)
require.Equal(t, true, ok)
err = dr.RecoverAccountsFromMnemonic(ctx, testMnemonic, "", numAccounts)
require.NoError(t, err)
resp, err := s.ListAccounts(ctx, &pb.ListAccountsRequest{
PageSize: int32(numAccounts),
})
require.NoError(t, err)
require.Equal(t, len(resp.Accounts), numAccounts)
for i := 0; i < numAccounts; i++ {
assert.DeepEqual(t, resp.Accounts[i].ValidatingPublicKey, keys[i])
}
tests := []struct {
req *pb.ListAccountsRequest
@@ -131,36 +85,3 @@ func TestServer_ListAccounts(t *testing.T) {
assert.DeepEqual(t, res, test.res)
}
}
func Test_createAccountWithDepositData(t *testing.T) {
ctx := context.Background()
secretKey, err := bls.RandKey()
require.NoError(t, err)
pubKey := secretKey.PublicKey().Marshal()
m := &mockAccountCreator{
data: &ethpb.Deposit_Data{
PublicKey: pubKey,
WithdrawalCredentials: make([]byte, 32),
Amount: params.BeaconConfig().MaxEffectiveBalance,
Signature: make([]byte, 96),
},
pubKey: pubKey,
}
rawResp, err := createAccountWithDepositData(ctx, m)
require.NoError(t, err)
assert.DeepEqual(
t, rawResp.Data["pubkey"], fmt.Sprintf("%x", pubKey),
)
assert.DeepEqual(
t, rawResp.Data["withdrawal_credentials"], fmt.Sprintf("%x", make([]byte, 32)),
)
assert.DeepEqual(
t, rawResp.Data["amount"], fmt.Sprintf("%d", params.BeaconConfig().MaxEffectiveBalance),
)
assert.DeepEqual(
t, rawResp.Data["signature"], fmt.Sprintf("%x", make([]byte, 96)),
)
assert.DeepEqual(
t, rawResp.Data["fork_version"], fmt.Sprintf("%x", params.BeaconConfig().GenesisForkVersion),
)
}

View File

@@ -14,7 +14,6 @@ import (
pb "github.com/prysmaticlabs/prysm/proto/validator/accounts/v2"
"github.com/prysmaticlabs/prysm/shared/rand"
"github.com/prysmaticlabs/prysm/validator/accounts"
"github.com/prysmaticlabs/prysm/validator/accounts/iface"
"github.com/prysmaticlabs/prysm/validator/accounts/wallet"
"github.com/prysmaticlabs/prysm/validator/keymanager"
"github.com/prysmaticlabs/prysm/validator/keymanager/imported"
@@ -111,13 +110,12 @@ func (s *Server) CreateWallet(ctx context.Context, req *pb.CreateWalletRequest)
if req.Mnemonic == "" {
return nil, status.Error(codes.InvalidArgument, "Must include mnemonic in request")
}
_, depositData, err := accounts.RecoverWallet(ctx, &accounts.RecoverWalletConfig{
if _, err := accounts.RecoverWallet(ctx, &accounts.RecoverWalletConfig{
WalletDir: walletDir,
WalletPassword: req.WalletPassword,
Mnemonic: req.Mnemonic,
NumAccounts: int64(req.NumAccounts),
})
if err != nil {
NumAccounts: int(req.NumAccounts),
}); err != nil {
return nil, err
}
if err := s.initializeWallet(ctx, &wallet.Config{
@@ -128,24 +126,11 @@ func (s *Server) CreateWallet(ctx context.Context, req *pb.CreateWalletRequest)
return nil, err
}
depositDataList := make([]*pb.DepositDataResponse_DepositData, len(depositData))
for i, item := range depositData {
data, err := accounts.DepositDataJSON(item)
if err != nil {
return nil, err
}
depositDataList[i] = &pb.DepositDataResponse_DepositData{
Data: data,
}
}
return &pb.CreateWalletResponse{
Wallet: &pb.WalletResponse{
WalletPath: walletDir,
KeymanagerKind: pb.KeymanagerKind_DERIVED,
},
AccountsCreated: &pb.DepositDataResponse{
DepositDataList: depositDataList,
},
}, nil
case pb.KeymanagerKind_REMOTE:
return nil, status.Error(codes.Unimplemented, "Remote keymanager not yet supported")
@@ -335,9 +320,7 @@ func (s *Server) initializeWallet(ctx context.Context, cfg *wallet.Config) error
}
s.walletInitialized = true
km, err := w.InitializeKeymanager(ctx, &iface.InitializeKeymanagerConfig{
SkipMnemonicConfirm: true,
})
km, err := w.InitializeKeymanager(ctx)
if err != nil {
return errors.Wrap(err, "could not initialize keymanager")
}

View File

@@ -15,7 +15,6 @@ import (
"github.com/prysmaticlabs/prysm/shared/testutil/assert"
"github.com/prysmaticlabs/prysm/shared/testutil/require"
"github.com/prysmaticlabs/prysm/validator/accounts"
"github.com/prysmaticlabs/prysm/validator/accounts/iface"
"github.com/prysmaticlabs/prysm/validator/accounts/wallet"
"github.com/prysmaticlabs/prysm/validator/keymanager"
"github.com/prysmaticlabs/prysm/validator/keymanager/imported"
@@ -36,9 +35,7 @@ func createImportedWalletWithAccounts(t testing.TB, numAccounts int) (*Server, [
SkipMnemonicConfirm: true,
})
require.NoError(t, err)
km, err := w.InitializeKeymanager(ctx, &iface.InitializeKeymanagerConfig{
SkipMnemonicConfirm: true,
})
km, err := w.InitializeKeymanager(ctx)
require.NoError(t, err)
ss := &Server{
keymanager: km,
@@ -75,9 +72,7 @@ func createImportedWalletWithAccounts(t testing.TB, numAccounts int) (*Server, [
KeystoresPassword: strongPass,
})
require.NoError(t, err)
ss.keymanager, err = ss.wallet.InitializeKeymanager(ctx, &iface.InitializeKeymanagerConfig{
SkipMnemonicConfirm: true,
})
ss.keymanager, err = ss.wallet.InitializeKeymanager(ctx)
require.NoError(t, err)
return ss, pubKeys
}
@@ -198,9 +193,7 @@ func TestServer_WalletConfig(t *testing.T) {
SkipMnemonicConfirm: true,
})
require.NoError(t, err)
km, err := w.InitializeKeymanager(ctx, &iface.InitializeKeymanagerConfig{
SkipMnemonicConfirm: true,
})
km, err := w.InitializeKeymanager(ctx)
require.NoError(t, err)
s.wallet = w
s.keymanager = km
@@ -272,9 +265,7 @@ func TestServer_ImportKeystores_FailedPreconditions_WrongKeymanagerKind(t *testi
SkipMnemonicConfirm: true,
})
require.NoError(t, err)
km, err := w.InitializeKeymanager(ctx, &iface.InitializeKeymanagerConfig{
SkipMnemonicConfirm: true,
})
km, err := w.InitializeKeymanager(ctx)
require.NoError(t, err)
ss := &Server{
wallet: w,
@@ -298,9 +289,7 @@ func TestServer_ImportKeystores_FailedPreconditions(t *testing.T) {
SkipMnemonicConfirm: true,
})
require.NoError(t, err)
km, err := w.InitializeKeymanager(ctx, &iface.InitializeKeymanagerConfig{
SkipMnemonicConfirm: true,
})
km, err := w.InitializeKeymanager(ctx)
require.NoError(t, err)
ss := &Server{
keymanager: km,
@@ -336,9 +325,7 @@ func TestServer_ImportKeystores_OK(t *testing.T) {
SkipMnemonicConfirm: true,
})
require.NoError(t, err)
km, err := w.InitializeKeymanager(ctx, &iface.InitializeKeymanagerConfig{
SkipMnemonicConfirm: true,
})
km, err := w.InitializeKeymanager(ctx)
require.NoError(t, err)
ss := &Server{
keymanager: km,
@@ -386,9 +373,7 @@ func TestServer_ImportKeystores_OK(t *testing.T) {
ImportedPublicKeys: pubKeys,
}, res)
km, err = w.InitializeKeymanager(ctx, &iface.InitializeKeymanagerConfig{
SkipMnemonicConfirm: true,
})
km, err = w.InitializeKeymanager(ctx)
require.NoError(t, err)
keys, err = km.FetchValidatingPublicKeys(ctx)
require.NoError(t, err)