-
Notifications
You must be signed in to change notification settings - Fork 580
/
packet.go
135 lines (109 loc) · 4.5 KB
/
packet.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
package types
import (
"crypto/sha256"
"github.com/cosmos/cosmos-sdk/codec"
sdk "github.com/cosmos/cosmos-sdk/types"
sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
clienttypes "github.com/cosmos/ibc-go/v7/modules/core/02-client/types"
host "github.com/cosmos/ibc-go/v7/modules/core/24-host"
"github.com/cosmos/ibc-go/v7/modules/core/exported"
)
// CommitPacket returns the packet commitment bytes. The commitment consists of:
// sha256_hash(timeout_timestamp + timeout_height.RevisionNumber + timeout_height.RevisionHeight + sha256_hash(data))
// from a given packet. This results in a fixed length preimage.
// NOTE: sdk.Uint64ToBigEndian sets the uint64 to a slice of length 8.
func CommitPacket(cdc codec.BinaryCodec, packet exported.PacketI) []byte {
timeoutHeight := packet.GetTimeoutHeight()
buf := sdk.Uint64ToBigEndian(packet.GetTimeoutTimestamp())
revisionNumber := sdk.Uint64ToBigEndian(timeoutHeight.GetRevisionNumber())
buf = append(buf, revisionNumber...)
revisionHeight := sdk.Uint64ToBigEndian(timeoutHeight.GetRevisionHeight())
buf = append(buf, revisionHeight...)
dataHash := sha256.Sum256(packet.GetData())
buf = append(buf, dataHash[:]...)
hash := sha256.Sum256(buf)
return hash[:]
}
// CommitAcknowledgement returns the hash of commitment bytes
func CommitAcknowledgement(data []byte) []byte {
hash := sha256.Sum256(data)
return hash[:]
}
var _ exported.PacketI = (*Packet)(nil)
// NewPacket creates a new Packet instance. It panics if the provided
// packet data interface is not registered.
func NewPacket(
data []byte,
sequence uint64, sourcePort, sourceChannel,
destinationPort, destinationChannel string,
timeoutHeight clienttypes.Height, timeoutTimestamp uint64,
) Packet {
return Packet{
Data: data,
Sequence: sequence,
SourcePort: sourcePort,
SourceChannel: sourceChannel,
DestinationPort: destinationPort,
DestinationChannel: destinationChannel,
TimeoutHeight: timeoutHeight,
TimeoutTimestamp: timeoutTimestamp,
}
}
// GetSequence implements PacketI interface
func (p Packet) GetSequence() uint64 { return p.Sequence }
// GetSourcePort implements PacketI interface
func (p Packet) GetSourcePort() string { return p.SourcePort }
// GetSourceChannel implements PacketI interface
func (p Packet) GetSourceChannel() string { return p.SourceChannel }
// GetDestPort implements PacketI interface
func (p Packet) GetDestPort() string { return p.DestinationPort }
// GetDestChannel implements PacketI interface
func (p Packet) GetDestChannel() string { return p.DestinationChannel }
// GetData implements PacketI interface
func (p Packet) GetData() []byte { return p.Data }
// GetTimeoutHeight implements PacketI interface
func (p Packet) GetTimeoutHeight() exported.Height { return p.TimeoutHeight }
// GetTimeoutTimestamp implements PacketI interface
func (p Packet) GetTimeoutTimestamp() uint64 { return p.TimeoutTimestamp }
// ValidateBasic implements PacketI interface
func (p Packet) ValidateBasic() error {
if err := host.PortIdentifierValidator(p.SourcePort); err != nil {
return sdkerrors.Wrap(err, "invalid source port ID")
}
if err := host.PortIdentifierValidator(p.DestinationPort); err != nil {
return sdkerrors.Wrap(err, "invalid destination port ID")
}
if err := host.ChannelIdentifierValidator(p.SourceChannel); err != nil {
return sdkerrors.Wrap(err, "invalid source channel ID")
}
if err := host.ChannelIdentifierValidator(p.DestinationChannel); err != nil {
return sdkerrors.Wrap(err, "invalid destination channel ID")
}
if p.Sequence == 0 {
return sdkerrors.Wrap(ErrInvalidPacket, "packet sequence cannot be 0")
}
if p.TimeoutHeight.IsZero() && p.TimeoutTimestamp == 0 {
return sdkerrors.Wrap(ErrInvalidPacket, "packet timeout height and packet timeout timestamp cannot both be 0")
}
if len(p.Data) == 0 {
return sdkerrors.Wrap(ErrInvalidPacket, "packet data bytes cannot be empty")
}
return nil
}
// Validates a PacketId
func (p PacketId) Validate() error {
if err := host.PortIdentifierValidator(p.PortId); err != nil {
return sdkerrors.Wrap(err, "invalid source port ID")
}
if err := host.ChannelIdentifierValidator(p.ChannelId); err != nil {
return sdkerrors.Wrap(err, "invalid source channel ID")
}
if p.Sequence == 0 {
return sdkerrors.Wrap(ErrInvalidPacket, "packet sequence cannot be 0")
}
return nil
}
// NewPacketID returns a new instance of PacketId
func NewPacketID(portID, channelID string, seq uint64) PacketId {
return PacketId{PortId: portID, ChannelId: channelID, Sequence: seq}
}