-
Notifications
You must be signed in to change notification settings - Fork 57
/
contract_call.go
65 lines (55 loc) · 2.25 KB
/
contract_call.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
package keeper
import (
"bytes"
"encoding/hex"
"sort"
sdk "github.com/cosmos/cosmos-sdk/types"
sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
"github.com/peggyjv/gravity-bridge/module/v4/x/gravity/types"
)
func (k Keeper) GetUnsignedContractCallTxs(ctx sdk.Context, val sdk.ValAddress) []*types.ContractCallTx {
var unconfirmed []*types.ContractCallTx
k.IterateOutgoingTxsByType(ctx, types.ContractCallTxPrefixByte, func(_ []byte, otx types.OutgoingTx) bool {
sig := k.getEthereumSignature(ctx, otx.GetStoreIndex(), val)
if len(sig) == 0 {
call, ok := otx.(*types.ContractCallTx)
if !ok {
panic(sdkerrors.Wrapf(types.ErrInvalid, "couldn't cast to contract call for %s", otx))
}
unconfirmed = append(unconfirmed, call)
}
return false
})
return orderContractCallsByNonceAscending(unconfirmed)
}
func (k Keeper) contractCallExecuted(ctx sdk.Context, invalidationScope []byte, invalidationNonce uint64) {
otx := k.GetOutgoingTx(ctx, types.MakeContractCallTxKey(invalidationScope, invalidationNonce))
if otx == nil {
k.Logger(ctx).Error("Failed to clean contract calls",
"invalidation scope", hex.EncodeToString(invalidationScope),
"invalidation nonce", invalidationNonce)
return
}
completedCallTx, _ := otx.(*types.ContractCallTx)
k.IterateOutgoingTxsByType(ctx, types.ContractCallTxPrefixByte, func(key []byte, otx types.OutgoingTx) bool {
// If the iterated contract call's nonce is lower than the one that was just executed, delete it
cctx, ok := otx.(*types.ContractCallTx)
if !ok {
panic(sdkerrors.Wrapf(types.ErrInvalid, "couldn't cast to contract call tx for %s", otx))
}
if (cctx.InvalidationNonce < completedCallTx.InvalidationNonce) &&
bytes.Equal(cctx.InvalidationScope, completedCallTx.InvalidationScope) {
k.DeleteEthereumSignatures(ctx, cctx.GetStoreIndex())
k.DeleteOutgoingTx(ctx, cctx.GetStoreIndex())
}
return false
})
k.CompleteOutgoingTx(ctx, completedCallTx)
}
// orderContractCallsByNonceAscending sorts a slice of contract calls by nonce in ascending order
func orderContractCallsByNonceAscending(calls []*types.ContractCallTx) []*types.ContractCallTx {
sort.SliceStable(calls, func(i, j int) bool {
return calls[i].InvalidationNonce < calls[j].InvalidationNonce
})
return calls
}