Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Put AccountSequence in SignerInfo #6997

Merged
merged 51 commits into from
Aug 21, 2020
Merged
Show file tree
Hide file tree
Changes from 14 commits
Commits
Show all changes
51 commits
Select commit Hold shift + click to select a range
8b9e820
WIP test the grounds
amaury1093 Aug 10, 2020
364c7aa
Update ADR020
amaury1093 Aug 10, 2020
4f789d6
Fix compile errors
amaury1093 Aug 10, 2020
3e71d87
Fix ADR
amaury1093 Aug 10, 2020
fcf8554
Merge branch 'master' of ssh://github.com/cosmos/cosmos-sdk into am-6…
amaury1093 Aug 11, 2020
a4fcf67
Make ante tests pass
amaury1093 Aug 11, 2020
99a59f4
Fix remaining ante handler tests
amaury1093 Aug 11, 2020
74ecbff
Merge branch 'master' of ssh://github.com/cosmos/cosmos-sdk into am-6…
amaury1093 Aug 11, 2020
48b380d
Simplify code
amaury1093 Aug 11, 2020
a2d42aa
Fix x/bank app_test
amaury1093 Aug 11, 2020
4d10cd1
Merge branch 'master' of ssh://github.com/cosmos/cosmos-sdk into am-6…
amaury1093 Aug 12, 2020
0231b26
Merge branch 'master' of ssh://github.com/cosmos/cosmos-sdk into am-6…
amaury1093 Aug 12, 2020
e2d8b5c
Fix tests
amaury1093 Aug 12, 2020
813961b
Merge branch 'master' into am-6966-seq-in-signerinfo
amaury1093 Aug 12, 2020
10f4849
Merge branch 'master' into am-6966-seq-in-signerinfo
amaury1093 Aug 12, 2020
76123e3
Remove useless accSeq from signerdata
amaury1093 Aug 12, 2020
576a1d9
Fix test
amaury1093 Aug 12, 2020
7256038
Merge branch 'am-6966-seq-in-signerinfo' of ssh://github.com/cosmos/c…
amaury1093 Aug 12, 2020
020ab39
Merge branch 'master' into am-6966-seq-in-signerinfo
amaury1093 Aug 12, 2020
69d0ff5
Update simapp/helpers/test_helpers.go
amaury1093 Aug 12, 2020
0966d5b
Update simapp/helpers/test_helpers.go
amaury1093 Aug 12, 2020
8883b34
Update x/auth/client/cli/tx_multisign.go
amaury1093 Aug 12, 2020
2dd868b
Merge branch 'master' into am-6966-seq-in-signerinfo
amaury1093 Aug 13, 2020
98f7cd5
Address rewview
amaury1093 Aug 14, 2020
e7f853a
Merge branch 'master' of ssh://github.com/cosmos/cosmos-sdk into am-6…
amaury1093 Aug 14, 2020
846761b
Merge branch 'am-6966-seq-in-signerinfo' of ssh://github.com/cosmos/c…
amaury1093 Aug 14, 2020
e930d43
Merge branch 'master' into am-6966-seq-in-signerinfo
sahith-narahari Aug 14, 2020
e4545c3
Update x/auth/ante/sigverify.go
amaury1093 Aug 14, 2020
2a2ff8e
Update x/auth/ante/sigverify_test.go
amaury1093 Aug 14, 2020
2a3c1da
Update x/auth/tx/builder_test.go
amaury1093 Aug 14, 2020
f5c04c7
Update x/auth/tx/builder_test.go
amaury1093 Aug 14, 2020
14b7a62
Update x/auth/tx/direct_test.go
amaury1093 Aug 14, 2020
7f44ee5
Update x/auth/tx/builder_test.go
amaury1093 Aug 14, 2020
dd5f6c9
AccSeq -> Seq
amaury1093 Aug 14, 2020
5b8edb0
Address reviews
amaury1093 Aug 14, 2020
2f4b399
Better variable naming
amaury1093 Aug 14, 2020
9cdeaa0
Fix variable assign
amaury1093 Aug 14, 2020
9f2d19b
Remove old SetSignerInfo
amaury1093 Aug 14, 2020
c4dda3b
Fix test
amaury1093 Aug 14, 2020
03a3cf8
Merge branch 'master' of ssh://github.com/cosmos/cosmos-sdk into am-6…
amaury1093 Aug 17, 2020
ed552df
proto-gen
amaury1093 Aug 17, 2020
be7410c
Merge branch 'master' of ssh://github.com/cosmos/cosmos-sdk into am-6…
amaury1093 Aug 19, 2020
4f01844
Make proto-gen
amaury1093 Aug 19, 2020
2fdf052
Reput gw comment
amaury1093 Aug 19, 2020
8f102b5
Add Changelog
amaury1093 Aug 19, 2020
55fac18
Merge branch 'master' of ssh://github.com/cosmos/cosmos-sdk into am-6…
amaury1093 Aug 20, 2020
432128f
Update x/bank/app_test.go
amaury1093 Aug 20, 2020
dfe6082
Update x/bank/app_test.go
amaury1093 Aug 20, 2020
2675653
Merge branch 'master' of ssh://github.com/cosmos/cosmos-sdk into am-6…
amaury1093 Aug 21, 2020
9eca77d
Merge branch 'am-6966-seq-in-signerinfo' of ssh://github.com/cosmos/c…
amaury1093 Aug 21, 2020
7d1d281
Merge branch 'master' into am-6966-seq-in-signerinfo
alexanderbez Aug 21, 2020
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 8 additions & 10 deletions client/testutil/suite.go
Original file line number Diff line number Diff line change
Expand Up @@ -101,12 +101,12 @@ func (s *TxConfigTestSuite) TestTxBuilderSetSignatures() {

// set SignatureV2 without actual signature bytes
sigData1 := &signingtypes.SingleSignatureData{SignMode: signModeHandler.DefaultMode()}
sig1 := signingtypes.SignatureV2{PubKey: pubkey, Data: sigData1}
amaury1093 marked this conversation as resolved.
Show resolved Hide resolved
sig1 := signingtypes.SignatureV2{PubKey: pubkey, Data: sigData1, AccountSequence: 2}

msigData := multisig.NewMultisig(2)
multisig.AddSignature(msigData, &signingtypes.SingleSignatureData{SignMode: signModeHandler.DefaultMode()}, 0)
multisig.AddSignature(msigData, &signingtypes.SingleSignatureData{SignMode: signModeHandler.DefaultMode()}, 1)
msig := signingtypes.SignatureV2{PubKey: multisigPk, Data: msigData}
msig := signingtypes.SignatureV2{PubKey: multisigPk, Data: msigData, AccountSequence: 4}

// fail validation without required signers
err = txBuilder.SetSignatures(sig1)
Expand All @@ -128,19 +128,17 @@ func (s *TxConfigTestSuite) TestTxBuilderSetSignatures() {

// sign transaction
signerData := signing.SignerData{
ChainID: "test",
AccountNumber: 1,
AccountSequence: 2,
ChainID: "test",
AccountNumber: 1,
}
signBytes, err := signModeHandler.GetSignBytes(signModeHandler.DefaultMode(), signerData, sigTx)
s.Require().NoError(err)
sigBz, err := privKey.Sign(signBytes)
s.Require().NoError(err)

signerData = signing.SignerData{
ChainID: "test",
AccountNumber: 3,
AccountSequence: 4,
ChainID: "test",
AccountNumber: 3,
}
mSignBytes, err := signModeHandler.GetSignBytes(signModeHandler.DefaultMode(), signerData, sigTx)
s.Require().NoError(err)
Expand All @@ -156,8 +154,8 @@ func (s *TxConfigTestSuite) TestTxBuilderSetSignatures() {

// set signature
sigData1.Signature = sigBz
sig1 = signingtypes.SignatureV2{PubKey: pubkey, Data: sigData1}
msig = signingtypes.SignatureV2{PubKey: multisigPk, Data: msigData}
sig1 = signingtypes.SignatureV2{PubKey: pubkey, Data: sigData1, AccountSequence: 2}
msig = signingtypes.SignatureV2{PubKey: multisigPk, Data: msigData, AccountSequence: 4}
err = txBuilder.SetSignatures(sig1, msig)
s.Require().NoError(err)
sigTx = txBuilder.GetTx()
Expand Down
16 changes: 10 additions & 6 deletions client/tx/tx.go
Original file line number Diff line number Diff line change
Expand Up @@ -322,6 +322,7 @@ func PrepareFactory(clientCtx client.Context, txf Factory) (Factory, error) {
func SignWithPrivKey(
signMode signing.SignMode, signerData authsigning.SignerData,
txBuilder client.TxBuilder, priv crypto.PrivKey, txConfig client.TxConfig,
accSeq uint64,
amaury1093 marked this conversation as resolved.
Show resolved Hide resolved
) (signing.SignatureV2, error) {
var sigV2 signing.SignatureV2

Expand All @@ -344,8 +345,9 @@ func SignWithPrivKey(
}

sigV2 = signing.SignatureV2{
PubKey: priv.PubKey(),
Data: &sigData,
PubKey: priv.PubKey(),
Data: &sigData,
AccountSequence: accSeq,
amaury1093 marked this conversation as resolved.
Show resolved Hide resolved
}

return sigV2, nil
Expand Down Expand Up @@ -390,8 +392,9 @@ func Sign(txf Factory, name string, txBuilder client.TxBuilder) error {
Signature: nil,
}
sig := signing.SignatureV2{
PubKey: pubKey,
Data: &sigData,
PubKey: pubKey,
Data: &sigData,
AccountSequence: txf.Sequence(),
amaury1093 marked this conversation as resolved.
Show resolved Hide resolved
}
if err := txBuilder.SetSignatures(sig); err != nil {
return err
Expand All @@ -415,8 +418,9 @@ func Sign(txf Factory, name string, txBuilder client.TxBuilder) error {
Signature: sigBytes,
}
sig = signing.SignatureV2{
PubKey: pubKey,
Data: &sigData,
PubKey: pubKey,
Data: &sigData,
AccountSequence: txf.Sequence(),
}

// And here the tx is populated with the signature
Expand Down
98 changes: 49 additions & 49 deletions docs/architecture/adr-020-protobuf-transaction-encoding.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ querying. However, this ADR solely focuses on transactions. Querying should be
addressed in a future ADR, but it should build off of these proposals.

Based on detailed discussions ([\#6030](https://github.com/cosmos/cosmos-sdk/issues/6030)
and [\#6078](https://github.com/cosmos/cosmos-sdk/issues/6078)), the original
and [\#6078](https://github.com/cosmos/cosmos-sdk/issues/6078)), the original
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

sorry, spacing changes are made by my editor... but i think they make sense.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you editor. By the way, have you considered adding an .editorconfig to this repo? I made very good experience with it and use it in all projects: https://editorconfig.org/

design for transactions was changed substantially from an `oneof` /JSON-signing
approach to the approach described below.

Expand All @@ -37,15 +37,15 @@ approach to the approach described below.
### Transactions

Since interface values are encoded with `google.protobuf.Any` in state (see [ADR 019](adr-019-protobuf-state-encoding.md)),
`sdk.Msg`s are encoding with `Any` in transactions.
One of the main goals of using `Any` to encode interface values is to have a
core set of types which is reused by apps so that
clients can safely be compatible with as many chains as possible.
It is one of the goals of this specification to provide a flexible cross-chain transaction
format that can serve a wide variety of use cases without breaking client
compatibility.
`sdk.Msg`s are encoding with `Any` in transactions.

One of the main goals of using `Any` to encode interface values is to have a
core set of types which is reused by apps so that
clients can safely be compatible with as many chains as possible.

It is one of the goals of this specification to provide a flexible cross-chain transaction
format that can serve a wide variety of use cases without breaking client
compatibility.

In order to facilitate signing, transactions are separated into `TxBody`,
which will be re-used by `SignDoc` below, and `signatures`:
Expand Down Expand Up @@ -105,20 +105,24 @@ message SignerInfo {
// ModeInfo describes the signing mode of the signer and is a nested
// structure to support nested multisig pubkey's
ModeInfo mode_info = 2;
// account_sequence is the sequence of the account, which describes the
// number of transactions sent from a given address. It is used to prevent
amaury1093 marked this conversation as resolved.
Show resolved Hide resolved
// replay attacks.
alexanderbez marked this conversation as resolved.
Show resolved Hide resolved
uint64 account_sequence = 3;
amaury1093 marked this conversation as resolved.
Show resolved Hide resolved
}

message ModeInfo {
oneof sum {
Single single = 1;
Multi multi = 2;
}
}

// Single is the mode info for a single signer. It is structured as a message
// to allow for additional fields such as locale for SIGN_MODE_TEXTUAL in the future
message Single {
SignMode mode = 1;
}

// Multi is the mode info for a multisig public key
message Multi {
// bitarray specifies which keys within the multisig are signing
Expand All @@ -127,15 +131,15 @@ message ModeInfo {
// which could include nested multisig public keys
repeated ModeInfo mode_infos = 2;
}
}
}

enum SignMode {
SIGN_MODE_UNSPECIFIED = 0;

SIGN_MODE_DIRECT = 1;

SIGN_MODE_TEXTUAL = 2;

SIGN_MODE_LEGACY_AMINO_JSON = 127;
}
```
Expand All @@ -157,10 +161,10 @@ attempt to upstream important improvements to `Tx`.

All of the signing modes below aim to provide the following guarantees:

* **No Malleability**: `TxBody` and `AuthInfo` cannot change once the transaction
is signed
* **Predictable Gas**: if I am signing a transaction where I am paying a fee,
the final gas is fully dependent on what I am signing
- **No Malleability**: `TxBody` and `AuthInfo` cannot change once the transaction
is signed
- **Predictable Gas**: if I am signing a transaction where I am paying a fee,
the final gas is fully dependent on what I am signing

These guarantees give the maximum amount confidence to message signers that
manipulation of `Tx`s by intermediaries can't result in any meaningful changes.
Expand All @@ -170,11 +174,11 @@ manipulation of `Tx`s by intermediaries can't result in any meaningful changes.
The "direct" signing behavior is to sign the raw `TxBody` bytes as broadcast over
the wire. This has the advantages of:

* requiring the minimum additional client capabilities beyond a standard protocol
buffers implementation
* leaving effectively zero holes for transaction malleability (i.e. there are no
subtle differences between the signing and encoding formats which could
potentially be exploited by an attacker)
- requiring the minimum additional client capabilities beyond a standard protocol
buffers implementation
- leaving effectively zero holes for transaction malleability (i.e. there are no
subtle differences between the signing and encoding formats which could
potentially be exploited by an attacker)

Signatures are structured using the `SignDoc` below which reuses the serialization of
`TxBody` and `AuthInfo` and only adds the fields which are needed for signatures:
Expand All @@ -188,9 +192,6 @@ message SignDoc {
bytes auth_info = 2;
string chain_id = 3;
uint64 account_number = 4;
// account_sequence starts at 1 rather than 0 to avoid the case where
// the default 0 value must be omitted in protobuf serialization
uint64 account_sequence = 5;
}
```

Expand Down Expand Up @@ -236,7 +237,7 @@ endpoint before broadcasting.
As was discussed extensively in [\#6078](https://github.com/cosmos/cosmos-sdk/issues/6078),
there is a desire for a human-readable signing encoding, especially for hardware
wallets like the [Ledger](https://www.ledger.com) which display
transaction contents to users before signing. JSON was an attempt at this but
transaction contents to users before signing. JSON was an attempt at this but
falls short of the ideal.

`SIGN_MODE_TEXTUAL` is intended as a placeholder for a human-readable
Expand All @@ -257,11 +258,11 @@ by `SIGN_MODE_TEXTUAL` when it is implemented.
Unknown fields in protobuf messages should generally be rejected by transaction
processors because:

* important data may be present in the unknown fields, that if ignored, will
cause unexpected behavior for clients
* they present a malleability vulnerability where attackers can bloat tx size
by adding random uninterpreted data to unsigned content (i.e. the master `Tx`,
not `TxBody`)
- important data may be present in the unknown fields, that if ignored, will
cause unexpected behavior for clients
- they present a malleability vulnerability where attackers can bloat tx size
by adding random uninterpreted data to unsigned content (i.e. the master `Tx`,
not `TxBody`)

There are also scenarios where we may choose to safely ignore unknown fields
(https://github.com/cosmos/cosmos-sdk/issues/6078#issuecomment-624400188) to
Expand All @@ -272,10 +273,11 @@ the range of 1024-2047) be considered non-critical fields that can safely be
ignored if unknown.

To handle this we will need a unknown field filter that:
* always rejects unknown fields in unsigned content (i.e. top-level `Tx` and
unsigned parts of `AuthInfo` if present based on the signing mode)
* rejects unknown fields in all messages (including nested `Any`s) other than
fields with bit 11 set

- always rejects unknown fields in unsigned content (i.e. top-level `Tx` and
unsigned parts of `AuthInfo` if present based on the signing mode)
- rejects unknown fields in all messages (including nested `Any`s) other than
fields with bit 11 set

This will likely need to be a custom protobuf parser pass that takes message bytes
and `FileDescriptor`s and returns a boolean result.
Expand All @@ -287,17 +289,18 @@ so a natural solution might be to use `Any` as we are doing for other interfaces
There are, however, a limited number of public keys in existence and new ones
aren't created overnight. The proposed solution is to use a `oneof` that:

* attempts to catalog all known key types even if a given app can't use them all
* has an `Any` member that can be used when a key type isn't present in the `oneof`
- attempts to catalog all known key types even if a given app can't use them all
- has an `Any` member that can be used when a key type isn't present in the `oneof`

Ex:

```proto
message PublicKey {
oneof sum {
bytes secp256k1 = 1;
bytes ed25519 = 2;
...
google.protobuf.Any any_pubkey = 15;
google.protobuf.Any any_pubkey = 15;
}
}
```
Expand Down Expand Up @@ -375,7 +378,7 @@ can gracefully transition away from Amino JSON.

### `SIGN_MODE_DIRECT_AUX`

(*Documented as option (3) in https://github.com/cosmos/cosmos-sdk/issues/6078#issuecomment-628026933)
(\*Documented as option (3) in https://github.com/cosmos/cosmos-sdk/issues/6078#issuecomment-628026933)

We could add a mode `SIGN_MODE_DIRECT_AUX`
to support scenarios where multiple signatures
Expand All @@ -402,7 +405,7 @@ fees or gas and thus can just sign `TxBody`.
To generate a signature in `SIGN_MODE_DIRECT_AUX` these steps would be followed:

1. Encode `SignDocAux` (with the same requirement that fields must be serialized
in order):
in order):

```proto
// types/types.proto
Expand All @@ -423,20 +426,17 @@ message SignDocAux {
PublicKey public_key = 2;
string chain_id = 3;
uint64 account_number = 4;
// account_sequence starts at 1 rather than 0 to avoid the case where
// the default 0 value must be omitted in protobuf serialization
uint64 account_sequence = 5;
}
```

2. Sign the encoded `SignDocAux` bytes
3. Send their signature and `SignerInfo` to primary signer who will then
sign and broadcast the final transaction (with `SIGN_MODE_DIRECT` and `AuthInfo`
added) once enough signatures have been collected
sign and broadcast the final transaction (with `SIGN_MODE_DIRECT` and `AuthInfo`
added) once enough signatures have been collected

### `SIGN_MODE_DIRECT_RELAXED`

(*Documented as option (1)(a) in https://github.com/cosmos/cosmos-sdk/issues/6078#issuecomment-628026933*)
(_Documented as option (1)(a) in https://github.com/cosmos/cosmos-sdk/issues/6078#issuecomment-628026933_)

This is a variation of `SIGN_MODE_DIRECT` where multiple signers wouldn't need to
coordinate public keys and signing modes in advance. It would involve an alternate
Expand All @@ -456,7 +456,7 @@ too burdensome.
### Negative

- `google.protobuf.Any` type URLs increase transaction size although the effect
may be negligible or compression may be able to mitigate it.
may be negligible or compression may be able to mitigate it.

### Neutral

Expand Down
5 changes: 5 additions & 0 deletions proto/cosmos/tx/signing/v1beta1/signing.proto
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,11 @@ message SignatureDescriptor {

Data data = 2;

// account_sequence is the sequence of the account, which describes the
// number of transactions sent from a given address. It is used to prevent
// replay attacks.
uint64 account_sequence = 3;

// Data represents signature data
message Data {
// sum is the oneof that specifies whether this represents single or multi-signature data
Expand Down
9 changes: 5 additions & 4 deletions proto/cosmos/tx/v1beta1/tx.proto
Original file line number Diff line number Diff line change
Expand Up @@ -54,10 +54,6 @@ message SignDoc {

// account_number is the account number of the account in state
uint64 account_number = 4;

// account_sequence starts at 1 rather than 0 to avoid the case where
// the default 0 value must be omitted in protobuf serialization
uint64 account_sequence = 5;
}

// TxBody is the body of a transaction that all signers sign over
Expand Down Expand Up @@ -112,6 +108,11 @@ message SignerInfo {
// mode_info describes the signing mode of the signer and is a nested
// structure to support nested multisig pubkey's
ModeInfo mode_info = 2;

// account_sequence is the sequence of the account, which describes the
// number of transactions sent from a given address. It is used to prevent
// replay attacks.
uint64 account_sequence = 3;
}

// ModeInfo describes the signing mode of a single or nested multisig signer
Expand Down
Loading