syntax = "proto2";

package gossipsub.pb;

message RPC {
	repeated SubOpts subscriptions = 1;
	repeated Message publish = 2;

	message SubOpts {
		optional bool subscribe = 1; // subscribe or unsubscribe
		optional string topic_id = 2;
	}

	optional ControlMessage control = 3;
}

message Message {
	optional bytes from = 1;
	optional bytes data = 2;
	optional bytes seqno = 3;
	repeated string topic_ids = 4;
}

message ControlMessage {
	repeated ControlIHave ihave = 1;
	repeated ControlIWant iwant = 2;
	repeated ControlGraft graft = 3;
	repeated ControlPrune prune = 4;
}

message ControlIHave {
	optional string topic_id = 1;
	repeated string message_ids = 2;
}

message ControlIWant {
	repeated string message_ids= 1;
}

message ControlGraft {
	optional string topic_id = 1;
}

message ControlPrune {
	optional string topic_id = 1;
}

// topicID = hash(topicDescriptor); (not the topic.name)
message TopicDescriptor {
	optional string name = 1;
	optional AuthOpts auth = 2;
	optional EncOpts enc = 3;

	message AuthOpts {
		optional AuthMode mode = 1;
		repeated bytes keys = 2; // root keys to trust

		enum AuthMode {
			NONE = 0; // no authentication, anyone can publish
			KEY = 1; // only messages signed by keys in the topic descriptor are accepted
			WOT = 2; // web of trust, certificates can allow publisher set to grow
		}
	}

	message EncOpts {
		optional EncMode mode = 1;
		repeated bytes key_hashes = 2; // the hashes of the shared keys used (salted)

		enum EncMode {
			NONE = 0; // no encryption, anyone can read
			SHAREDKEY = 1; // messages are encrypted with shared key
			WOT = 2; // web of trust, certificates can allow publisher set to grow
		}
	}
}
