-
Notifications
You must be signed in to change notification settings - Fork 368
/
authorized.go
63 lines (54 loc) · 2.19 KB
/
authorized.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
package ante
import (
sdk "github.com/cosmos/cosmos-sdk/types"
sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
authtypes "github.com/cosmos/cosmos-sdk/x/auth/types"
)
var _ sigVerifiableTx = (*authtypes.StdTx)(nil) // assert StdTx implements SigVerifiableTx
// SigVerifiableTx defines a Tx interface for all signature verification decorators
type sigVerifiableTx interface {
GetSigners() []sdk.AccAddress
}
// AddressFetcher is a type signature for functions used by the AuthenticatedMempoolDecorator to get authorized addresses.
type AddressFetcher func(sdk.Context) []sdk.AccAddress
// AuthenticatedMempoolDecorator blocks all txs from reaching the mempool unless they're signed by one of the authorzed addresses.
// It only runs before entry to mempool (CheckTx), and not in consensus (DeliverTx)
type AuthenticatedMempoolDecorator struct {
addressFetchers []AddressFetcher
}
func NewAuthenticatedMempoolDecorator(fetchers ...AddressFetcher) AuthenticatedMempoolDecorator {
return AuthenticatedMempoolDecorator{
addressFetchers: fetchers,
}
}
func (amd AuthenticatedMempoolDecorator) AnteHandle(ctx sdk.Context, tx sdk.Tx, simulate bool, next sdk.AnteHandler) (newCtx sdk.Context, err error) {
// This is only for local mempool purposes, and thus is only run on check tx.
if ctx.IsCheckTx() && !simulate {
sigTx, ok := tx.(sigVerifiableTx)
if !ok {
return ctx, sdkerrors.Wrap(sdkerrors.ErrTxDecode, "tx must be sig verifiable tx")
}
if !commonAddressesExist(sigTx.GetSigners(), amd.fetchAuthorizedAddresses(ctx)) {
return ctx, sdkerrors.Wrap(sdkerrors.ErrUnauthorized, "tx contains no signers authorized for this mempool")
}
}
return next(ctx, tx, simulate)
}
func (amd AuthenticatedMempoolDecorator) fetchAuthorizedAddresses(ctx sdk.Context) []sdk.AccAddress {
addrs := []sdk.AccAddress{}
for _, fetch := range amd.addressFetchers {
addrs = append(addrs, fetch(ctx)...)
}
return addrs
}
// commonAddressesExist checks if there is any intersection between two lists of addresses
func commonAddressesExist(addresses1, addresses2 []sdk.AccAddress) bool {
for _, a1 := range addresses1 {
for _, a2 := range addresses2 {
if a1.Equals(a2) {
return true
}
}
}
return false
}