syntax = "proto2";

package pubsub.pb;

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

	message SubOpts {
		optional bool subscribe = 1; // subscribe or unsubcribe
		optional string topicid = 2;
	}

	optional ControlMessage control = 3;
}

message Message {
	optional bytes from = 1;
	optional bytes data = 2;
	optional bytes seqno = 3;
	optional string topic = 4;
	optional bytes signature = 5;
	optional bytes key = 6;
}

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

message ControlIHave {
	optional string topicID = 1;
	// implementors from other languages should use bytes here - go protobuf emits invalid utf8 strings
	repeated string messageIDs = 2;
}

message ControlIWant {
	// implementors from other languages should use bytes here - go protobuf emits invalid utf8 strings
	repeated string messageIDs = 1;
}

message ControlGraft {
	optional string topicID = 1;
}

message ControlPrune {
	optional string topicID = 1;
	repeated PeerInfo peers = 2;
	optional uint64 backoff = 3;
}

message PeerInfo {
	optional bytes peerID = 1;
	optional bytes signedPeerRecord = 2;
}

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 keyHashes = 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
		}
	}
}
