-
Notifications
You must be signed in to change notification settings - Fork 12
/
msg_server.go
129 lines (107 loc) · 4.59 KB
/
msg_server.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
package keeper
import (
"context"
"encoding/hex"
"fmt"
sdk "github.com/cosmos/cosmos-sdk/types"
sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
crosschainkeeper "github.com/functionx/fx-core/v3/x/crosschain/keeper"
crosschaintypes "github.com/functionx/fx-core/v3/x/crosschain/types"
trontypes "github.com/functionx/fx-core/v3/x/tron/types"
)
var _ crosschaintypes.MsgServer = msgServer{}
type msgServer struct {
crosschainkeeper.MsgServer
}
// NewMsgServerImpl returns an implementation of the gov MsgServer interface
// for the provided Keeper.
func NewMsgServerImpl(keeper Keeper) crosschaintypes.MsgServer {
return &msgServer{crosschainkeeper.MsgServer{Keeper: keeper.Keeper}}
}
// ConfirmBatch handles MsgConfirmBatch
func (s msgServer) ConfirmBatch(c context.Context, msg *crosschaintypes.MsgConfirmBatch) (*crosschaintypes.MsgConfirmBatchResponse, error) {
bridgerAddr, err := sdk.AccAddressFromBech32(msg.BridgerAddress)
if err != nil {
return nil, sdkerrors.Wrap(crosschaintypes.ErrInvalid, "bridger address")
}
ctx := sdk.UnwrapSDKContext(c)
// fetch the outgoing batch given the nonce
batch := s.GetOutgoingTxBatch(ctx, msg.TokenContract, msg.Nonce)
if batch == nil {
return nil, sdkerrors.Wrap(crosschaintypes.ErrInvalid, "couldn't find batch")
}
checkpoint, err := trontypes.GetCheckpointConfirmBatch(batch, s.GetGravityID(ctx))
if err != nil {
return nil, sdkerrors.Wrap(crosschaintypes.ErrInvalid, "checkpoint generation")
}
oracleAddr, err := s.confirmHandlerCommon(ctx, bridgerAddr, msg.ExternalAddress, msg.Signature, checkpoint)
if err != nil {
return nil, err
}
// check if we already have this confirm
if s.GetBatchConfirm(ctx, msg.TokenContract, msg.Nonce, oracleAddr) != nil {
return nil, sdkerrors.Wrap(crosschaintypes.ErrDuplicate, "signature")
}
s.SetBatchConfirm(ctx, oracleAddr, msg)
ctx.EventManager().EmitEvent(sdk.NewEvent(
sdk.EventTypeMessage,
sdk.NewAttribute(sdk.AttributeKeyModule, msg.ChainName),
sdk.NewAttribute(sdk.AttributeKeySender, msg.BridgerAddress),
))
return &crosschaintypes.MsgConfirmBatchResponse{}, nil
}
// OracleSetConfirm handles MsgOracleSetConfirm
func (s msgServer) OracleSetConfirm(c context.Context, msg *crosschaintypes.MsgOracleSetConfirm) (*crosschaintypes.MsgOracleSetConfirmResponse, error) {
bridgerAddr, err := sdk.AccAddressFromBech32(msg.BridgerAddress)
if err != nil {
return nil, sdkerrors.Wrap(crosschaintypes.ErrInvalid, "bridger address")
}
ctx := sdk.UnwrapSDKContext(c)
oracleSet := s.GetOracleSet(ctx, msg.Nonce)
if oracleSet == nil {
return nil, sdkerrors.Wrap(crosschaintypes.ErrInvalid, "couldn't find oracleSet")
}
checkpoint, err := trontypes.GetCheckpointOracleSet(oracleSet, s.GetGravityID(ctx))
if err != nil {
return nil, err
}
oracleAddr, err := s.confirmHandlerCommon(ctx, bridgerAddr, msg.ExternalAddress, msg.Signature, checkpoint)
if err != nil {
return nil, err
}
// check if we already have this confirm
if s.GetOracleSetConfirm(ctx, msg.Nonce, oracleAddr) != nil {
return nil, sdkerrors.Wrap(crosschaintypes.ErrDuplicate, "signature")
}
s.SetOracleSetConfirm(ctx, oracleAddr, msg)
ctx.EventManager().EmitEvent(sdk.NewEvent(
sdk.EventTypeMessage,
sdk.NewAttribute(sdk.AttributeKeyModule, msg.ChainName),
sdk.NewAttribute(sdk.AttributeKeySender, msg.BridgerAddress),
))
return &crosschaintypes.MsgOracleSetConfirmResponse{}, nil
}
func (s msgServer) confirmHandlerCommon(ctx sdk.Context, bridgerAddr sdk.AccAddress, signatureAddr, signature string, checkpoint []byte) (oracleAddr sdk.AccAddress, err error) {
sigBytes, err := hex.DecodeString(signature)
if err != nil {
return nil, sdkerrors.Wrap(crosschaintypes.ErrInvalid, "signature decoding")
}
oracleAddr, found := s.GetOracleByExternalAddress(ctx, signatureAddr)
if !found {
return nil, crosschaintypes.ErrNoFoundOracle
}
oracle, found := s.GetOracle(ctx, oracleAddr)
if !found {
return nil, crosschaintypes.ErrNoFoundOracle
}
if oracle.ExternalAddress != signatureAddr {
return nil, sdkerrors.Wrapf(crosschaintypes.ErrInvalid, "got %s, expected %s", signatureAddr, oracle.ExternalAddress)
}
if oracle.BridgerAddress != bridgerAddr.String() {
return nil, sdkerrors.Wrapf(crosschaintypes.ErrInvalid, "got %s, expected %s", bridgerAddr, oracle.BridgerAddress)
}
if err = trontypes.ValidateTronSignature(checkpoint, sigBytes, oracle.ExternalAddress); err != nil {
return nil, sdkerrors.Wrap(crosschaintypes.ErrInvalid, fmt.Sprintf("signature verification failed expected sig by %s with checkpoint %s found %s", oracle.ExternalAddress, hex.EncodeToString(checkpoint), signature))
}
return oracle.GetOracle(), nil
}