2018-01-12 11:49:53 -08:00
|
|
|
package auth
|
|
|
|
|
|
|
|
import (
|
2018-01-26 04:19:33 -08:00
|
|
|
bam "github.com/cosmos/cosmos-sdk/baseapp"
|
2018-01-12 14:30:02 -08:00
|
|
|
sdk "github.com/cosmos/cosmos-sdk/types"
|
2018-01-12 11:49:53 -08:00
|
|
|
)
|
|
|
|
|
2018-01-22 05:44:24 -08:00
|
|
|
func NewAnteHandler(accountMapper sdk.AccountMapper) sdk.AnteHandler {
|
2018-01-12 11:49:53 -08:00
|
|
|
return func(
|
2018-01-12 14:30:02 -08:00
|
|
|
ctx sdk.Context, tx sdk.Tx,
|
2018-01-26 05:11:01 -08:00
|
|
|
) (_ sdk.Context, _ sdk.Result, abort bool) {
|
2018-01-12 11:49:53 -08:00
|
|
|
|
|
|
|
// Deduct the fee from the fee payer.
|
|
|
|
// This is done first because it only
|
|
|
|
// requires fetching 1 account.
|
|
|
|
payerAddr := tx.GetFeePayer()
|
2018-01-26 04:19:33 -08:00
|
|
|
if payerAddr != nil {
|
|
|
|
payerAcc := accountMapper.GetAccount(ctx, payerAddr)
|
|
|
|
if payerAcc == nil {
|
|
|
|
return ctx,
|
|
|
|
sdk.ErrUnrecognizedAddress("").Result(),
|
|
|
|
true
|
|
|
|
}
|
|
|
|
// TODO: Charge fee from payerAcc.
|
|
|
|
// TODO: accountMapper.SetAccount(ctx, payerAddr)
|
|
|
|
} else {
|
|
|
|
// TODO: Ensure that some other spam prevention is used.
|
|
|
|
// NOTE: bam.TestApp.RunDeliverMsg/RunCheckMsg will
|
|
|
|
// create a Tx with no payer.
|
2018-01-12 11:49:53 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
// Ensure that signatures are correct.
|
2018-01-12 14:30:02 -08:00
|
|
|
var signerAddrs = tx.GetSigners()
|
|
|
|
var signerAccs = make([]sdk.Account, len(signerAddrs))
|
|
|
|
var signatures = tx.GetSignatures()
|
2018-01-12 11:49:53 -08:00
|
|
|
|
|
|
|
// Assert that there are signers.
|
2018-01-26 04:19:33 -08:00
|
|
|
if len(signerAddrs) == 0 {
|
|
|
|
if !bam.IsTestAppTx(tx) {
|
|
|
|
return ctx,
|
|
|
|
sdk.ErrUnauthorized("no signers").Result(),
|
|
|
|
true
|
|
|
|
}
|
2018-01-12 11:49:53 -08:00
|
|
|
}
|
2018-01-26 04:19:33 -08:00
|
|
|
|
|
|
|
// Assert that number of signatures is correct.
|
2018-01-12 14:30:02 -08:00
|
|
|
if len(signatures) != len(signerAddrs) {
|
2018-01-26 04:19:33 -08:00
|
|
|
return ctx,
|
|
|
|
sdk.ErrUnauthorized("wrong number of signers").Result(),
|
|
|
|
true
|
2018-01-12 11:49:53 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
// Check each nonce and sig.
|
|
|
|
for i, sig := range signatures {
|
|
|
|
|
2018-01-22 05:44:24 -08:00
|
|
|
var signerAcc = accountMapper.GetAccount(ctx, signerAddrs[i])
|
2018-01-12 11:49:53 -08:00
|
|
|
signerAccs[i] = signerAcc
|
|
|
|
|
|
|
|
// If no pubkey, set pubkey.
|
2018-01-14 19:49:57 -08:00
|
|
|
if signerAcc.GetPubKey() == nil {
|
2018-01-12 14:30:02 -08:00
|
|
|
err := signerAcc.SetPubKey(sig.PubKey)
|
2018-01-12 11:49:53 -08:00
|
|
|
if err != nil {
|
2018-01-26 04:19:33 -08:00
|
|
|
return ctx,
|
|
|
|
sdk.ErrInternal("setting PubKey on signer").Result(),
|
|
|
|
true
|
2018-01-12 11:49:53 -08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-01-17 16:59:40 -08:00
|
|
|
// Check and increment sequence number.
|
2018-01-12 14:30:02 -08:00
|
|
|
seq := signerAcc.GetSequence()
|
2018-01-12 11:49:53 -08:00
|
|
|
if seq != sig.Sequence {
|
2018-01-26 04:19:33 -08:00
|
|
|
return ctx,
|
|
|
|
sdk.ErrInvalidSequence("").Result(),
|
|
|
|
true
|
2018-01-12 11:49:53 -08:00
|
|
|
}
|
2018-01-12 14:30:02 -08:00
|
|
|
signerAcc.SetSequence(seq + 1)
|
2018-01-12 11:49:53 -08:00
|
|
|
|
|
|
|
// Check sig.
|
2018-01-12 14:30:02 -08:00
|
|
|
if !sig.PubKey.VerifyBytes(tx.GetSignBytes(), sig.Signature) {
|
2018-01-26 04:19:33 -08:00
|
|
|
return ctx,
|
|
|
|
sdk.ErrUnauthorized("").Result(),
|
|
|
|
true
|
2018-01-12 11:49:53 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
// Save the account.
|
2018-01-22 05:44:24 -08:00
|
|
|
accountMapper.SetAccount(ctx, signerAcc)
|
2018-01-12 11:49:53 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
ctx = WithSigners(ctx, signerAccs)
|
2018-01-12 14:30:02 -08:00
|
|
|
return ctx, sdk.Result{}, false // continue...
|
2018-01-12 11:49:53 -08:00
|
|
|
}
|
|
|
|
}
|