types: StdSignDoc includes sequence for each sig

This commit is contained in:
Ethan Buchman 2018-03-11 00:57:39 +01:00
parent e4da8ebee2
commit 661d0fd7e8
3 changed files with 24 additions and 21 deletions

View File

@ -69,9 +69,9 @@ func TestMsgs(t *testing.T) {
}
chainID := ""
sequence := int64(0)
sequences := []int64{0}
for i, m := range msgs {
sig := priv1.Sign(sdk.StdSignBytes(chainID, sequence, m.msg))
sig := priv1.Sign(sdk.StdSignBytes(chainID, sequences, m.msg))
tx := sdk.NewStdTx(m.msg, []sdk.StdSignature{{
PubKey: priv1.PubKey(),
Signature: sig,
@ -169,8 +169,8 @@ func TestSendMsgWithAccounts(t *testing.T) {
// Sign the tx
chainID := "" // TODO: InitChain should get the ChainID
sequence := int64(0)
sig := priv1.Sign(sdk.StdSignBytes(chainID, sequence, sendMsg))
sequences := []int64{0}
sig := priv1.Sign(sdk.StdSignBytes(chainID, sequences, sendMsg))
tx := sdk.NewStdTx(sendMsg, []sdk.StdSignature{{
PubKey: priv1.PubKey(),
Signature: sig,
@ -197,13 +197,13 @@ func TestSendMsgWithAccounts(t *testing.T) {
assert.Equal(t, sdk.CodeInvalidSequence, res.Code, res.Log)
// bumping the txnonce number without resigning should be an auth error
sequence += 1
tx.Signatures[0].Sequence = sequence
tx.Signatures[0].Sequence = 1
res = bapp.Deliver(tx)
assert.Equal(t, sdk.CodeUnauthorized, res.Code, res.Log)
// resigning the tx with the bumped sequence should work
sig = priv1.Sign(sdk.StdSignBytes(chainID, sequence, tx.Msg))
sequences = []int64{1}
sig = priv1.Sign(sdk.StdSignBytes(chainID, sequences, tx.Msg))
tx.Signatures[0].Signature = sig
res = bapp.Deliver(tx)
assert.Equal(t, sdk.CodeOK, res.Code, res.Log)

View File

@ -71,19 +71,20 @@ func (tx StdTx) GetSignatures() []StdSignature { return tx.Signatures }
// StdSignDoc is replay-prevention structure.
// It includes the result of msg.GetSignBytes(),
// as well as the ChainID (prevent cross chain replay)
// and the Sequence (prevent inchain replay).
// and the Sequence numbers for each signature (prevent
// inchain replay and enforce tx ordering per account).
type StdSignDoc struct {
ChainID string `json:"chain_id"`
Sequence int64 `json:"sequence"`
MsgBytes []byte `json:"msg_bytes"`
AltBytes []byte `json:"alt_bytes"` // TODO: do we really want this ?
ChainID string `json:"chain_id"`
Sequences []int64 `json:"sequences"`
MsgBytes []byte `json:"msg_bytes"`
AltBytes []byte `json:"alt_bytes"` // TODO: do we really want this ?
}
func StdSignBytes(chainID string, sequence int64, msg Msg) []byte {
func StdSignBytes(chainID string, sequences []int64, msg Msg) []byte {
bz, err := json.Marshal(StdSignDoc{
ChainID: chainID,
Sequence: sequence,
MsgBytes: msg.GetSignBytes(),
ChainID: chainID,
Sequences: sequences,
MsgBytes: msg.GetSignBytes(),
})
if err != nil {
panic(err)

View File

@ -31,15 +31,17 @@ func NewAnteHandler(accountMapper sdk.AccountMapper) sdk.AnteHandler {
// Collect accounts to set in the context
var signerAccs = make([]sdk.Account, len(signerAddrs))
// First sig is the fee payer.
// signBytes uses the sequence of the fee payer
// (ie. the first account)
payerAddr, payerSig := signerAddrs[0], sigs[0]
signBytes := sdk.StdSignBytes(ctx.ChainID(), payerSig.Sequence, msg)
// Get the sign bytes by collecting all sequence numbers
sequences := make([]int64, len(signerAddrs))
for i := 0; i < len(signerAddrs); i++ {
sequences[i] = sigs[i].Sequence
}
signBytes := sdk.StdSignBytes(ctx.ChainID(), sequences, msg)
// Check fee payer sig and nonce, and deduct fee.
// This is done first because it only
// requires fetching 1 account.
payerAddr, payerSig := signerAddrs[0], sigs[0]
payerAcc, res := processSig(ctx, accountMapper, payerAddr, payerSig, signBytes)
if !res.IsOK() {
return ctx, res, true