feat(x/accounts)!: make address generation more robust and add predictable address creation (backport #22776) (#22805)
Co-authored-by: testinginprod <98415576+testinginprod@users.noreply.github.com> Co-authored-by: Julien Robert <julien@rbrt.fr>
This commit is contained in:
parent
d65bc30bfd
commit
17c17b6287
@ -32,7 +32,7 @@ func TestBaseAccount(t *testing.T) {
|
||||
|
||||
_, baseAccountAddr, err := ak.Init(ctx, "base", accCreator, &baseaccountv1.MsgInit{
|
||||
PubKey: toAnyPb(t, privKey.PubKey()),
|
||||
}, nil)
|
||||
}, nil, nil)
|
||||
require.NoError(t, err)
|
||||
|
||||
// fund base account! this will also cause an auth base account to be created
|
||||
|
||||
@ -185,7 +185,7 @@ func initFixture(t *testing.T, f func(ctx context.Context, msg *account_abstract
|
||||
banktypes.RegisterMsgServer(router, bankkeeper.NewMsgServerImpl(bankKeeper))
|
||||
|
||||
// init account
|
||||
_, addr, err := accountsKeeper.Init(integrationApp.Context(), "mock", []byte("system"), &gogotypes.Empty{}, nil)
|
||||
_, addr, err := accountsKeeper.Init(integrationApp.Context(), "mock", []byte("system"), &gogotypes.Empty{}, nil, nil)
|
||||
require.NoError(t, err)
|
||||
|
||||
fixture := &fixture{
|
||||
|
||||
@ -34,7 +34,7 @@ func (s *IntegrationTestSuite) TestContinuousLockingAccount() {
|
||||
StartTime: currentTime,
|
||||
// end time in 1 minutes
|
||||
EndTime: currentTime.Add(time.Minute),
|
||||
}, sdk.Coins{sdk.NewCoin("stake", math.NewInt(1000))})
|
||||
}, sdk.Coins{sdk.NewCoin("stake", math.NewInt(1000))}, nil)
|
||||
require.NoError(t, err)
|
||||
|
||||
addr, err := app.AuthKeeper.AddressCodec().BytesToString(randAcc)
|
||||
|
||||
@ -33,7 +33,7 @@ func (s *IntegrationTestSuite) TestDelayedLockingAccount() {
|
||||
Owner: ownerAddrStr,
|
||||
// end time in 1 minutes
|
||||
EndTime: currentTime.Add(time.Minute),
|
||||
}, sdk.Coins{sdk.NewCoin("stake", math.NewInt(1000))})
|
||||
}, sdk.Coins{sdk.NewCoin("stake", math.NewInt(1000))}, nil)
|
||||
require.NoError(t, err)
|
||||
|
||||
addr, err := app.AuthKeeper.AddressCodec().BytesToString(randAcc)
|
||||
|
||||
@ -47,7 +47,7 @@ func (s *IntegrationTestSuite) TestPeriodicLockingAccount() {
|
||||
Length: time.Minute,
|
||||
},
|
||||
},
|
||||
}, sdk.Coins{sdk.NewCoin("stake", math.NewInt(1500))})
|
||||
}, sdk.Coins{sdk.NewCoin("stake", math.NewInt(1500))}, nil)
|
||||
require.NoError(t, err)
|
||||
|
||||
addr, err := app.AuthKeeper.AddressCodec().BytesToString(randAcc)
|
||||
|
||||
@ -30,7 +30,7 @@ func (s *IntegrationTestSuite) TestPermanentLockingAccount() {
|
||||
|
||||
_, accountAddr, err := app.AccountsKeeper.Init(ctx, lockupaccount.PERMANENT_LOCKING_ACCOUNT, accOwner, &types.MsgInitLockupAccount{
|
||||
Owner: ownerAddrStr,
|
||||
}, sdk.Coins{sdk.NewCoin("stake", math.NewInt(1000))})
|
||||
}, sdk.Coins{sdk.NewCoin("stake", math.NewInt(1000))}, nil)
|
||||
require.NoError(t, err)
|
||||
|
||||
addr, err := app.AuthKeeper.AddressCodec().BytesToString(randAcc)
|
||||
|
||||
@ -85,7 +85,7 @@ func (s *IntegrationTestSuite) initAccount(ctx context.Context, sender []byte, m
|
||||
Revote: false,
|
||||
EarlyExecution: true,
|
||||
},
|
||||
}, sdk.Coins{sdk.NewCoin("stake", math.NewInt(1000))})
|
||||
}, sdk.Coins{sdk.NewCoin("stake", math.NewInt(1000))}, nil)
|
||||
s.NoError(err)
|
||||
|
||||
accountAddrStr, err := s.app.AuthKeeper.AddressCodec().BytesToString(accountAddr)
|
||||
|
||||
@ -28,7 +28,7 @@ func TestDependencies(t *testing.T) {
|
||||
|
||||
_, counterAddr, err := ak.Init(ctx, "counter", accCreator, &counterv1.MsgInit{
|
||||
InitialValue: 0,
|
||||
}, nil)
|
||||
}, nil, nil)
|
||||
require.NoError(t, err)
|
||||
// test dependencies
|
||||
creatorInitFunds := sdk.NewCoins(sdk.NewInt64Coin("stake", 100_000))
|
||||
|
||||
@ -74,7 +74,7 @@ func TestAuthToAccountsGRPCCompat(t *testing.T) {
|
||||
|
||||
// init three accounts
|
||||
for n, a := range accs {
|
||||
_, addr, err := f.accountsKeeper.Init(f.app.Context(), n, []byte("me"), &gogotypes.Empty{}, nil)
|
||||
_, addr, err := f.accountsKeeper.Init(f.app.Context(), n, []byte("me"), &gogotypes.Empty{}, nil, nil)
|
||||
require.NoError(t, err)
|
||||
a.(*mockRetroCompatAccount).address = addr
|
||||
}
|
||||
@ -132,10 +132,10 @@ func TestAccountsBaseAccountRetroCompat(t *testing.T) {
|
||||
require.NoError(t, err)
|
||||
|
||||
// we init two accounts to have account num not be zero.
|
||||
_, _, err = f.accountsKeeper.Init(f.app.Context(), "base", []byte("me"), &basev1.MsgInit{PubKey: anyPk}, nil)
|
||||
_, _, err = f.accountsKeeper.Init(f.app.Context(), "base", []byte("me"), &basev1.MsgInit{PubKey: anyPk}, nil, nil)
|
||||
require.NoError(t, err)
|
||||
|
||||
_, addr, err := f.accountsKeeper.Init(f.app.Context(), "base", []byte("me"), &basev1.MsgInit{PubKey: anyPk}, nil)
|
||||
_, addr, err := f.accountsKeeper.Init(f.app.Context(), "base", []byte("me"), &basev1.MsgInit{PubKey: anyPk}, nil, nil)
|
||||
require.NoError(t, err)
|
||||
|
||||
// try to query it via auth
|
||||
|
||||
@ -496,6 +496,32 @@ func (a Account) AuthRetroCompatibility(ctx context.Context, _ *authtypes.QueryL
|
||||
* Implement this handler only for account types you want to expose via x/auth gRPC methods.
|
||||
* The `info` field in the response can be nil if your account doesn't fit the `BaseAccount` structure.
|
||||
|
||||
## Address Derivation
|
||||
|
||||
The x/accounts module offers two methods for deriving addresses, both ensuring non-squattability. This means each address is uniquely tied to its creator, preventing address collisions between different creators (e.g., Alice cannot create addresses that would conflict with Bob's addresses).
|
||||
|
||||
### Method 1: Using Address Seeds
|
||||
|
||||
When creating an account via `MsgInit`, you can provide an `address_seed`. The address is derived using:
|
||||
|
||||
```bash
|
||||
address = sha256(ModuleName || address_seed || creator_address)
|
||||
```
|
||||
|
||||
### Method 2: Using Account Numbers
|
||||
If no address seed is provided, the address is derived using:
|
||||
|
||||
```
|
||||
address = sha256(ModuleName || creator_address || next_account_number)
|
||||
```
|
||||
|
||||
### Address Seed Best Practices
|
||||
|
||||
1. Address seeds must be unique per creator (not globally unique)
|
||||
2. Reusing an address seed will cause account creation to fail
|
||||
3. For programmatic account creation, use an incrementing sequence number as the address seed
|
||||
4. This is particularly useful for contracts or modules that need deterministic address generation
|
||||
|
||||
## Genesis
|
||||
|
||||
### Creating accounts on genesis
|
||||
|
||||
@ -10,4 +10,6 @@ var (
|
||||
ErrBundlerPayment = errors.New(ModuleName, 2, "bundler payment failed")
|
||||
// ErrExecution is returned when the execution fails.
|
||||
ErrExecution = errors.New(ModuleName, 3, "execution failed")
|
||||
// ErrAccountAlreadyExists is returned when the account already exists in state.
|
||||
ErrAccountAlreadyExists = errors.New(ModuleName, 4, "account already exists")
|
||||
)
|
||||
|
||||
@ -19,13 +19,13 @@ func TestGenesis(t *testing.T) {
|
||||
// we init two accounts of the same type
|
||||
|
||||
// we set counter to 10
|
||||
_, addr1, err := k.Init(ctx, testAccountType, []byte("sender"), &types.Empty{}, nil)
|
||||
_, addr1, err := k.Init(ctx, testAccountType, []byte("sender"), &types.Empty{}, nil, nil)
|
||||
require.NoError(t, err)
|
||||
_, err = k.Execute(ctx, addr1, []byte("sender"), &types.UInt64Value{Value: 10}, nil)
|
||||
require.NoError(t, err)
|
||||
|
||||
// we set counter to 20
|
||||
_, addr2, err := k.Init(ctx, testAccountType, []byte("sender"), &types.Empty{}, nil)
|
||||
_, addr2, err := k.Init(ctx, testAccountType, []byte("sender"), &types.Empty{}, nil, nil)
|
||||
require.NoError(t, err)
|
||||
_, err = k.Execute(ctx, addr2, []byte("sender"), &types.UInt64Value{Value: 20}, nil)
|
||||
require.NoError(t, err)
|
||||
@ -62,7 +62,7 @@ func TestGenesis(t *testing.T) {
|
||||
require.Equal(t, &types.UInt64Value{Value: 20}, resp)
|
||||
|
||||
// check initted on genesis account
|
||||
addr3, err := k.makeAddress(2)
|
||||
addr3, err := k.makeAddress([]byte("sender-2"), 2, nil)
|
||||
require.NoError(t, err)
|
||||
resp, err = k.Query(ctx, addr3, &types.DoubleValue{})
|
||||
require.NoError(t, err)
|
||||
|
||||
@ -148,6 +148,7 @@ func (k Keeper) Init(
|
||||
creator []byte,
|
||||
initRequest transaction.Msg,
|
||||
funds sdk.Coins,
|
||||
addressSeed []byte,
|
||||
) (transaction.Msg, []byte, error) {
|
||||
// get the next account number
|
||||
num, err := k.AccountNumber.Next(ctx)
|
||||
@ -155,7 +156,7 @@ func (k Keeper) Init(
|
||||
return nil, nil, err
|
||||
}
|
||||
// create address
|
||||
accountAddr, err := k.makeAddress(num)
|
||||
accountAddr, err := k.makeAddress(creator, num, addressSeed)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
@ -180,7 +181,7 @@ func (k Keeper) initFromMsg(ctx context.Context, initMsg *v1.MsgInit) (transacti
|
||||
}
|
||||
|
||||
// run account creation logic
|
||||
return k.Init(ctx, initMsg.AccountType, creator, msg, initMsg.Funds)
|
||||
return k.Init(ctx, initMsg.AccountType, creator, msg, initMsg.Funds, initMsg.AddressSeed)
|
||||
}
|
||||
|
||||
// init initializes the account, given the type, the creator the newly created account number, its address and the
|
||||
@ -199,8 +200,17 @@ func (k Keeper) init(
|
||||
return nil, fmt.Errorf("%w: not found %s", errAccountTypeNotFound, accountType)
|
||||
}
|
||||
|
||||
// check if account exists
|
||||
alreadyExists, err := k.AccountsByType.Has(ctx, accountAddr)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if alreadyExists {
|
||||
return nil, ErrAccountAlreadyExists
|
||||
}
|
||||
|
||||
// send funds, if provided
|
||||
err := k.maybeSendFunds(ctx, creator, accountAddr, funds)
|
||||
err = k.maybeSendFunds(ctx, creator, accountAddr, funds)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("unable to transfer funds: %w", err)
|
||||
}
|
||||
@ -307,9 +317,26 @@ func (k Keeper) getImplementation(ctx context.Context, addr []byte) (implementat
|
||||
return impl, nil
|
||||
}
|
||||
|
||||
func (k Keeper) makeAddress(accNum uint64) ([]byte, error) {
|
||||
// TODO: better address scheme, ref: https://github.com/cosmos/cosmos-sdk/issues/17516
|
||||
addr := sha256.Sum256(append([]byte("x/accounts"), binary.BigEndian.AppendUint64(nil, accNum)...))
|
||||
// makeAddress creates an address for the given account.
|
||||
// It uses the creator address to ensure address squatting cannot happen, for example
|
||||
// assuming creator sends funds to a new account X nobody can front-run that address instantiation
|
||||
// unless the creator itself sends the tx.
|
||||
// AddressSeed can be used to create predictable addresses, security guarantees of the above are retained.
|
||||
// If address seed is not provided, the address is created using the creator and account number.
|
||||
func (k Keeper) makeAddress(creator []byte, accNum uint64, addressSeed []byte) ([]byte, error) {
|
||||
// in case an address seed is provided, we use it to create the address.
|
||||
var seed []byte
|
||||
if len(addressSeed) > 0 {
|
||||
seed = append(creator, addressSeed...)
|
||||
} else {
|
||||
// otherwise we use the creator and account number to create the address.
|
||||
seed = append(creator, binary.BigEndian.AppendUint64(nil, accNum)...)
|
||||
}
|
||||
|
||||
moduleAndSeed := append([]byte(ModuleName), seed...)
|
||||
|
||||
addr := sha256.Sum256(moduleAndSeed)
|
||||
|
||||
return addr[:], nil
|
||||
}
|
||||
|
||||
|
||||
@ -17,7 +17,7 @@ func TestKeeper_Init(t *testing.T) {
|
||||
t.Run("ok", func(t *testing.T) {
|
||||
sender := []byte("sender")
|
||||
|
||||
resp, addr, err := m.Init(ctx, "test", sender, &types.Empty{}, nil)
|
||||
resp, addr, err := m.Init(ctx, "test", sender, &types.Empty{}, nil, nil)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, &types.Empty{}, resp)
|
||||
require.NotNil(t, addr)
|
||||
@ -34,7 +34,7 @@ func TestKeeper_Init(t *testing.T) {
|
||||
})
|
||||
|
||||
t.Run("unknown account type", func(t *testing.T) {
|
||||
_, _, err := m.Init(ctx, "unknown", []byte("sender"), &types.Empty{}, nil)
|
||||
_, _, err := m.Init(ctx, "unknown", []byte("sender"), &types.Empty{}, nil, nil)
|
||||
require.ErrorIs(t, err, errAccountTypeNotFound)
|
||||
})
|
||||
}
|
||||
@ -44,7 +44,7 @@ func TestKeeper_Execute(t *testing.T) {
|
||||
|
||||
// create account
|
||||
sender := []byte("sender")
|
||||
_, accAddr, err := m.Init(ctx, "test", sender, &types.Empty{}, nil)
|
||||
_, accAddr, err := m.Init(ctx, "test", sender, &types.Empty{}, nil, nil)
|
||||
require.NoError(t, err)
|
||||
|
||||
t.Run("ok", func(t *testing.T) {
|
||||
@ -70,7 +70,7 @@ func TestKeeper_Query(t *testing.T) {
|
||||
|
||||
// create account
|
||||
sender := []byte("sender")
|
||||
_, accAddr, err := m.Init(ctx, "test", sender, &types.Empty{}, nil)
|
||||
_, accAddr, err := m.Init(ctx, "test", sender, &types.Empty{}, nil, nil)
|
||||
require.NoError(t, err)
|
||||
|
||||
t.Run("ok", func(t *testing.T) {
|
||||
|
||||
@ -24,24 +24,46 @@ func TestMsgServer(t *testing.T) {
|
||||
Sender: "sender",
|
||||
AccountType: "test",
|
||||
Message: initMsg,
|
||||
AddressSeed: []byte("seed"),
|
||||
})
|
||||
require.NoError(t, err)
|
||||
require.NotNil(t, initResp)
|
||||
|
||||
// execute
|
||||
executeMsg := &wrapperspb.StringValue{
|
||||
Value: "10",
|
||||
}
|
||||
executeMsgAny, err := implementation.PackAny(executeMsg)
|
||||
require.NoError(t, err)
|
||||
t.Run("success", func(t *testing.T) {
|
||||
// execute
|
||||
executeMsg := &wrapperspb.StringValue{
|
||||
Value: "10",
|
||||
}
|
||||
executeMsgAny, err := implementation.PackAny(executeMsg)
|
||||
require.NoError(t, err)
|
||||
|
||||
execResp, err := s.Execute(ctx, &v1.MsgExecute{
|
||||
Sender: "sender",
|
||||
Target: initResp.AccountAddress,
|
||||
Message: executeMsgAny,
|
||||
execResp, err := s.Execute(ctx, &v1.MsgExecute{
|
||||
Sender: "sender",
|
||||
Target: initResp.AccountAddress,
|
||||
Message: executeMsgAny,
|
||||
})
|
||||
require.NoError(t, err)
|
||||
require.NotNil(t, execResp)
|
||||
})
|
||||
|
||||
t.Run("fail initting same account twice", func(t *testing.T) {
|
||||
_, err := s.Init(ctx, &v1.MsgInit{
|
||||
Sender: "sender",
|
||||
AccountType: "test",
|
||||
Message: initMsg,
|
||||
AddressSeed: []byte("seed"),
|
||||
})
|
||||
require.ErrorIs(t, err, ErrAccountAlreadyExists)
|
||||
})
|
||||
|
||||
t.Run("initting without seed", func(t *testing.T) {
|
||||
_, err := s.Init(ctx, &v1.MsgInit{
|
||||
Sender: "sender",
|
||||
AccountType: "test",
|
||||
Message: initMsg,
|
||||
})
|
||||
require.NoError(t, err)
|
||||
})
|
||||
require.NoError(t, err)
|
||||
require.NotNil(t, execResp)
|
||||
}
|
||||
|
||||
func TestMsgServer_BundlingDisabled(t *testing.T) {
|
||||
|
||||
@ -39,6 +39,9 @@ message MsgInit {
|
||||
// send alongside the request.
|
||||
repeated cosmos.base.v1beta1.Coin funds = 4
|
||||
[(gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins", (gogoproto.nullable) = false];
|
||||
// address_seed can be used to deterministically create the address of the account.
|
||||
// If not present the address will be generated based on its associated account number.
|
||||
bytes address_seed = 5;
|
||||
}
|
||||
|
||||
// MsgInitResponse defines the Create response type for the Msg/Create RPC method.
|
||||
|
||||
@ -44,6 +44,9 @@ type MsgInit struct {
|
||||
// funds contains the coins that the account wants to
|
||||
// send alongside the request.
|
||||
Funds github_com_cosmos_cosmos_sdk_types.Coins `protobuf:"bytes,4,rep,name=funds,proto3,castrepeated=github.com/cosmos/cosmos-sdk/types.Coins" json:"funds"`
|
||||
// address_seed can be used to deterministically create the address of the account.
|
||||
// If not present the address will be generated based on its associated account number.
|
||||
AddressSeed []byte `protobuf:"bytes,5,opt,name=address_seed,json=addressSeed,proto3" json:"address_seed,omitempty"`
|
||||
}
|
||||
|
||||
func (m *MsgInit) Reset() { *m = MsgInit{} }
|
||||
@ -107,6 +110,13 @@ func (m *MsgInit) GetFunds() github_com_cosmos_cosmos_sdk_types.Coins {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *MsgInit) GetAddressSeed() []byte {
|
||||
if m != nil {
|
||||
return m.AddressSeed
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// MsgInitResponse defines the Create response type for the Msg/Create RPC method.
|
||||
type MsgInitResponse struct {
|
||||
// account_address is the address of the newly created account.
|
||||
@ -496,51 +506,52 @@ func init() {
|
||||
func init() { proto.RegisterFile("cosmos/accounts/v1/tx.proto", fileDescriptor_29c2b6d8a13d4189) }
|
||||
|
||||
var fileDescriptor_29c2b6d8a13d4189 = []byte{
|
||||
// 690 bytes of a gzipped FileDescriptorProto
|
||||
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xcc, 0x55, 0xcb, 0x4e, 0xdb, 0x4c,
|
||||
0x14, 0x8e, 0x73, 0xfd, 0x39, 0xe1, 0x2f, 0x74, 0x4a, 0xc1, 0x18, 0xc9, 0xa4, 0xe9, 0x2d, 0x42,
|
||||
0xd4, 0x26, 0xb4, 0x6a, 0x25, 0x76, 0x80, 0xe8, 0x45, 0x2a, 0x12, 0x8d, 0xe8, 0xa6, 0x9b, 0xc8,
|
||||
0xb1, 0x07, 0x13, 0x41, 0x3c, 0x91, 0xcf, 0x18, 0x25, 0xbb, 0xaa, 0x0f, 0x50, 0xf5, 0x39, 0xba,
|
||||
0xe2, 0x31, 0x58, 0xb2, 0xec, 0xa2, 0xea, 0x05, 0x2a, 0xf1, 0x1a, 0x55, 0xc6, 0x33, 0x36, 0xe1,
|
||||
0x12, 0xb1, 0xec, 0x2a, 0x33, 0xf3, 0x9d, 0xf3, 0x9d, 0xf3, 0x7d, 0x27, 0x33, 0x86, 0x39, 0x97,
|
||||
0x61, 0x87, 0xa1, 0xed, 0xb8, 0x2e, 0x8b, 0x02, 0x8e, 0xf6, 0x41, 0xdd, 0xe6, 0x3d, 0xab, 0x1b,
|
||||
0x32, 0xce, 0x08, 0x89, 0x41, 0x4b, 0x81, 0xd6, 0x41, 0xdd, 0x98, 0xf5, 0x19, 0xf3, 0xf7, 0xa9,
|
||||
0x2d, 0x22, 0x5a, 0xd1, 0x8e, 0xed, 0x04, 0xfd, 0x38, 0xdc, 0x98, 0x91, 0x5c, 0x1d, 0xf4, 0x07,
|
||||
0x34, 0x1d, 0xf4, 0x25, 0x60, 0x4a, 0xa0, 0xe5, 0x20, 0xb5, 0x0f, 0xea, 0x2d, 0xca, 0x9d, 0xba,
|
||||
0xed, 0xb2, 0x76, 0x20, 0x71, 0x43, 0xe2, 0xbc, 0x97, 0xa0, 0xaa, 0x07, 0x63, 0xca, 0x67, 0x3e,
|
||||
0x13, 0x4b, 0x7b, 0xb0, 0x8a, 0x4f, 0xab, 0x7f, 0x34, 0x28, 0x6d, 0xa2, 0xff, 0x26, 0x68, 0x73,
|
||||
0x32, 0x0d, 0x45, 0xa4, 0x81, 0x47, 0x43, 0x5d, 0xab, 0x68, 0xb5, 0xb1, 0x86, 0xdc, 0x91, 0x7b,
|
||||
0x30, 0x2e, 0x1b, 0x6f, 0xf2, 0x7e, 0x97, 0xea, 0x59, 0x81, 0x96, 0xe5, 0xd9, 0x76, 0xbf, 0x4b,
|
||||
0x89, 0x05, 0xa5, 0x0e, 0x45, 0x74, 0x7c, 0xaa, 0xe7, 0x2a, 0x5a, 0xad, 0xbc, 0x3c, 0x65, 0xc5,
|
||||
0xf2, 0x2c, 0x25, 0xcf, 0x5a, 0x0d, 0xfa, 0x0d, 0x15, 0x44, 0x1c, 0x28, 0xec, 0x44, 0x81, 0x87,
|
||||
0x7a, 0xbe, 0x92, 0xab, 0x95, 0x97, 0x67, 0x2d, 0x69, 0xd0, 0x40, 0x98, 0x25, 0x5b, 0xb7, 0xd6,
|
||||
0x59, 0x3b, 0x58, 0x5b, 0x3a, 0xfa, 0x31, 0x9f, 0xf9, 0xfa, 0x73, 0xbe, 0xe6, 0xb7, 0xf9, 0x6e,
|
||||
0xd4, 0xb2, 0x5c, 0xd6, 0xb1, 0xa5, 0xca, 0xf8, 0xe7, 0x09, 0x7a, 0x7b, 0xf6, 0xa0, 0x2f, 0x14,
|
||||
0x09, 0xd8, 0x88, 0x99, 0x57, 0xca, 0x9f, 0xce, 0x0e, 0x17, 0xa4, 0x84, 0xea, 0x3e, 0x4c, 0x48,
|
||||
0x95, 0x0d, 0x8a, 0x5d, 0x16, 0x20, 0x25, 0x8f, 0x61, 0x42, 0xa9, 0x72, 0x3c, 0x2f, 0xa4, 0x88,
|
||||
0x52, 0xf6, 0x2d, 0x79, 0xbc, 0x1a, 0x9f, 0x92, 0x25, 0xf8, 0x2f, 0x94, 0x49, 0x42, 0xfa, 0x75,
|
||||
0xe2, 0x92, 0xa8, 0xea, 0x77, 0x0d, 0x60, 0x13, 0xfd, 0x8d, 0x1e, 0x75, 0x23, 0x4e, 0xaf, 0xf5,
|
||||
0x75, 0x1a, 0x8a, 0xdc, 0x09, 0x7d, 0xca, 0xa5, 0xa3, 0x72, 0xf7, 0xcf, 0x9b, 0xf9, 0x12, 0x48,
|
||||
0xaa, 0x2e, 0xf1, 0xf3, 0xbc, 0x4d, 0xda, 0x8d, 0x6c, 0x7a, 0x0b, 0x93, 0x29, 0xcf, 0x5a, 0x14,
|
||||
0x78, 0xfb, 0x94, 0xe8, 0x50, 0x6a, 0x89, 0x95, 0x32, 0x4b, 0x6d, 0xc9, 0x24, 0xe4, 0x78, 0x0f,
|
||||
0xf5, 0x6c, 0x25, 0x57, 0x1b, 0x6f, 0x0c, 0x96, 0x2b, 0xe3, 0x83, 0xa6, 0x14, 0x5e, 0xfd, 0x9d,
|
||||
0x85, 0xdb, 0x31, 0x89, 0xb7, 0xdd, 0x4b, 0xba, 0x7a, 0x0e, 0x33, 0x4e, 0xc4, 0x77, 0x69, 0xc0,
|
||||
0xdb, 0xae, 0xc3, 0xdb, 0x2c, 0x68, 0xfa, 0x0e, 0x36, 0x23, 0xa4, 0x9e, 0xe0, 0xcf, 0x37, 0xee,
|
||||
0x0e, 0xc3, 0xaf, 0x1c, 0x7c, 0x8f, 0xd4, 0x23, 0x2f, 0x40, 0x97, 0xc4, 0xcd, 0xae, 0xd3, 0xef,
|
||||
0xd0, 0x80, 0xa7, 0x89, 0xd9, 0x38, 0x51, 0xe2, 0x5b, 0x31, 0xac, 0x12, 0xb7, 0x60, 0xf6, 0x62,
|
||||
0xa2, 0x12, 0x8c, 0x7a, 0x4e, 0x0c, 0xe8, 0x6a, 0x5f, 0x66, 0x86, 0xf9, 0x94, 0x02, 0x24, 0x8b,
|
||||
0x40, 0xa8, 0xf0, 0x68, 0xa8, 0xfb, 0xbc, 0x68, 0x62, 0x32, 0x41, 0x54, 0xfd, 0x0d, 0xb8, 0x93,
|
||||
0x46, 0xa7, 0x95, 0x0b, 0x23, 0x2a, 0xa7, 0xf4, 0x69, 0xd1, 0x29, 0x28, 0xd0, 0x30, 0x64, 0xa1,
|
||||
0x5e, 0x14, 0x53, 0x88, 0x37, 0xd5, 0x26, 0xe8, 0x17, 0x27, 0x96, 0x38, 0xbd, 0x0e, 0x63, 0x69,
|
||||
0x39, 0x4d, 0x94, 0x7b, 0x68, 0x5d, 0x7e, 0xf7, 0xac, 0x4b, 0x33, 0x6a, 0xa4, 0x79, 0xcb, 0x9f,
|
||||
0xb3, 0x90, 0xdb, 0x44, 0x9f, 0xbc, 0x86, 0xbc, 0x78, 0x92, 0xe6, 0xae, 0x62, 0x90, 0x37, 0xd9,
|
||||
0xb8, 0x3f, 0x02, 0x4c, 0xda, 0x7a, 0x07, 0x25, 0x75, 0x0f, 0xcd, 0x6b, 0xe2, 0x25, 0x6e, 0x3c,
|
||||
0x1a, 0x8d, 0x27, 0x94, 0x2e, 0xfc, 0x3f, 0xfc, 0xa7, 0x7d, 0x30, 0x3a, 0x31, 0x8e, 0x32, 0x16,
|
||||
0x6f, 0x12, 0xa5, 0x8a, 0x18, 0x85, 0x8f, 0x67, 0x87, 0x0b, 0xda, 0xda, 0xb3, 0xa3, 0x13, 0x53,
|
||||
0x3b, 0x3e, 0x31, 0xb5, 0x5f, 0x27, 0xa6, 0xf6, 0xe5, 0xd4, 0xcc, 0x1c, 0x9f, 0x9a, 0x99, 0x6f,
|
||||
0xa7, 0x66, 0xe6, 0x83, 0x7c, 0xeb, 0xd1, 0xdb, 0xb3, 0xda, 0xcc, 0xee, 0x9d, 0xff, 0xf0, 0xb4,
|
||||
0x8a, 0x62, 0xbe, 0x4f, 0xff, 0x06, 0x00, 0x00, 0xff, 0xff, 0x15, 0x7e, 0x1c, 0x2a, 0x95, 0x06,
|
||||
0x00, 0x00,
|
||||
// 709 bytes of a gzipped FileDescriptorProto
|
||||
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xcc, 0x55, 0xcb, 0x4e, 0xdb, 0x40,
|
||||
0x14, 0x8d, 0xf3, 0x2c, 0x37, 0x69, 0xa1, 0x53, 0x0a, 0xc6, 0x48, 0x26, 0x4d, 0x5f, 0x11, 0xa2,
|
||||
0x36, 0xa1, 0x55, 0x2b, 0xb1, 0x03, 0x44, 0x1f, 0x52, 0x91, 0xa8, 0x4b, 0x37, 0xdd, 0x44, 0x8e,
|
||||
0x3d, 0x98, 0x08, 0xe2, 0x89, 0x7c, 0xc7, 0x28, 0xd9, 0x55, 0xdd, 0x74, 0x57, 0xf5, 0x3b, 0xba,
|
||||
0xe2, 0x33, 0x58, 0xb2, 0xec, 0xa2, 0xea, 0x03, 0x16, 0xfc, 0x46, 0x95, 0xf1, 0xd8, 0x26, 0x3c,
|
||||
0x22, 0x96, 0x5d, 0x65, 0x66, 0xce, 0xbd, 0xe7, 0x9e, 0x73, 0x26, 0xb6, 0x61, 0xd6, 0x61, 0xd8,
|
||||
0x61, 0x68, 0xda, 0x8e, 0xc3, 0x42, 0x9f, 0xa3, 0xb9, 0xdf, 0x30, 0x79, 0xcf, 0xe8, 0x06, 0x8c,
|
||||
0x33, 0x42, 0x22, 0xd0, 0x88, 0x41, 0x63, 0xbf, 0xa1, 0xcd, 0x78, 0x8c, 0x79, 0x7b, 0xd4, 0x14,
|
||||
0x15, 0xad, 0x70, 0xdb, 0xb4, 0xfd, 0x7e, 0x54, 0xae, 0x4d, 0x4b, 0xae, 0x0e, 0x7a, 0x03, 0x9a,
|
||||
0x0e, 0x7a, 0x12, 0xd0, 0x25, 0xd0, 0xb2, 0x91, 0x9a, 0xfb, 0x8d, 0x16, 0xe5, 0x76, 0xc3, 0x74,
|
||||
0x58, 0xdb, 0x97, 0xb8, 0x26, 0x71, 0xde, 0x4b, 0xd0, 0x58, 0x83, 0x36, 0xe9, 0x31, 0x8f, 0x89,
|
||||
0xa5, 0x39, 0x58, 0x45, 0xa7, 0xb5, 0x2f, 0x59, 0x28, 0x6d, 0xa0, 0xf7, 0xc6, 0x6f, 0x73, 0x32,
|
||||
0x05, 0x45, 0xa4, 0xbe, 0x4b, 0x03, 0x55, 0xa9, 0x2a, 0xf5, 0x31, 0x4b, 0xee, 0xc8, 0x3d, 0xa8,
|
||||
0x48, 0xe1, 0x4d, 0xde, 0xef, 0x52, 0x35, 0x2b, 0xd0, 0xb2, 0x3c, 0xdb, 0xea, 0x77, 0x29, 0x31,
|
||||
0xa0, 0xd4, 0xa1, 0x88, 0xb6, 0x47, 0xd5, 0x5c, 0x55, 0xa9, 0x97, 0x97, 0x26, 0x8d, 0xc8, 0x9e,
|
||||
0x11, 0xdb, 0x33, 0x56, 0xfc, 0xbe, 0x15, 0x17, 0x11, 0x1b, 0x0a, 0xdb, 0xa1, 0xef, 0xa2, 0x9a,
|
||||
0xaf, 0xe6, 0xea, 0xe5, 0xa5, 0x19, 0x43, 0x06, 0x34, 0x30, 0x66, 0x48, 0xe9, 0xc6, 0x1a, 0x6b,
|
||||
0xfb, 0xab, 0x8b, 0x87, 0xbf, 0xe6, 0x32, 0xdf, 0x7f, 0xcf, 0xd5, 0xbd, 0x36, 0xdf, 0x09, 0x5b,
|
||||
0x86, 0xc3, 0x3a, 0xa6, 0x74, 0x19, 0xfd, 0x3c, 0x41, 0x77, 0xd7, 0x1c, 0xe8, 0x42, 0xd1, 0x80,
|
||||
0x56, 0xc4, 0x2c, 0x54, 0xbb, 0x6e, 0x40, 0x11, 0x9b, 0x48, 0xa9, 0xab, 0x16, 0xaa, 0x4a, 0xbd,
|
||||
0x62, 0x95, 0xe5, 0xd9, 0x7b, 0x4a, 0xdd, 0xe5, 0xf2, 0xe7, 0xd3, 0x83, 0x79, 0xe9, 0xb2, 0xb6,
|
||||
0x07, 0xe3, 0x32, 0x08, 0x8b, 0x62, 0x97, 0xf9, 0x48, 0xc9, 0x63, 0x18, 0x8f, 0x8d, 0xcb, 0x36,
|
||||
0x99, 0xcc, 0x2d, 0x79, 0xbc, 0x12, 0x9d, 0x92, 0x45, 0xb8, 0x11, 0xc8, 0x26, 0x91, 0xce, 0x55,
|
||||
0xfe, 0x93, 0xaa, 0xda, 0x4f, 0x05, 0x60, 0x03, 0xbd, 0xf5, 0x1e, 0x75, 0x42, 0x4e, 0xaf, 0x8c,
|
||||
0x7e, 0x0a, 0x8a, 0xdc, 0x0e, 0x3c, 0xca, 0x65, 0xe8, 0x72, 0xf7, 0x1f, 0xe6, 0x3d, 0x1c, 0xe6,
|
||||
0x4b, 0x20, 0xa9, 0xbb, 0x24, 0xcf, 0xb3, 0x31, 0x29, 0xd7, 0x8a, 0xe9, 0x2d, 0x4c, 0xa4, 0x3c,
|
||||
0xab, 0xa1, 0xef, 0xee, 0x51, 0xa2, 0x42, 0xa9, 0x25, 0x56, 0x71, 0x58, 0xf1, 0x96, 0x4c, 0x40,
|
||||
0x8e, 0xf7, 0x50, 0xcd, 0x56, 0x73, 0xf5, 0x8a, 0x35, 0x58, 0x2e, 0x57, 0x06, 0xa2, 0x62, 0xbc,
|
||||
0xf6, 0x37, 0x0b, 0xb7, 0x23, 0x12, 0x77, 0xab, 0x97, 0xa8, 0x7a, 0x0e, 0xd3, 0x76, 0xc8, 0x77,
|
||||
0xa8, 0xcf, 0xdb, 0x8e, 0xcd, 0xdb, 0xcc, 0x6f, 0x7a, 0x36, 0x36, 0x43, 0xa4, 0xae, 0xe0, 0xcf,
|
||||
0x5b, 0x77, 0x87, 0xe1, 0x57, 0x36, 0x7e, 0x40, 0xea, 0x92, 0x17, 0xa0, 0x4a, 0xe2, 0x66, 0xd7,
|
||||
0xee, 0x77, 0xa8, 0xcf, 0xd3, 0xc6, 0x6c, 0xd4, 0x28, 0xf1, 0xcd, 0x08, 0x8e, 0x1b, 0x37, 0x61,
|
||||
0xe6, 0x7c, 0x63, 0x6c, 0x18, 0xd5, 0x9c, 0xb8, 0xa0, 0xcb, 0x73, 0x99, 0x1e, 0xe6, 0x8b, 0x1d,
|
||||
0x20, 0x59, 0x00, 0x42, 0x45, 0x46, 0x43, 0xea, 0xf3, 0x42, 0xc4, 0x44, 0x82, 0xc4, 0xf3, 0xd7,
|
||||
0xe1, 0x4e, 0x5a, 0x9d, 0x4e, 0x2e, 0x8c, 0x98, 0x9c, 0xd2, 0xa7, 0x43, 0x27, 0xa1, 0x40, 0x83,
|
||||
0x80, 0x05, 0x6a, 0x51, 0xdc, 0x42, 0xb4, 0xa9, 0x35, 0x41, 0x3d, 0x7f, 0x63, 0x49, 0xd2, 0x6b,
|
||||
0x30, 0x96, 0x8e, 0x53, 0xc4, 0xb8, 0x87, 0xc6, 0xc5, 0x57, 0xa3, 0x71, 0xe1, 0x8e, 0xac, 0xb4,
|
||||
0x6f, 0xe9, 0x6b, 0x16, 0x72, 0x1b, 0xe8, 0x91, 0xd7, 0x90, 0x17, 0x6f, 0xad, 0xd9, 0xcb, 0x18,
|
||||
0xe4, 0x93, 0xac, 0xdd, 0x1f, 0x01, 0x26, 0xb2, 0xde, 0x41, 0x29, 0x7e, 0x0e, 0xf5, 0x2b, 0xea,
|
||||
0x25, 0xae, 0x3d, 0x1a, 0x8d, 0x27, 0x94, 0x0e, 0xdc, 0x1c, 0xfe, 0xd3, 0x3e, 0x18, 0xdd, 0x18,
|
||||
0x55, 0x69, 0x0b, 0xd7, 0xa9, 0x8a, 0x87, 0x68, 0x85, 0x4f, 0xa7, 0x07, 0xf3, 0xca, 0xea, 0xb3,
|
||||
0xc3, 0x63, 0x5d, 0x39, 0x3a, 0xd6, 0x95, 0x3f, 0xc7, 0xba, 0xf2, 0xed, 0x44, 0xcf, 0x1c, 0x9d,
|
||||
0xe8, 0x99, 0x1f, 0x27, 0x7a, 0xe6, 0xa3, 0xfc, 0x1c, 0xa0, 0xbb, 0x6b, 0xb4, 0x99, 0xd9, 0x3b,
|
||||
0xfb, 0x6d, 0x6a, 0x15, 0xc5, 0xfd, 0x3e, 0xfd, 0x17, 0x00, 0x00, 0xff, 0xff, 0x53, 0x6a, 0x24,
|
||||
0xdc, 0xb8, 0x06, 0x00, 0x00,
|
||||
}
|
||||
|
||||
// Reference imports to suppress errors if they are not otherwise used.
|
||||
@ -724,6 +735,13 @@ func (m *MsgInit) MarshalToSizedBuffer(dAtA []byte) (int, error) {
|
||||
_ = i
|
||||
var l int
|
||||
_ = l
|
||||
if len(m.AddressSeed) > 0 {
|
||||
i -= len(m.AddressSeed)
|
||||
copy(dAtA[i:], m.AddressSeed)
|
||||
i = encodeVarintTx(dAtA, i, uint64(len(m.AddressSeed)))
|
||||
i--
|
||||
dAtA[i] = 0x2a
|
||||
}
|
||||
if len(m.Funds) > 0 {
|
||||
for iNdEx := len(m.Funds) - 1; iNdEx >= 0; iNdEx-- {
|
||||
{
|
||||
@ -1091,6 +1109,10 @@ func (m *MsgInit) Size() (n int) {
|
||||
n += 1 + l + sovTx(uint64(l))
|
||||
}
|
||||
}
|
||||
l = len(m.AddressSeed)
|
||||
if l > 0 {
|
||||
n += 1 + l + sovTx(uint64(l))
|
||||
}
|
||||
return n
|
||||
}
|
||||
|
||||
@ -1388,6 +1410,40 @@ func (m *MsgInit) Unmarshal(dAtA []byte) error {
|
||||
return err
|
||||
}
|
||||
iNdEx = postIndex
|
||||
case 5:
|
||||
if wireType != 2 {
|
||||
return fmt.Errorf("proto: wrong wireType = %d for field AddressSeed", wireType)
|
||||
}
|
||||
var byteLen int
|
||||
for shift := uint(0); ; shift += 7 {
|
||||
if shift >= 64 {
|
||||
return ErrIntOverflowTx
|
||||
}
|
||||
if iNdEx >= l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
b := dAtA[iNdEx]
|
||||
iNdEx++
|
||||
byteLen |= int(b&0x7F) << shift
|
||||
if b < 0x80 {
|
||||
break
|
||||
}
|
||||
}
|
||||
if byteLen < 0 {
|
||||
return ErrInvalidLengthTx
|
||||
}
|
||||
postIndex := iNdEx + byteLen
|
||||
if postIndex < 0 {
|
||||
return ErrInvalidLengthTx
|
||||
}
|
||||
if postIndex > l {
|
||||
return io.ErrUnexpectedEOF
|
||||
}
|
||||
m.AddressSeed = append(m.AddressSeed[:0], dAtA[iNdEx:postIndex]...)
|
||||
if m.AddressSeed == nil {
|
||||
m.AddressSeed = []byte{}
|
||||
}
|
||||
iNdEx = postIndex
|
||||
default:
|
||||
iNdEx = preIndex
|
||||
skippy, err := skipTx(dAtA[iNdEx:])
|
||||
|
||||
Loading…
Reference in New Issue
Block a user