/
packet.go
112 lines (92 loc) · 3.89 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
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/cosmos-sdk/x/ibc/core/02-client/types"
host "github.com/cosmos/cosmos-sdk/x/ibc/core/24-host"
"github.com/cosmos/cosmos-sdk/x/ibc/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.BinaryMarshaler, 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
}