Skip to content

Commit

Permalink
Added protobuf specifications for ibc messages
Browse files Browse the repository at this point in the history
  • Loading branch information
ethanfrey authored and cwgoes committed Apr 17, 2018
1 parent f403353 commit 06ec4b4
Show file tree
Hide file tree
Showing 5 changed files with 173 additions and 0 deletions.
1 change: 1 addition & 0 deletions docs/spec/ibc/protobuf/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
*.pb.go
7 changes: 7 additions & 0 deletions docs/spec/ibc/protobuf/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
.PHONEY: proto test

proto:
protoc --gogo_out=. *.proto

test: proto
go install .
79 changes: 79 additions & 0 deletions docs/spec/ibc/protobuf/merkle.proto
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
syntax = "proto3";

package protobuf;


// HashOp is the hashing algorithm we use at each level
enum HashOp {
RIPEMD160 = 0;
SHA224 = 1;
SHA256 = 2;
SHA384 = 3;
SHA512 = 4;
SHA3_224 = 5;
SHA3_256 = 6;
SHA3_384 = 7;
SHA3_512 = 8;
SHA256_X2 = 9;
};

// Op represents one hash in a chain of hashes.
// An operation takes the output of the last level and returns
// a hash for the next level:
// Op(last) => Operation(prefix + last + sufix)
//
// A simple left/right hash would simply set prefix=left or
// suffix=right and leave the other blank. However, one could
// also represent the a Patricia trie proof by setting
// prefix to the rlp encoding of all nodes before the branch
// we select, and suffix to all those after the one we select.
message Op {
bytes prefix = 1;
bytes suffix = 2;
HashOp op = 3;
}

// Data is the end value stored,
// used to generate the initial hash store
message Data {
// optional prefix allows second preimage resistance
bytes prefix = 1;
bytes key = 2;
bytes value = 3;
HashOp op = 4;
// If it is KeyValue, this is the data we want
// If it is SubTree, key is name of the tree,
// value is root hash
enum DataType {
KeyValue = 0;
SubTree = 1;
}
DataType dataType = 5;
}

// Branch will hash data and then pass it through operations
// from first to last in order to calculate the root node.
//
// Visualize Branch as representing the data closest to
// root as the first item, and the leaf as the last item.
message Branch {
// if either are non-empty, enforce this prefix on all
// leaf/inner nodes to provide second preimage resistence
bytes prefixLeaf = 1;
bytes prefixInner = 2;
// this is the data to get the original hash,
// and a set of operations to calculate the root hash
Data data = 3;
repeated Op operations = 4;
}

message MerkleProof {
// TODO: root, height, chain_id, etc...

// branches start from the value, and then may
// include multiple subtree branches to embed it
//
// The first branch must have dataType KeyValue
// Following branches must have dataType SubTree
repeated Branch branches = 1;
}
29 changes: 29 additions & 0 deletions docs/spec/ibc/protobuf/messages.proto
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
syntax = "proto3";

package protobuf;

import "merkle.proto";


// IBCPacket sends a proven key/value pair from an IBCQueue.
// Depending on the type of message, we require a certain type
// of key (MessageKey at a given height, or StateKey).
//
// Includes src_chain and src_height to look up the proper
// header to verify the merkle proof.
message IBCPacket {
// chain id it is coming from
string src_chain = 1;
// height for the header the proof belongs to
uint64 src_height = 2;
// the message type, which determines what key/value mean
enum MsgType {
RECEIVE = 0;
RECEIPT = 1;
TIMEOUT = 2;
CLEANUP = 3;
}
MsgType msgType = 3;
// the proof of the message, includes key and value
MerkleProof proof = 6;
}
57 changes: 57 additions & 0 deletions docs/spec/ibc/protobuf/queue.proto
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
syntax = "proto3";

package protobuf;

import "google/protobuf/timestamp.proto";

message QueueName {
// chain_id is which chain this queue is
// associated with
string chain_id = 1;
enum Purpose {
SEND = 0;
RECEIPT = 1;
}
Purpose purpose = 2;
}

// StateKey is a key for the head/tail of a given queue
message StateKey {
QueueName queue = 1;
// both encode into one byte with varint encoding
// never clash with 8 byte message indexes
enum State {
HEAD = 0;
TAIL = 0x7f;
}
State state = 2;
}

// StateValue is the type stored under a StateKey
message StateValue {
fixed64 index = 1;
}

// MessageKey is the key for message *index* in a given queue
message MessageKey {
QueueName queue = 1;
fixed64 index = 2;
}

// SendValue is stored under a MessageKey in the SEND queue
message SendValue {
uint64 maxHeight = 1;
google.protobuf.Timestamp maxTime = 2;
// use kind instead of type to avoid keyword conflict
bytes kind = 3;
bytes data = 4;
}

// ReceiptValue is stored under a MessageKey in the RECEIPT queue
message ReceiptValue {
// 0 is success, others are application-defined errors
int32 errorCode = 1;
// contains result on success, optional info on error
bytes data = 2;
}

0 comments on commit 06ec4b4

Please sign in to comment.