From 8c6f2dec76e39be0f3c89dd096cbc701b7dbc06c Mon Sep 17 00:00:00 2001 From: Christopher Goes Date: Mon, 19 Nov 2018 15:32:42 +0100 Subject: [PATCH 01/14] Update PENDING.md --- PENDING.md | 1 + 1 file changed, 1 insertion(+) diff --git a/PENDING.md b/PENDING.md index a8f278ebb469..a02190653df1 100644 --- a/PENDING.md +++ b/PENDING.md @@ -62,6 +62,7 @@ IMPROVEMENTS * SDK - [x/mock/simulation] [\#2720] major cleanup, introduction of helper objects, reorganization - \#2821 Codespaces are now strings + - \#1277 Complete bank module specification * Tendermint - #2796 Update to go-amino 0.14.1 From 03e8121f13bbc03be9390ecde44a525a6395c020 Mon Sep 17 00:00:00 2001 From: Christopher Goes Date: Mon, 19 Nov 2018 15:38:49 +0100 Subject: [PATCH 02/14] New structure --- docs/spec/bank/README.md | 19 +++++++++++++++++++ docs/spec/bank/WIP_keeper.md | 25 ------------------------- docs/spec/bank/keepers.md | 1 + docs/spec/bank/state.md | 1 + docs/spec/bank/transactions.md | 1 + 5 files changed, 22 insertions(+), 25 deletions(-) create mode 100644 docs/spec/bank/README.md delete mode 100644 docs/spec/bank/WIP_keeper.md create mode 100644 docs/spec/bank/keepers.md create mode 100644 docs/spec/bank/state.md diff --git a/docs/spec/bank/README.md b/docs/spec/bank/README.md new file mode 100644 index 000000000000..49f436d59a73 --- /dev/null +++ b/docs/spec/bank/README.md @@ -0,0 +1,19 @@ +# Bank module specification + +## Abstract + +This document specifies the bank module of the Cosmos SDK. + +The bank module is responsible for handling multi-asset coin transfers between +accounts and tracking special-case pseudo-transfers which must work differently +with particular kinds of accounts (notably delegating/undelegating for vesting +accounts). It exposes several interfaces with varying capabilities for secure +interaction with other modules which must alter user balances. + +This module will be used in the Cosmos Hub. + +## Contents + +1. **[State](state.md)** +2. **[Keepers](keepers.md)** +3. **[Transactions](transactions.md)** diff --git a/docs/spec/bank/WIP_keeper.md b/docs/spec/bank/WIP_keeper.md deleted file mode 100644 index 9667fc5dd0fe..000000000000 --- a/docs/spec/bank/WIP_keeper.md +++ /dev/null @@ -1,25 +0,0 @@ -WORK IN PROGRESS -See PR comments here https://github.com/cosmos/cosmos-sdk/pull/2072 - -# Keeper - -## Denom Metadata - -The BankKeeper contains a store that stores the metadata of different token denoms. Denoms are referred to by their name, same as the `denom` field in sdk.Coin. The different attributes of a denom are stored in the denom metadata store under the key `[denom name]:[attribute name]`. The default attributes in the store are explained below. However, this can be extended by the developer or through SoftwareUpgrade proposals. - -### Decimals `int8` - -- `Base Unit` = The common standard for the default "standard" size of a token. Examples: 1 Bitcoin or 1 Ether. -- `Smallest Unit` = The smallest possible denomination of a token. A fraction of the base unit. Examples: 1 satoshi or 1 wei. - -All amounts throughout the SDK are denominated in the smallest unit of a token, so that all amounts can be expressed as integers. However, UIs typically want to display token values in the base unit, so the Decimals metadata field standardizes the number of digits that come after the decimal place in the base unit. - -`1 [Base Unit] = 10^(N) [Smallest Unit]` - -### TotalSupply `sdk.Integer` - -The TotalSupply of a denom is the total amount of a token that exists (known to the chain) across all accounts and modules. It is denominated in the `smallest unit` of a denom. It can be changed by the Keeper functions `MintCoins` and `BurnCoins`. `AddCoins` and `SubtractCoins` are used when adding or subtracting coins for an account, but not removing them from total supply (for example, when moving the coins to the control of the staking module). - -### Aliases `[]string` - -Aliases is an array of strings that are "alternative names" for a token. As an example, while the Ether's denom name might be `ether`, a possible alias could be `ETH`. This field can be useful for UIs and clients. It is intended that this field can be modified by a governance mechanism. diff --git a/docs/spec/bank/keepers.md b/docs/spec/bank/keepers.md new file mode 100644 index 000000000000..e49a23404200 --- /dev/null +++ b/docs/spec/bank/keepers.md @@ -0,0 +1 @@ +## Keepers diff --git a/docs/spec/bank/state.md b/docs/spec/bank/state.md new file mode 100644 index 000000000000..25e85fac2824 --- /dev/null +++ b/docs/spec/bank/state.md @@ -0,0 +1 @@ +## State diff --git a/docs/spec/bank/transactions.md b/docs/spec/bank/transactions.md index e69de29bb2d1..e51286c0ef2e 100644 --- a/docs/spec/bank/transactions.md +++ b/docs/spec/bank/transactions.md @@ -0,0 +1 @@ +## Transactions From 18ca55cf3f95891aa412c2108b3462abd7090201 Mon Sep 17 00:00:00 2001 From: Christopher Goes Date: Mon, 19 Nov 2018 16:06:18 +0100 Subject: [PATCH 03/14] Start transactions section --- docs/spec/bank/transactions.md | 36 ++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/docs/spec/bank/transactions.md b/docs/spec/bank/transactions.md index e51286c0ef2e..00cf0532fb53 100644 --- a/docs/spec/bank/transactions.md +++ b/docs/spec/bank/transactions.md @@ -1 +1,37 @@ ## Transactions + +### MsgSend + +#### Input + +```golang +type Input struct { + Address AccAddress + Coins Coins +} +``` + +#### Output + +```golang +type Output struct { + Address AccAddress + Coins Coins +} +``` + +```golang +type MsgSend struct { + Inputs []Input + Outputs []Output +} +``` + +### MsgIssue + +```golang +type MsgIssue struct { + Banker AccAddress + Outputs []Output +} +``` From f25e56259ccf9902ddb233fa2b2cdd634290bbd0 Mon Sep 17 00:00:00 2001 From: Christopher Goes Date: Wed, 21 Nov 2018 15:53:01 +0100 Subject: [PATCH 04/14] Remove MsgIssue --- docs/spec/bank/transactions.md | 9 --------- 1 file changed, 9 deletions(-) diff --git a/docs/spec/bank/transactions.md b/docs/spec/bank/transactions.md index 00cf0532fb53..6c3477f416ab 100644 --- a/docs/spec/bank/transactions.md +++ b/docs/spec/bank/transactions.md @@ -26,12 +26,3 @@ type MsgSend struct { Outputs []Output } ``` - -### MsgIssue - -```golang -type MsgIssue struct { - Banker AccAddress - Outputs []Output -} -``` From ca0805bc593e4c5e747d47ffed40db3dd1196448 Mon Sep 17 00:00:00 2001 From: Christopher Goes Date: Wed, 21 Nov 2018 16:26:43 +0100 Subject: [PATCH 05/14] Update keepers.md --- docs/spec/bank/keepers.md | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/docs/spec/bank/keepers.md b/docs/spec/bank/keepers.md index e49a23404200..2ed8eab4e06e 100644 --- a/docs/spec/bank/keepers.md +++ b/docs/spec/bank/keepers.md @@ -1 +1,37 @@ ## Keepers + +The bank module provides three different exported keeper interfaces which can be passed to other modules which need to read or update account balances. Modules should use the least-permissive interface which provides the functionality they require. + +### BaseKeeper + +The base keeper provides full-permission access: the ability to arbitrary modify any account's balance and mint or burn coins. + +```golang +type BaseKeeper interface { + SetCoins(ctx Context, addr AccAddress, amt Coins) error + SubtractCoins(ctx Context, addr AccAddress, amt Coins) (Coins, Tags, error) + AddCoins(ctx Context, addr AccAddress, amt Coins) (Coins, Tags, error) +} +``` + +### SendKeeper + +The send keeper provides access to account balances and the ability to transfer coins between accounts, but not to alter the total supply (mint or burn coins). + +```golang +type SendKeeper interface { + SendCoins(ctx Content, from AccAddress, to AccAddress, amt Coins) (Tags, error) + InputOutputCoins(ctx Context, inputs []Input, outputs []Output) (Tags, error) +} +``` + +### ViewKeeper + +The view keeper provides read-only access to account balances but no balance alteration functionality. All balance lookups are `O(1)`. + +```golang +type ViewKeeper interface { + GetCoins(ctx Context, addr AccAddress) Coins + HasCoins(ctx Context, addr AccAddress, amt Coins) bool +} +``` From ad7c0e1474345055c11712217dfd39ad6e411d95 Mon Sep 17 00:00:00 2001 From: Christopher Goes Date: Thu, 22 Nov 2018 16:39:41 +0100 Subject: [PATCH 06/14] Add state.md --- docs/spec/bank/README.md | 11 +++++++++-- docs/spec/bank/state.md | 2 ++ docs/spec/bank/transactions.md | 4 +++- 3 files changed, 14 insertions(+), 3 deletions(-) diff --git a/docs/spec/bank/README.md b/docs/spec/bank/README.md index 49f436d59a73..9959cd9dd248 100644 --- a/docs/spec/bank/README.md +++ b/docs/spec/bank/README.md @@ -15,5 +15,12 @@ This module will be used in the Cosmos Hub. ## Contents 1. **[State](state.md)** -2. **[Keepers](keepers.md)** -3. **[Transactions](transactions.md)** +1. **[Keepers](keepers.md)** + 1. [BaseKeeper](keepers.md#basekeeper) + 1. [SendKeeper](keepers.md#sendkeeper) + 1. [ViewKeeper](keepers.md#viewkeeper) +1. **[Transactions](transactions.md)** + 1. [Common](transactions.md#common) + 1. [Input](transactions.md#input) + 1. [Output](transactions.md#output) + 1. [MsgSend](transactions.md#msgsend) diff --git a/docs/spec/bank/state.md b/docs/spec/bank/state.md index 25e85fac2824..ac8ba163a0da 100644 --- a/docs/spec/bank/state.md +++ b/docs/spec/bank/state.md @@ -1 +1,3 @@ ## State + +Presently, the bank module has no inherent state — it simply reads and writes accounts using the `AccountKeeper` from the `auth` module. diff --git a/docs/spec/bank/transactions.md b/docs/spec/bank/transactions.md index 6c3477f416ab..c89db21d5e69 100644 --- a/docs/spec/bank/transactions.md +++ b/docs/spec/bank/transactions.md @@ -1,6 +1,6 @@ ## Transactions -### MsgSend +### Common #### Input @@ -20,6 +20,8 @@ type Output struct { } ``` +### MsgSend + ```golang type MsgSend struct { Inputs []Input From 449a0af27616fe3c4eb7c64b556695074aa77c2e Mon Sep 17 00:00:00 2001 From: Christopher Goes Date: Thu, 22 Nov 2018 17:19:57 +0100 Subject: [PATCH 07/14] Update keepers.md, discovered #2887 --- docs/spec/bank/README.md | 6 +- docs/spec/bank/keepers.md | 100 ++++++++++++++++++++++++++++++--- docs/spec/bank/transactions.md | 27 +++------ 3 files changed, 103 insertions(+), 30 deletions(-) diff --git a/docs/spec/bank/README.md b/docs/spec/bank/README.md index 9959cd9dd248..bee48c02946b 100644 --- a/docs/spec/bank/README.md +++ b/docs/spec/bank/README.md @@ -16,11 +16,11 @@ This module will be used in the Cosmos Hub. 1. **[State](state.md)** 1. **[Keepers](keepers.md)** + 1. [Common Types](keepers.md#common-types) + 1. [Input](keepers.md#input) + 1. [Output](keepers.md#output) 1. [BaseKeeper](keepers.md#basekeeper) 1. [SendKeeper](keepers.md#sendkeeper) 1. [ViewKeeper](keepers.md#viewkeeper) 1. **[Transactions](transactions.md)** - 1. [Common](transactions.md#common) - 1. [Input](transactions.md#input) - 1. [Output](transactions.md#output) 1. [MsgSend](transactions.md#msgsend) diff --git a/docs/spec/bank/keepers.md b/docs/spec/bank/keepers.md index 2ed8eab4e06e..e1332fff066b 100644 --- a/docs/spec/bank/keepers.md +++ b/docs/spec/bank/keepers.md @@ -2,36 +2,122 @@ The bank module provides three different exported keeper interfaces which can be passed to other modules which need to read or update account balances. Modules should use the least-permissive interface which provides the functionality they require. +### Common Types + +#### Input + +An input of a multiparty transfer + +```golang +type Input struct { + Address AccAddress + Coins Coins +} +``` + +#### Output + +An output of a multiparty transfer. + +```golang +type Output struct { + Address AccAddress + Coins Coins +} +``` + ### BaseKeeper The base keeper provides full-permission access: the ability to arbitrary modify any account's balance and mint or burn coins. ```golang type BaseKeeper interface { - SetCoins(ctx Context, addr AccAddress, amt Coins) error - SubtractCoins(ctx Context, addr AccAddress, amt Coins) (Coins, Tags, error) - AddCoins(ctx Context, addr AccAddress, amt Coins) (Coins, Tags, error) + SetCoins(addr AccAddress, amt Coins) + SubtractCoins(addr AccAddress, amt Coins) + AddCoins(addr AccAddress, amt Coins) } ``` +`setCoins` fetches an account by address, sets the coins on the account, and saves the account. + +``` +setCoins(addr AccAddress, amt Coins) + account = accountKeeper.getAccount(addr) + if account == nil + fail with "no account found" + account.Coins = amt + accountKeeper.setAccount(account) +``` + +`subtractCoins` fetches the coins of an account, subtracts the provided amount, and saves the account. This decreases the total supply. + +``` +subtractCoins(addr AccAddress, amt Coins) + oldCoins = getCoins(addr) + newCoins = oldCoins - amt + if newCoins < 0 + fail with "cannot end up with negative coins" + setCoins(addr, newCoins) +``` + +`addCoins` fetches the coins of an account, adds the provided amount, and saves the account. This increases the total supply. + +``` +addCoins(addr AccAddress, amt Coins) + oldCoins = getCoins(addr) + newCoins = oldCoins + amt + setCoins(addr, newCoins) +``` + ### SendKeeper The send keeper provides access to account balances and the ability to transfer coins between accounts, but not to alter the total supply (mint or burn coins). ```golang type SendKeeper interface { - SendCoins(ctx Content, from AccAddress, to AccAddress, amt Coins) (Tags, error) - InputOutputCoins(ctx Context, inputs []Input, outputs []Output) (Tags, error) + SendCoins(from AccAddress, to AccAddress, amt Coins) + InputOutputCoins(inputs []Input, outputs []Output) } ``` +`sendCoins` transfers coins from one account to another. + +``` +sendCoins(from AccAddress, to AccAddress, amt Coins) +``` + +``` +inputOutputCoins(inputs []Input, outputs []Output) +``` + +`inputOutputCoins` transfers coins from any number of input accounts (who must all sign the transaction) to any number of output accounts. + ### ViewKeeper The view keeper provides read-only access to account balances but no balance alteration functionality. All balance lookups are `O(1)`. ```golang type ViewKeeper interface { - GetCoins(ctx Context, addr AccAddress) Coins - HasCoins(ctx Context, addr AccAddress, amt Coins) bool + GetCoins(addr AccAddress) Coins + HasCoins(addr AccAddress, amt Coins) bool } ``` + +`getCoins` returns the coins associated with an account. + +``` +getCoins(addr AccAddress) + account = accountKeeper.getAccount(addr) + if account == nil + return Coins{} + return account.Coins +``` + +`hasCoins` returns whether or not an account has at least the provided amount of coins. + +``` +hasCoins(addr AccAddress, amt Coins) + account = accountKeeper.getAccount(addr) + coins = getCoins(addr) + return coins >= amt +``` diff --git a/docs/spec/bank/transactions.md b/docs/spec/bank/transactions.md index c89db21d5e69..b10840e34d23 100644 --- a/docs/spec/bank/transactions.md +++ b/docs/spec/bank/transactions.md @@ -1,25 +1,5 @@ ## Transactions -### Common - -#### Input - -```golang -type Input struct { - Address AccAddress - Coins Coins -} -``` - -#### Output - -```golang -type Output struct { - Address AccAddress - Coins Coins -} -``` - ### MsgSend ```golang @@ -28,3 +8,10 @@ type MsgSend struct { Outputs []Output } ``` + +`handleMsgSend` just runs `inputOutputCoins`. + +``` +handleMsgSend(msg MsgSend) + return inputOutputCoins(msg.Inputs, msg.Outputs) +``` From 1a6bb0f8e24607e25b9dfc4c34225ed9422556e4 Mon Sep 17 00:00:00 2001 From: Christopher Goes Date: Fri, 23 Nov 2018 12:42:18 +0100 Subject: [PATCH 08/14] Move inputOutputCoins to BaseKeeper --- docs/spec/bank/keepers.md | 15 ++++++++------- x/bank/keeper.go | 18 +++++++++--------- 2 files changed, 17 insertions(+), 16 deletions(-) diff --git a/docs/spec/bank/keepers.md b/docs/spec/bank/keepers.md index e1332fff066b..5f44a20258b5 100644 --- a/docs/spec/bank/keepers.md +++ b/docs/spec/bank/keepers.md @@ -35,6 +35,7 @@ type BaseKeeper interface { SetCoins(addr AccAddress, amt Coins) SubtractCoins(addr AccAddress, amt Coins) AddCoins(addr AccAddress, amt Coins) + InputOutputCoins(inputs []Input, outputs []Output) } ``` @@ -69,6 +70,13 @@ addCoins(addr AccAddress, amt Coins) setCoins(addr, newCoins) ``` +`inputOutputCoins` transfers coins from any number of input accounts (who must all sign the transaction) to any number of output accounts. + + +``` +inputOutputCoins(inputs []Input, outputs []Output) +``` + ### SendKeeper The send keeper provides access to account balances and the ability to transfer coins between accounts, but not to alter the total supply (mint or burn coins). @@ -76,7 +84,6 @@ The send keeper provides access to account balances and the ability to transfer ```golang type SendKeeper interface { SendCoins(from AccAddress, to AccAddress, amt Coins) - InputOutputCoins(inputs []Input, outputs []Output) } ``` @@ -86,12 +93,6 @@ type SendKeeper interface { sendCoins(from AccAddress, to AccAddress, amt Coins) ``` -``` -inputOutputCoins(inputs []Input, outputs []Output) -``` - -`inputOutputCoins` transfers coins from any number of input accounts (who must all sign the transaction) to any number of output accounts. - ### ViewKeeper The view keeper provides read-only access to account balances but no balance alteration functionality. All balance lookups are `O(1)`. diff --git a/x/bank/keeper.go b/x/bank/keeper.go index af930953f4be..579c0a2a9858 100644 --- a/x/bank/keeper.go +++ b/x/bank/keeper.go @@ -28,6 +28,7 @@ type Keeper interface { SetCoins(ctx sdk.Context, addr sdk.AccAddress, amt sdk.Coins) sdk.Error SubtractCoins(ctx sdk.Context, addr sdk.AccAddress, amt sdk.Coins) (sdk.Coins, sdk.Tags, sdk.Error) AddCoins(ctx sdk.Context, addr sdk.AccAddress, amt sdk.Coins) (sdk.Coins, sdk.Tags, sdk.Error) + InputOutputCoins(ctx sdk.Context, inputs []Input, outputs []Output) (sdk.Tags, sdk.Error) } // BaseKeeper manages transfers between accounts. It implements the Keeper @@ -67,6 +68,14 @@ func (keeper BaseKeeper) AddCoins( return addCoins(ctx, keeper.ak, addr, amt) } +// InputOutputCoins handles a list of inputs and outputs +func (keeper BaseKeeper) InputOutputCoins( + ctx sdk.Context, inputs []Input, outputs []Output, +) (sdk.Tags, sdk.Error) { + + return inputOutputCoins(ctx, keeper.ak, inputs, outputs) +} + //----------------------------------------------------------------------------- // Send Keeper @@ -76,7 +85,6 @@ type SendKeeper interface { ViewKeeper SendCoins(ctx sdk.Context, fromAddr sdk.AccAddress, toAddr sdk.AccAddress, amt sdk.Coins) (sdk.Tags, sdk.Error) - InputOutputCoins(ctx sdk.Context, inputs []Input, outputs []Output) (sdk.Tags, sdk.Error) } var _ SendKeeper = (*BaseSendKeeper)(nil) @@ -105,14 +113,6 @@ func (keeper BaseSendKeeper) SendCoins( return sendCoins(ctx, keeper.ak, fromAddr, toAddr, amt) } -// InputOutputCoins handles a list of inputs and outputs -func (keeper BaseSendKeeper) InputOutputCoins( - ctx sdk.Context, inputs []Input, outputs []Output, -) (sdk.Tags, sdk.Error) { - - return inputOutputCoins(ctx, keeper.ak, inputs, outputs) -} - //----------------------------------------------------------------------------- // View Keeper From 58997a93ea6a072245ef91959681825990640eff Mon Sep 17 00:00:00 2001 From: Christopher Goes Date: Fri, 23 Nov 2018 12:45:46 +0100 Subject: [PATCH 09/14] Remove no-loner-applicable tests --- x/bank/keeper_test.go | 22 ---------------------- 1 file changed, 22 deletions(-) diff --git a/x/bank/keeper_test.go b/x/bank/keeper_test.go index 26c1446d27c7..14f40f9c4f40 100644 --- a/x/bank/keeper_test.go +++ b/x/bank/keeper_test.go @@ -124,7 +124,6 @@ func TestSendKeeper(t *testing.T) { addr := sdk.AccAddress([]byte("addr1")) addr2 := sdk.AccAddress([]byte("addr2")) - addr3 := sdk.AccAddress([]byte("addr3")) acc := accountKeeper.NewAccountWithAddress(ctx, addr) // Test GetCoins/SetCoins @@ -157,27 +156,6 @@ func TestSendKeeper(t *testing.T) { require.True(t, sendKeeper.GetCoins(ctx, addr).IsEqual(sdk.Coins{sdk.NewInt64Coin("barcoin", 20), sdk.NewInt64Coin("foocoin", 5)})) require.True(t, sendKeeper.GetCoins(ctx, addr2).IsEqual(sdk.Coins{sdk.NewInt64Coin("barcoin", 10), sdk.NewInt64Coin("foocoin", 10)})) - // Test InputOutputCoins - input1 := NewInput(addr2, sdk.Coins{sdk.NewInt64Coin("foocoin", 2)}) - output1 := NewOutput(addr, sdk.Coins{sdk.NewInt64Coin("foocoin", 2)}) - sendKeeper.InputOutputCoins(ctx, []Input{input1}, []Output{output1}) - require.True(t, sendKeeper.GetCoins(ctx, addr).IsEqual(sdk.Coins{sdk.NewInt64Coin("barcoin", 20), sdk.NewInt64Coin("foocoin", 7)})) - require.True(t, sendKeeper.GetCoins(ctx, addr2).IsEqual(sdk.Coins{sdk.NewInt64Coin("barcoin", 10), sdk.NewInt64Coin("foocoin", 8)})) - - inputs := []Input{ - NewInput(addr, sdk.Coins{sdk.NewInt64Coin("foocoin", 3)}), - NewInput(addr2, sdk.Coins{sdk.NewInt64Coin("barcoin", 3), sdk.NewInt64Coin("foocoin", 2)}), - } - - outputs := []Output{ - NewOutput(addr, sdk.Coins{sdk.NewInt64Coin("barcoin", 1)}), - NewOutput(addr3, sdk.Coins{sdk.NewInt64Coin("barcoin", 2), sdk.NewInt64Coin("foocoin", 5)}), - } - sendKeeper.InputOutputCoins(ctx, inputs, outputs) - require.True(t, sendKeeper.GetCoins(ctx, addr).IsEqual(sdk.Coins{sdk.NewInt64Coin("barcoin", 21), sdk.NewInt64Coin("foocoin", 4)})) - require.True(t, sendKeeper.GetCoins(ctx, addr2).IsEqual(sdk.Coins{sdk.NewInt64Coin("barcoin", 7), sdk.NewInt64Coin("foocoin", 6)})) - require.True(t, sendKeeper.GetCoins(ctx, addr3).IsEqual(sdk.Coins{sdk.NewInt64Coin("barcoin", 2), sdk.NewInt64Coin("foocoin", 5)})) - } func TestViewKeeper(t *testing.T) { From abb0b73a61ccc1b0abe09e06ddfc8f869f137f78 Mon Sep 17 00:00:00 2001 From: Christopher Goes Date: Fri, 23 Nov 2018 14:39:29 +0100 Subject: [PATCH 10/14] More spec updates --- docs/spec/bank/keepers.md | 8 +++++++- docs/spec/bank/transactions.md | 9 +++++++++ 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/docs/spec/bank/keepers.md b/docs/spec/bank/keepers.md index 5f44a20258b5..f4fd5a59c139 100644 --- a/docs/spec/bank/keepers.md +++ b/docs/spec/bank/keepers.md @@ -70,11 +70,15 @@ addCoins(addr AccAddress, amt Coins) setCoins(addr, newCoins) ``` -`inputOutputCoins` transfers coins from any number of input accounts (who must all sign the transaction) to any number of output accounts. +`inputOutputCoins` transfers coins from any number of input accounts to any number of output accounts. ``` inputOutputCoins(inputs []Input, outputs []Output) + for input in inputs + subtractCoins(input.Address, input.Coins) + for output in outputs + addCoins(output.Address, output.Coins) ``` ### SendKeeper @@ -91,6 +95,8 @@ type SendKeeper interface { ``` sendCoins(from AccAddress, to AccAddress, amt Coins) + subtractCoins(from, amt) + addCoins(to, amt) ``` ### ViewKeeper diff --git a/docs/spec/bank/transactions.md b/docs/spec/bank/transactions.md index b10840e34d23..7cb512405e49 100644 --- a/docs/spec/bank/transactions.md +++ b/docs/spec/bank/transactions.md @@ -13,5 +13,14 @@ type MsgSend struct { ``` handleMsgSend(msg MsgSend) + inputSum = 0 + for input in inputs + inputSum += input.Amount + outputSum = 0 + for output in outputs + outputSum += output.Amount + if inputSum != outputSum: + fail with "input/output amount mismatch" + return inputOutputCoins(msg.Inputs, msg.Outputs) ``` From 5e8aa3e92521fc1e6304aaba9eda6912b856c790 Mon Sep 17 00:00:00 2001 From: Christopher Goes Date: Fri, 23 Nov 2018 14:53:26 +0100 Subject: [PATCH 11/14] Tiny cleanup --- x/bank/msgs.go | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/x/bank/msgs.go b/x/bank/msgs.go index 1af7acfe73dd..48d251a1f87a 100644 --- a/x/bank/msgs.go +++ b/x/bank/msgs.go @@ -6,6 +6,9 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" ) +// name to identify transaction routes +const MsgRoute = "bank" + // MsgSend - high level transaction of the coin module type MsgSend struct { Inputs []Input `json:"inputs"` @@ -21,7 +24,7 @@ func NewMsgSend(in []Input, out []Output) MsgSend { // Implements Msg. // nolint -func (msg MsgSend) Route() string { return "bank" } // TODO: "bank/send" +func (msg MsgSend) Route() string { return MsgRoute } func (msg MsgSend) Type() string { return "send" } // Implements Msg. From afe50766a4c0a647643f6c165d478a8cb08ebd2e Mon Sep 17 00:00:00 2001 From: Christopher Goes Date: Mon, 26 Nov 2018 11:53:14 +0100 Subject: [PATCH 12/14] Clarify storage rationale --- docs/spec/bank/state.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docs/spec/bank/state.md b/docs/spec/bank/state.md index ac8ba163a0da..aa6585bbffb3 100644 --- a/docs/spec/bank/state.md +++ b/docs/spec/bank/state.md @@ -1,3 +1,5 @@ ## State Presently, the bank module has no inherent state — it simply reads and writes accounts using the `AccountKeeper` from the `auth` module. + +This implementation choice is intended to minimize necessary state reads/writes, since we expect most transactions to involve coin amounts (for fees), so storing coin data in the account saves reading it separately. From 81c4f512614347cc5fc9aabd11a0f0ecab6ced01 Mon Sep 17 00:00:00 2001 From: Christopher Goes Date: Mon, 26 Nov 2018 11:59:15 +0100 Subject: [PATCH 13/14] Warn the user --- docs/spec/bank/keepers.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docs/spec/bank/keepers.md b/docs/spec/bank/keepers.md index f4fd5a59c139..8c3afb5f886e 100644 --- a/docs/spec/bank/keepers.md +++ b/docs/spec/bank/keepers.md @@ -2,6 +2,8 @@ The bank module provides three different exported keeper interfaces which can be passed to other modules which need to read or update account balances. Modules should use the least-permissive interface which provides the functionality they require. +Note that you should always review the `bank` module code to ensure that permissions are limited in the way that you expect. + ### Common Types #### Input From d039e52cf0c398a2274289e5d0b2574c55a7f3c0 Mon Sep 17 00:00:00 2001 From: Christopher Goes Date: Mon, 26 Nov 2018 16:19:53 +0100 Subject: [PATCH 14/14] Remove extra newline --- docs/spec/bank/keepers.md | 1 - 1 file changed, 1 deletion(-) diff --git a/docs/spec/bank/keepers.md b/docs/spec/bank/keepers.md index 8c3afb5f886e..3c6eab7725d8 100644 --- a/docs/spec/bank/keepers.md +++ b/docs/spec/bank/keepers.md @@ -74,7 +74,6 @@ addCoins(addr AccAddress, amt Coins) `inputOutputCoins` transfers coins from any number of input accounts to any number of output accounts. - ``` inputOutputCoins(inputs []Input, outputs []Output) for input in inputs