function verifyClientConsensusState(
connection: ConnectionEnd,
height: Height,
proof: CommitmentProof,
clientIdentifier: Identifier,
consensusStateHeight: Height,
consensusState: ConsensusState
) {
clientState = queryClientState(connection.clientIdentifier)
path = applyPrefix(connection.counterpartyPrefix, consensusStatePath(clientIdentifier, consensusStateHeight))
return verifyMembership(clientState, height, 0, 0, proof, path, consensusState)
}
function verifyClientState(
connection: ConnectionEnd,
height: Height,
proof: CommitmentProof,
clientState: ClientState
) {
clientState = queryClientState(connection.clientIdentifier)
path = applyPrefix(connection.counterpartyPrefix, clientStatePath(clientIdentifier)
return verifyMembership(clientState, height, 0, 0, proof, path, clientState)
}
function verifyConnectionState(
connection: ConnectionEnd,
height: Height,
proof: CommitmentProof,
connectionIdentifier: Identifier,
connectionEnd: ConnectionEnd
) {
clientState = queryClientState(connection.clientIdentifier)
path = applyPrefix(connection.counterpartyPrefix, connectionPath(connectionIdentifier))
return verifyMembership(clientState, height, 0, 0, proof, path, connectionEnd)
}
function verifyChannelState(
connection: ConnectionEnd,
height: Height,
proof: CommitmentProof,
portIdentifier: Identifier,
channelIdentifier: Identifier,
channelEnd: ChannelEnd
) {
clientState = queryClientState(connection.clientIdentifier)
path = applyPrefix(connection.counterpartyPrefix, channelPath(portIdentifier, channelIdentifier))
return verifyMembership(clientState, height, 0, 0, proof, path, channelEnd)
}
function verifyPacketCommitment(
connection: ConnectionEnd,
height: Height,
proof: CommitmentProof,
portIdentifier: Identifier,
channelIdentifier: Identifier,
sequence: uint64,
commitmentBytes: bytes
) {
clientState = queryClientState(connection.clientIdentifier)
path = applyPrefix(connection.counterpartyPrefix, packetCommitmentPath(portIdentifier, channelIdentifier, sequence))
return verifyMembership(clientState, height, connection.delayPeriodTime, connection.delayPeriodBlocks, proof, path, commitmentBytes)
}
function verifyPacketAcknowledgement(
connection: ConnectionEnd,
height: Height,
proof: CommitmentProof,
portIdentifier: Identifier,
channelIdentifier: Identifier,
sequence: uint64,
acknowledgement: bytes
) {
clientState = queryClientState(connection.clientIdentifier)
path = applyPrefix(connection.counterpartyPrefix, packetAcknowledgementPath(portIdentifier, channelIdentifier, sequence))
return verifyMembership(clientState, height, connection.delayPeriodTime, connection.delayPeriodBlocks, proof, path, acknowledgement)
}
function verifyPacketReceiptAbsence(
connection: ConnectionEnd,
height: Height,
proof: CommitmentProof,
portIdentifier: Identifier,
channelIdentifier: Identifier,
sequence: uint64
) {
clientState = queryClientState(connection.clientIdentifier)
path = applyPrefix(connection.counterpartyPrefix, packetReceiptPath(portIdentifier, channelIdentifier, sequence))
return verifyNonMembership(clientState, height, connection.delayPeriodTime, connection.delayPeriodBlocks, proof, path)
}
// OPTIONAL: verifyPacketReceipt is only required to support new channel types beyond ORDERED and UNORDERED.
function verifyPacketReceipt(
connection: ConnectionEnd,
height: Height,
proof: CommitmentProof,
portIdentifier: Identifier,
channelIdentifier: Identifier,
sequence: uint64,
receipt: bytes
) {
clientState = queryClientState(connection.clientIdentifier)
path = applyPrefix(connection.counterpartyPrefix, packetReceiptPath(portIdentifier, channelIdentifier, sequence))
return verifyMembership(clientState, height, connection.delayPeriodTime, connection.delayPeriodBlocks, connection.counterpartyPrefix, proof, portIdentifier, channelIdentifier, sequence, receipt)
}
function verifyNextSequenceRecv(
connection: ConnectionEnd,
height: Height,
proof: CommitmentProof,
portIdentifier: Identifier,
channelIdentifier: Identifier,
sequence: uint64,
nextSequenceRecv: uint64
) {
clientState = queryClientState(connection.clientIdentifier)
path = applyPrefix(connection.counterpartyPrefix, nextSequenceRecvPath(portIdentifier, channelIdentifier, sequence))
return verifyMembership(clientState, height, connection.delayPeriodTime, connection.delayPeriodBlocks, proof, path, nextSequenceRecv)
}
function verifyMultihopMembership(
connection: ConnectionEnd, // the connection end corresponding to the receiving chain.
height: Height,
proof: MultihopProof,
connectionHops: []Identifier,
key: CommitmentPath,
value: bytes
) {
// the connectionEnd corresponding to the end of the multi-hop channel path (sending/counterparty chain).
multihopConnectionEnd = abortTransactionUnless(getMultihopConnectionEnd(proof))
prefix = multihopConnectionEnd.GetCounterparty().GetPrefix()
client = queryClient(connection.clientIdentifier)
consensusState = queryConsensusState(connection.clientIdentifier, height)
abortTransactionUnless(client.Status() === "active")
abortTransactionUnless(client.GetLatestHeight() >= height)
// verify maximum delay period has passed
expectedTimePerBlock = queryMaxExpectedTimePerBlock()
delayPeriodTime = abortTransactionUnless(getMaximumDelayPeriod(proof, connection))
delayPeriodBlocks = getBlockDelay(delayPeriodTime, expectedTimePerBlock)
abortTransactionUnless(tendermint.VerifyDelayPeriodPassed(height, delayPeriodTime, delayPeriodBlocks))
return multihop.VerifyMultihopMembership(consensusState, connectionHops, proof, prefix, key, value) // see ics-033
}
function verifyMultihopNonMembership(
connection: ConnectionEnd, // the connection end corresponding to the receiving chain.
height: Height,
proof: MultihopProof,
connectionHops: Identifier[],
key: CommitmentPath
) {
// the connectionEnd corresponding to the end of the multi-hop channel path (sending/counterparty chain).
multihopConnectionEnd = abortTransactionUnless(getMultihopConnectionEnd(proof))
prefix = multihopConnectionEnd.GetCounterparty().GetPrefix()
client = queryClient(connection.clientIdentifier)
consensusState = queryConsensusState(connection.clientIdentifier, height)
abortTransactionUnless(client.Status() === "active")
abortTransactionUnless(client.GetLatestHeight() >= height)
// verify maximum delay period has passed
expectedTimePerBlock = queryMaxExpectedTimePerBlock()
delayPeriodTime = abortTransactionUnless(getMaximumDelayPeriod(proof, connection))
delayPeriodBlocks = getBlockDelay(delayPeriodTime, expectedTimePerBlock)
abortTransactionUnless(tendermint.VerifyDelayPeriodPassed(height, delayPeriodTime, delayPeriodBlocks))
return multihop.VerifyMultihopNonMembership(consensusState, connectionHops, proof, prefix, key) // see ics-033
}
// Return the maximum expected time per block from the paramstore.
// See 03-connection - GetMaxExpectedTimePerBlock.
function queryMaxExpectedTimePerBlock(): uint64
function getTimestampAtHeight(
connection: ConnectionEnd,
height: Height
) {
return queryConsensusState(connection.clientIdentifier, height).getTimestamp()
}
// Return the connectionEnd corresponding to the source chain.
function getMultihopConnectionEnd(proof: MultihopProof): ConnectionEnd {
return abortTransactionUnless(Unmarshal(proof.ConnectionProofs[proof.ConnectionProofs.length - 1].Value))
}
// Return the maximum delay period in seconds across all connections in the channel path.
function getMaximumDelayPeriod(proof: MultihopProof, lastConnection: ConnectionEnd): number {
delayPeriodTime = lastConnection.GetDelayPeriod()
for connData in range proofs.ConnectionProofs {
connectionEnd = abortTransactionUnless(Unmarshal(connData.Value))
if (connectionEnd.DelayPeriod > delayPeriodTime) {
delayPeriodTime = connectionEnd.DelayPeriod
}
}
return delayPeriodTime
}