Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add IBC prefix for ics-08 clients and bugfixes #826

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ static void setup() throws Exception {
@Test
@Order(0)
void registerClient() {
getClientInterface(owner).registerClient(clientType, mockLightClient._address());
getClientInterface(owner).registerClient(clientType, mockLightClient._address(), 0);
}

@Test
Expand Down
Original file line number Diff line number Diff line change
@@ -1,17 +1,18 @@
package ibc.ics03.connection;

import java.math.BigInteger;
import java.util.Arrays;
import java.util.List;

import icon.proto.core.client.Height;
import icon.proto.core.connection.ConnectionEnd;
import icon.proto.core.connection.Counterparty;
import icon.proto.core.connection.Version;
import ibc.core.commitment.v1.MerklePrefix;
import ibc.icon.score.util.ByteUtil;
import ibc.icon.score.util.Logger;
import ibc.ics02.client.IBCClient;
import ibc.ics24.host.IBCCommitment;
import ibc.ics24.host.IBCHost;
import icon.ibc.interfaces.ILightClient;
import icon.ibc.structs.messages.MsgConnectionOpenAck;
import icon.ibc.structs.messages.MsgConnectionOpenConfirm;
Expand All @@ -24,6 +25,12 @@ public class IBCConnection extends IBCClient {
public static final String v1Identifier = "1";
public static final List<String> supportedV1Features = List.of("ORDER_ORDERED", "ORDER_UNORDERED");

public static final MerklePrefix ICS08PREFIX = new MerklePrefix();
static {
ICS08PREFIX.setKeyPrefix("ibc".getBytes());

}

Logger logger = new Logger("ibc-core");

public String _connectionOpenInit(MsgConnectionOpenInit msg) {
Expand Down Expand Up @@ -67,6 +74,9 @@ public String _connectionOpenTry(MsgConnectionOpenTry msg) {
Counterparty expectedCounterparty = new Counterparty();
expectedCounterparty.setClientId(msg.getClientId());
expectedCounterparty.setConnectionId("");
if (IBCCommitment.getHashType(msg.getClientId()) == IBCHost.HashType.ICS08.type) {
expectedCounterparty.setPrefix(ICS08PREFIX);
}

ConnectionEnd expectedConnection = new ConnectionEnd();
expectedConnection.setClientId(counterparty.getClientId());
Expand Down Expand Up @@ -108,6 +118,9 @@ public byte[] _connectionOpenAck(MsgConnectionOpenAck msg) {
Counterparty expectedCounterparty = new Counterparty();
expectedCounterparty.setClientId(connection.getClientId());
expectedCounterparty.setConnectionId(msg.getConnectionId());
if (IBCCommitment.getHashType(connection.getClientId()) == IBCHost.HashType.ICS08.type) {
expectedCounterparty.setPrefix(ICS08PREFIX);
}

ConnectionEnd expectedConnection = new ConnectionEnd();
expectedConnection.setClientId(connection.getCounterparty().getClientId());
Expand Down Expand Up @@ -150,6 +163,9 @@ public byte[] _connectionOpenConfirm(MsgConnectionOpenConfirm msg) {
Counterparty expectedCounterparty = new Counterparty();
expectedCounterparty.setClientId(connection.getClientId());
expectedCounterparty.setConnectionId(msg.getConnectionId());
if (IBCCommitment.getHashType(connection.getClientId()) == IBCHost.HashType.ICS08.type) {
expectedCounterparty.setPrefix(ICS08PREFIX);
}

ConnectionEnd expectedConnection = new ConnectionEnd();
expectedConnection.setClientId(connection.getCounterparty().getClientId());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -181,12 +181,13 @@ public void _acknowledgePacket(Packet packet, byte[] acknowledgement, byte[] pro

byte[] packetAckPath = IBCCommitment.packetAcknowledgementCommitmentPath(packet.getDestinationPort(),
packet.getDestinationChannel(), packet.getSequence());
byte[] commitmentBytes = createAcknowledgmentCommitmentBytes(connection.getClientId(), acknowledgement);
verifyPacketAcknowledgement(
connection,
proofHeight,
proof,
packetAckPath,
acknowledgement);
commitmentBytes);

if (channel.getOrdering() == Channel.Order.ORDER_ORDERED) {
DictDB<String, BigInteger> nextSequenceAckSourcePort = nextSequenceAcknowledgements
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ public class Merkle {
Proof.getTendermintSpec()
);

public static MerklePath applyPrefix(String path, String prefix) {
public static MerklePath applyPrefix(String prefix, String path) {
var mpath = new MerklePath();
List<String> keyPath = new ArrayList<>();
keyPath.add(prefix);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ public static BigInteger getTotalVotingPower(ValidatorSet validatorSet) {
}

public static BigInteger getRevisionNumber(String chainId) {
int id = chainId.indexOf("-");
int id = chainId.lastIndexOf("-");
if (id >= 0) {
return new BigInteger(chainId.substring(id+1));
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -213,7 +213,7 @@ public void verifyMembership(

var root = consensusState.getRoot();
var merkleProof = MerkleProof.decode(proof);
var merklePath = applyPrefix(new String(path), StringUtil.bytesToHex("wasm".getBytes()));
var merklePath = applyPrefix(StringUtil.bytesToHex("wasm".getBytes()), new String(path));

Merkle.verifyMembership(merkleProof, Merkle.SDK_SPEC, root, merklePath, value);
}
Expand All @@ -240,7 +240,7 @@ public void verifyNonMembership(

var root = consensusState.getRoot();
var merkleProof = MerkleProof.decode(proof);
var merklePath = applyPrefix(new String(path), StringUtil.bytesToHex("wasm".getBytes()));
var merklePath = applyPrefix(StringUtil.bytesToHex("wasm".getBytes()), new String(path));

Merkle.verifyNonMembership(merkleProof, Merkle.SDK_SPEC, root, merklePath);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -170,7 +170,7 @@ public static byte[] encodeBooleanArray(int order, List<Boolean> items) {
}

public static byte[] encode(int order, Boolean item) {
if (item == null) {
if (item == null || item == false) {
return new byte[0];
}

Expand Down
206 changes: 206 additions & 0 deletions proto/clients/tendermint/TendermintLight.proto
Original file line number Diff line number Diff line change
@@ -0,0 +1,206 @@
syntax = "proto3";
package tendermint.light;

option go_package = "libraries/go/common/tendermint;tendermint";
import "gogoproto/gogo.proto";

message Fraction {
uint64 numerator = 1;
uint64 denominator = 2;
}

// https://developers.google.com/protocol-buffers/docs/reference/google.protobuf#google.protobuf.Timestamp
message Duration {
int64 seconds = 1;
int32 nanos = 2;
}

message Consensus {
uint64 block = 1;
uint64 app = 2;
}

message ClientState {
option (gogoproto.goproto_getters) = false;

string chain_id = 1;
Fraction trust_level = 2;

// duration of the period since the LastestTimestamp during which the
// submitted headers are valid for upgrade
Duration trusting_period = 3;
// duration of the staking unbonding period
Duration unbonding_period = 4;
// defines how much new (untrusted) header's Time can drift into the future.
Duration max_clock_drift = 5;
// Block height when the client was frozen due to a misbehaviour
//ibc.core.client.v1.Height frozen_height = 6;
int64 frozen_height = 6;
// Latest height the client was updated to
int64 latest_height = 7;
// This flag, when set to true, will allow governance to recover a client
// which has expired
bool allow_update_after_expiry = 8;
// This flag, when set to true, will allow governance to unfreeze a client
// whose chain has experienced a misbehaviour event
bool allow_update_after_misbehaviour = 9;
}

// ConsensusState defines the consensus state from Tendermint.
message ConsensusState {
option (gogoproto.goproto_getters) = false;
// timestamp that corresponds to the block height in which the ConsensusState
// was stored.
Timestamp timestamp = 1;

// commitment root (i.e app hash)
MerkleRoot root = 2;
bytes next_validators_hash = 3;
}

// MerkleRoot defines a merkle root hash.
// In the Cosmos SDK, the AppHash of a block header becomes the root.
message MerkleRoot {
bytes hash = 1;
}

enum BlockIDFlag {
BLOCK_ID_FLAG_UNKNOWN = 0;
BLOCK_ID_FLAG_ABSENT = 1;
BLOCK_ID_FLAG_COMMIT = 2;
BLOCK_ID_FLAG_NIL = 3;
}

enum SignedMsgType {
SIGNED_MSG_TYPE_UNKNOWN = 0;
// Votes
SIGNED_MSG_TYPE_PREVOTE = 1;
SIGNED_MSG_TYPE_PRECOMMIT = 2;

// Proposals
SIGNED_MSG_TYPE_PROPOSAL = 32;
}

message CanonicalPartSetHeader {
uint32 total = 1;
bytes hash = 2;
}

message CanonicalBlockID {
bytes hash = 1;
CanonicalPartSetHeader part_set_header = 2;
}

message CanonicalVote {
SignedMsgType type = 1;
sfixed64 height = 2;
sfixed64 round = 3;
BlockID block_id = 4;
Timestamp timestamp = 5;
string chain_id = 6;
}

message Vote {
SignedMsgType type = 1;
int64 height = 2;
int32 round = 3;
BlockID block_id = 4;
Timestamp timestamp = 5;
bytes validator_address = 6;
int32 validator_index = 7;
bytes signature = 8;
}

message ValidatorSet {
repeated Validator validators = 1;
Validator proposer = 2;
int64 total_voting_power = 3;
}

message Validator {
bytes address = 1;
PublicKey pub_key = 2;
int64 voting_power = 3;
int64 proposer_priority = 4;
}

message SimpleValidator {
PublicKey pub_key = 1;
int64 voting_power = 2;
}

message PublicKey {
oneof sum {
bytes ed25519 = 1;
bytes secp256k1 = 2;
bytes sr25519 = 3;
}
}

message PartSetHeader {
uint32 total = 1;
bytes hash= 2;
}

message BlockID {
bytes hash = 1;
PartSetHeader part_set_header = 2;
}

message Commit {
int64 height = 1;
int32 round = 2;
BlockID block_id = 3;
repeated CommitSig signatures = 4;
}

// CommitSig is a part of the Vote included in a Commit.
message CommitSig {
BlockIDFlag block_id_flag = 1;
bytes validator_address = 2;
Timestamp timestamp = 3;
bytes signature = 4;
}

message Timestamp {
// Represents seconds of UTC time since Unix epoch
// 1970-01-01T00:00:00Z. Must be from 0001-01-01T00:00:00Z to
// 9999-12-31T23:59:59Z inclusive.
int64 seconds = 1;

// Non-negative fractions of a second at nanosecond resolution. Negative
// second values with fractions must still have non-negative nanos values
// that count forward in time. Must be from 0 to 999,999,999
// inclusive.
int32 nanos = 2;
}

message LightHeader {
Consensus version = 1;
string chain_id = 2;
int64 height = 3;
Timestamp time = 4;
BlockID last_block_id = 5;
bytes last_commit_hash = 6; // commit from validators from the last block
bytes data_hash = 7; // transactions
bytes validators_hash = 8; // validators for the current block
bytes next_validators_hash = 9; // validators for the next block
bytes consensus_hash = 10; // consensus params for current block
bytes app_hash = 11; // state after txs from the previous block
bytes last_results_hash = 12; // root hash of all results from the txs from the previous block
bytes evidence_hash = 13; // evidence included in the block
bytes proposer_address = 14; // original proposer of the block
}

message SignedHeader {
LightHeader header = 1;
Commit commit = 2;
}

message TmHeader {
SignedHeader signed_header = 1;
ValidatorSet validator_set = 2;

int64 trusted_height = 3;
ValidatorSet trusted_validators = 4;
}
Loading