-
Notifications
You must be signed in to change notification settings - Fork 0
/
block_message_ids.go
109 lines (98 loc) · 3.41 KB
/
block_message_ids.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
package keeper
import (
errorsmod "cosmossdk.io/errors"
"github.com/cosmos/cosmos-sdk/store/prefix"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/furyanprotocol/v4-chain/protocol/lib"
"github.com/furyanprotocol/v4-chain/protocol/x/delaymsg/types"
)
// newBlockMessageIdsStore creates a new prefix store for BlockMessageIds.
func (k Keeper) newBlockMessageIdsStore(ctx sdk.Context) prefix.Store {
return prefix.NewStore(ctx.KVStore(k.storeKey), []byte(types.BlockMessageIdsPrefix))
}
// GetBlockMessageIds gets the ids of delayed messages to execute at a given block height.
// `found` is false is there is no delayed message for the given block height.
func (k Keeper) GetBlockMessageIds(
ctx sdk.Context,
blockHeight uint32,
) (
blockMessageIds types.BlockMessageIds,
found bool,
) {
store := k.newBlockMessageIdsStore(ctx)
b := store.Get(lib.Uint32ToKey(blockHeight))
if b == nil {
return types.BlockMessageIds{}, false
}
blockMessageIds = types.BlockMessageIds{}
k.cdc.MustUnmarshal(b, &blockMessageIds)
return blockMessageIds, true
}
// addMessageIdToBlock adds a message id to the list of message ids for a block height. This method should only
// be called from DelayMessageByBlocks whenever a new message is added. When this restriction is followed, the
// message ids for a block height will always be in ascending order.
func (k Keeper) addMessageIdToBlock(
ctx sdk.Context,
id uint32,
blockHeight uint32,
) {
store := k.newBlockMessageIdsStore(ctx)
var blockMessageIds types.BlockMessageIds
key := lib.Uint32ToKey(blockHeight)
if b := store.Get(key); b != nil {
k.cdc.MustUnmarshal(b, &blockMessageIds)
blockMessageIds.Ids = append(blockMessageIds.Ids, id)
} else {
blockMessageIds = types.BlockMessageIds{
Ids: []uint32{id},
}
}
store.Set(key, k.cdc.MustMarshal(&blockMessageIds))
}
// deleteMessageIdFromBlock deletes a message id from the list of message ids for a block. This method should
// only be called from DeleteMessage whenever a message is deleted. Message id removal assumes non-duplicate ids and
// respects the original ordering of message ids for a block, so if the message ids were already sorted, they will
// remain sorted.
func (k Keeper) deleteMessageIdFromBlock(
ctx sdk.Context,
id uint32,
blockHeight uint32,
) (
err error,
) {
blockMessageIds, found := k.GetBlockMessageIds(ctx, blockHeight)
if !found {
return errorsmod.Wrapf(
types.ErrInvalidInput,
"block %v not found",
blockHeight,
)
}
for i, blockMessageId := range blockMessageIds.Ids {
// Skip ids that don't match.
if blockMessageId != id {
continue
}
// Reconstruct the id list in the same order, with this id removed. This reconstruction of ids preserves the
// original ordering of ids.
blockMessageIds.Ids = append(blockMessageIds.Ids[:i], blockMessageIds.Ids[i+1:]...)
// If the remaining list of ids is empty, go ahead and delete the BlockMessageIds from the store.
if len(blockMessageIds.Ids) == 0 {
k.newBlockMessageIdsStore(ctx).Delete(lib.Uint32ToKey(blockHeight))
} else {
// Otherwise, update the BlockMessageIds to have the id of this delayed message removed.
k.newBlockMessageIdsStore(ctx).Set(
lib.Uint32ToKey(blockHeight),
k.cdc.MustMarshal(&blockMessageIds),
)
}
return nil
}
// If we make it here, the message id was not found in the block.
return errorsmod.Wrapf(
types.ErrInvalidInput,
"message id %v not found in block %v",
id,
blockHeight,
)
}