forked from forbole/juno
-
Notifications
You must be signed in to change notification settings - Fork 0
/
account_parser.go
232 lines (178 loc) · 7.28 KB
/
account_parser.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
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
package messages
import (
"fmt"
"github.com/gogo/protobuf/proto"
crisistypes "github.com/cosmos/cosmos-sdk/x/crisis/types"
evidencetypes "github.com/cosmos/cosmos-sdk/x/evidence/types"
govtypes "github.com/cosmos/cosmos-sdk/x/gov/types"
slashingtypes "github.com/cosmos/cosmos-sdk/x/slashing/types"
ibctransfertypes "github.com/cosmos/ibc-go/v3/modules/apps/transfer/types"
channeltypes "github.com/cosmos/ibc-go/v3/modules/core/04-channel/types"
"github.com/cosmos/cosmos-sdk/codec"
sdk "github.com/cosmos/cosmos-sdk/types"
banktypes "github.com/cosmos/cosmos-sdk/x/bank/types"
distrtypes "github.com/cosmos/cosmos-sdk/x/distribution/types"
stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types"
)
// MessageNotSupported returns an error telling that the given message is not supported
func MessageNotSupported(msg sdk.Msg) error {
return fmt.Errorf("message type not supported: %s", proto.MessageName(msg))
}
// MessageAddressesParser represents a function that extracts all the
// involved addresses from a provided message (both accounts and validators)
type MessageAddressesParser = func(cdc codec.Codec, msg sdk.Msg) ([]string, error)
// JoinMessageParsers joins together all the given parsers, calling them in order
func JoinMessageParsers(parsers ...MessageAddressesParser) MessageAddressesParser {
return func(cdc codec.Codec, msg sdk.Msg) ([]string, error) {
for _, parser := range parsers {
// Try getting the addresses
addresses, _ := parser(cdc, msg)
// If some addresses are found, return them
if len(addresses) > 0 {
return addresses, nil
}
}
return nil, MessageNotSupported(msg)
}
}
// CosmosMessageAddressesParser represents a MessageAddressesParser that parses a
// Chain message and returns all the involved addresses (both accounts and validators)
var CosmosMessageAddressesParser = JoinMessageParsers(
BankMessagesParser,
CrisisMessagesParser,
DistributionMessagesParser,
EvidenceMessagesParser,
GovMessagesParser,
IBCTransferMessagesParser,
SlashingMessagesParser,
StakingMessagesParser,
DefaultMessagesParser,
)
// DefaultMessagesParser represents the default messages parser that simply returns the list
// of all the signers of a message
func DefaultMessagesParser(_ codec.Codec, cosmosMsg sdk.Msg) ([]string, error) {
var signers = make([]string, len(cosmosMsg.GetSigners()))
for index, signer := range cosmosMsg.GetSigners() {
signers[index] = signer.String()
}
return signers, nil
}
// BankMessagesParser returns the list of all the accounts involved in the given
// message if it's related to the x/bank module
func BankMessagesParser(_ codec.Codec, cosmosMsg sdk.Msg) ([]string, error) {
switch msg := cosmosMsg.(type) {
case *banktypes.MsgSend:
return []string{msg.ToAddress, msg.FromAddress}, nil
case *banktypes.MsgMultiSend:
var addresses []string
for _, i := range msg.Inputs {
addresses = append(addresses, i.Address)
}
for _, o := range msg.Outputs {
addresses = append(addresses, o.Address)
}
return addresses, nil
}
return nil, MessageNotSupported(cosmosMsg)
}
// CrisisMessagesParser returns the list of all the accounts involved in the given
// message if it's related to the x/crisis module
func CrisisMessagesParser(_ codec.Codec, cosmosMsg sdk.Msg) ([]string, error) {
switch msg := cosmosMsg.(type) {
case *crisistypes.MsgVerifyInvariant:
return []string{msg.Sender}, nil
}
return nil, MessageNotSupported(cosmosMsg)
}
// DistributionMessagesParser returns the list of all the accounts involved in the given
// message if it's related to the x/distribution module
func DistributionMessagesParser(_ codec.Codec, cosmosMsg sdk.Msg) ([]string, error) {
switch msg := cosmosMsg.(type) {
case *distrtypes.MsgSetWithdrawAddress:
return []string{msg.DelegatorAddress, msg.WithdrawAddress}, nil
case *distrtypes.MsgWithdrawDelegatorReward:
return []string{msg.DelegatorAddress, msg.ValidatorAddress}, nil
case *distrtypes.MsgWithdrawValidatorCommission:
return []string{msg.ValidatorAddress}, nil
case *distrtypes.MsgFundCommunityPool:
return []string{msg.Depositor}, nil
}
return nil, MessageNotSupported(cosmosMsg)
}
// EvidenceMessagesParser returns the list of all the accounts involved in the given
// message if it's related to the x/evidence module
func EvidenceMessagesParser(_ codec.Codec, cosmosMsg sdk.Msg) ([]string, error) {
switch msg := cosmosMsg.(type) {
case *evidencetypes.MsgSubmitEvidence:
return []string{msg.Submitter}, nil
}
return nil, MessageNotSupported(cosmosMsg)
}
// GovMessagesParser returns the list of all the accounts involved in the given
// message if it's related to the x/gov module
func GovMessagesParser(cdc codec.Codec, cosmosMsg sdk.Msg) ([]string, error) {
switch msg := cosmosMsg.(type) {
case *govtypes.MsgSubmitProposal:
addresses := []string{msg.Proposer}
var content govtypes.Content
err := cdc.UnpackAny(msg.Content, &content)
if err != nil {
return nil, err
}
// Get addresses from contents
switch content := content.(type) {
case *distrtypes.CommunityPoolSpendProposal:
addresses = append(addresses, content.Recipient)
}
return addresses, nil
case *govtypes.MsgDeposit:
return []string{msg.Depositor}, nil
case *govtypes.MsgVote:
return []string{msg.Voter}, nil
}
return nil, MessageNotSupported(cosmosMsg)
}
// IBCTransferMessagesParser returns the list of all the accounts involved in the given
// message if it's related to the x/iBCTransfer module
func IBCTransferMessagesParser(_ codec.Codec, cosmosMsg sdk.Msg) ([]string, error) {
switch msg := cosmosMsg.(type) {
case *ibctransfertypes.MsgTransfer:
return []string{msg.Sender, msg.Receiver}, nil
case *channeltypes.MsgRecvPacket:
var data ibctransfertypes.FungibleTokenPacketData
if err := ibctransfertypes.ModuleCdc.UnmarshalJSON(msg.Packet.Data, &data); err != nil {
// The packet data is not a FungibleTokenPacketData, so nothing to update
return nil, nil
}
// We are receiving some IBC tokens, so we need to update the receiver balance
// as well as the message signer (the relayer)
return []string{data.Receiver, msg.Signer}, nil
}
return nil, MessageNotSupported(cosmosMsg)
}
// SlashingMessagesParser returns the list of all the accounts involved in the given
// message if it's related to the x/slashing module
func SlashingMessagesParser(_ codec.Codec, cosmosMsg sdk.Msg) ([]string, error) {
switch msg := cosmosMsg.(type) {
case *slashingtypes.MsgUnjail:
return []string{msg.ValidatorAddr}, nil
}
return nil, MessageNotSupported(cosmosMsg)
}
// StakingMessagesParser returns the list of all the accounts involved in the given
// message if it's related to the x/staking module
func StakingMessagesParser(_ codec.Codec, cosmosMsg sdk.Msg) ([]string, error) {
switch msg := cosmosMsg.(type) {
case *stakingtypes.MsgCreateValidator:
return []string{msg.ValidatorAddress, msg.DelegatorAddress}, nil
case *stakingtypes.MsgEditValidator:
return []string{msg.ValidatorAddress}, nil
case *stakingtypes.MsgDelegate:
return []string{msg.DelegatorAddress, msg.ValidatorAddress}, nil
case *stakingtypes.MsgBeginRedelegate:
return []string{msg.DelegatorAddress, msg.ValidatorSrcAddress, msg.ValidatorDstAddress}, nil
case *stakingtypes.MsgUndelegate:
return []string{msg.DelegatorAddress, msg.ValidatorAddress}, nil
}
return nil, MessageNotSupported(cosmosMsg)
}