Skip to content

Commit c7d9a8e

Browse files
robinbryceRobin Bryce
andauthored
adds the forestrie confirm message (#13)
* Adds MerkleLogConfirm &Adds MerkleLogConfirmMessage * Adds MerkleLogUnequivocal & MerkleLogUnequivocalMessage (currently empty, just claims the pb ordinals we know we will need) * Removes MerkleLogCommitMongoDB * Removes log version, log epoch and massif index. All of which are harmful to our strategy for managing the backing storage. See https://github.com/datatrails/ epic-8120-scalable-proof-mechanisms/ blob/e38ca5e050356a47028b1d2b47bb6f02ff6c5c3c/mmr/ forestrie-mmrblobs.md#changing-the-massifheight-for-a-log for important context * Adds EventResponseJSONAPI, which largely duplicates EventResponse but importantly, supports decoding the format the *customer* will see from our apis. The duplication is unfortunate, but it means we can stop having ad-hoc soultions to this problem in all our go-lang based demo code. It also means the data can be reliably decoded with protojson. the generic json unmarshal fails to deal with 64 bit unsigned integers (and other numbers) correctly for example. Put EventResponseJSONAPI in its own file And add appropriate file comments for both eventresponse.proto and eventresponsejsonapi.proto AB#8336 Co-authored-by: Robin Bryce <[email protected]>
1 parent 73f875c commit c7d9a8e

File tree

3 files changed

+246
-54
lines changed

3 files changed

+246
-54
lines changed

datatrails-common-api/assets/v2/assets/eventresponse.proto

Lines changed: 17 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,10 @@
11
// Maintainers, please refer to the style guide here:
22
// https://developers.google.com/protocol-buffers/docs/style
3+
// Provides our internal, native, event response data. The data that is returned
4+
// over our apis doe NOT fit this shape. To marshal api data into a golang type,
5+
// see EventResponseJSONAPI instead.
6+
// The EventResponse message here MUST be kept up to date with EventResponseJSONAPI
7+
38
syntax = "proto3";
49
package archivist.v2;
510
option go_package="github.com/datatrails/go-datatrails-common-api-gen/assets/v2/assets;assets";
@@ -168,19 +173,18 @@ message EventResponse {
168173
max_length: 1024
169174
}];
170175

171-
// An event has exactly one proof mechanism. This field caputures the proof
172-
// mechanism specific details supporting the trustworthyness of the event
173-
// record. We anticipate at least two proof mechs: merkle_log and
174-
// verkle_log. We use oneof to avoid repeating the scattering of randomly
175-
// re-purposed fields we currently have for simple hash vs khipu.
176-
176+
// An event has exactly one proof mechanism. On any event only the entry
177+
// corresponding to the chosen proof mechanism will be present. (Note that
178+
// onfof exposes us to to many tooling compatibility issues)
177179

178180
// proof details for proof_mechanism MERKLE_LOG
179-
MerkleLogEntry merklelog_entry = 19 [ (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {
180-
description:
181-
"verifiable merkle mmr log entry details",
182-
// see https://github.com/grpc-ecosystem/grpc-gateway/blob/master/protoc-gen-openapiv2/options/openapiv2.proto
183-
// for specific types.
184-
type: OBJECT
185-
}];
181+
oneof proof_details {
182+
MerkleLogEntry merklelog_entry = 19 [ (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {
183+
description:
184+
"verifiable merkle mmr log entry details",
185+
// see https://github.com/grpc-ecosystem/grpc-gateway/blob/master/protoc-gen-openapiv2/options/openapiv2.proto
186+
// for specific types.
187+
type: OBJECT
188+
}];
189+
}
186190
}
Lines changed: 191 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,191 @@
1+
// Maintainers, please refer to the style guide here:
2+
// https://developers.google.com/protocol-buffers/docs/style
3+
//
4+
// This file provides a type that can marshal the event data a customer sees
5+
// from our apis. It is typically used for demo and api code in go-lang that
6+
// needs to work with our api responses.
7+
//
8+
// NOTE: It MUST be kept up to date with the EventResponse message definition
9+
10+
syntax = "proto3";
11+
package archivist.v2;
12+
option go_package="github.com/datatrails/go-datatrails-common-api-gen/assets/v2/assets;assets";
13+
import "protoc-gen-openapiv2/options/annotations.proto";
14+
import "datatrails-common-api/assets/v2/assets/enums.proto";
15+
import "datatrails-common-api/assets/v2/assets/principal.proto";
16+
import "datatrails-common-api/assets/v2/assets/merklelogentry.proto";
17+
18+
19+
// EventResponseJSONAPI represents how the consumer of the events api sees the event data.
20+
message EventResponseJSONAPI {
21+
option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_schema) = {
22+
json_schema: {
23+
description: "This describes an Event."
24+
}
25+
example:"{ "
26+
"\"identity\": \"assets/add30235-1424-4fda-840a-d5ef82c4c96f/events/11bf5b37-e0b8-42e0-8dcf-dc8c4aefc000\", "
27+
"\"asset_identity\": \"assets/add30235-1424-4fda-840a-d5ef82c4c96f\", "
28+
"\"operation\": \"Record\", "
29+
"\"behaviour\": \"RecordEvidence\", "
30+
"\"event_attributes\": { "
31+
" \"arc_attachments\": ["
32+
" {"
33+
" \"arc_attachment_identity\": \"blobs/1754b920-cf20-4d7e-9d36-9ed7d479744d\","
34+
" \"arc_hash_value\": \"01ba4719c80b6fe911b091a7c05124b64eeece964e09c058ef8f9805daca546b\","
35+
" \"arc_display_name\": \"Picture from yesterday\","
36+
" \"arc_hash_alg\": \"sha256\""
37+
" }"
38+
" ]"
39+
"}, "
40+
"\"asset_attributes\": { "
41+
" \"arc_firmware_version\": \"3.2.1\", "
42+
" \"arc_home_location_identity\": \"locations/42054f10-9952-4c10-a082-9fd0d10295ae\""
43+
"}, "
44+
"\"timestamp_accepted\": \"2019-11-27T14:44:19Z\", "
45+
"\"timestamp_declared\": \"2019-11-27T14:44:19Z\", "
46+
"\"timestamp_committed\": \"2019-11-27T14:44:19Z\", "
47+
"\"principal_declared\": { "
48+
" \"issuer\": \"job.idp.server/1234\", \"subject\":\"bob@job\" "
49+
" }, "
50+
" \"principal_accepted\": { "
51+
" \"issuer\": \"job.idp.server/1234\", \"subject\":\"bob@job\" "
52+
"}, "
53+
"\"confirmation_status\": \"CONFIRMED\", "
54+
"\"block_number\": 12, "
55+
"\"transaction_index\": 5, "
56+
"\"transaction_id\": \"0x07569\", "
57+
"\"tenant_identity\": \"tenant/8e0b600c-8234-43e4-860c-e95bdcd695a9\" "
58+
"}"
59+
};
60+
61+
// Relative Resource Name for the operation event
62+
string identity = 1 [ (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {
63+
description: "identity of a event resource"
64+
read_only: true
65+
}];
66+
67+
// relative resource name for associated asset ( asset the operation is performed on - has to have specific behaviour enabled)
68+
string asset_identity = 2 [ (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {
69+
description: "identity of a related asset resource `assets/11bf5b37-e0b8-42e0-8dcf-dc8c4aefc000`"
70+
read_only: true
71+
}];
72+
73+
// map of event attributes. Specific behaviours define required and optional event attributes for each supported operation.
74+
map<string, string> event_attributes = 16 [
75+
(grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {
76+
description: "key value mapping of event attributes"
77+
}
78+
];
79+
80+
// map of asset attributes. Specific behaviours define required and optional asset attributes. These attributes cause the corresponding attributes on the asset to be updated.
81+
map<string, string> asset_attributes = 17 [
82+
(grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {
83+
description: "key value mapping of asset attributes"
84+
}
85+
];
86+
87+
// name of operation on this behviour
88+
string operation = 4 [ (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {
89+
description: "The operation represented by the event. `Record`"
90+
read_only: true
91+
max_length: 4096
92+
}];
93+
94+
// name of this behaviour
95+
string behaviour = 14 [ (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {
96+
description: "The behaviour used to create event. `RecordEvidence`"
97+
read_only: true
98+
max_length: 4096
99+
}];
100+
101+
// timestamp when operation was actually performed - if not provided will be set to timestamp_accepted
102+
string timestamp_declared = 5 [ (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {
103+
description: "RFC 3339 time of event as declared by the user"
104+
read_only: true
105+
}];
106+
107+
// timestamp when system received operation request
108+
string timestamp_accepted = 6 [ (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {
109+
description: "RFC 3339 time of event as recorded by the server"
110+
read_only: true
111+
}];
112+
113+
// timestamp for when the event was committed to a verifiable log
114+
string timestamp_committed = 7 [ (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {
115+
description: "RFC 3339 time of event as recorded in verifiable storage"
116+
read_only: true
117+
}];
118+
119+
// principal information associated with event - if not provided will be set to principal_accepted
120+
Principal principal_declared = 8 [ (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {
121+
description: "principal provided by the user"
122+
read_only: true
123+
// see https://github.com/grpc-ecosystem/grpc-gateway/blob/master/protoc-gen-openapiv2/options/openapiv2.proto
124+
// for specific types.
125+
type: OBJECT
126+
}];
127+
128+
// principal logged into the system that performed the operation
129+
Principal principal_accepted = 9 [ (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {
130+
description: "principal recorded by the server"
131+
read_only: true
132+
// see https://github.com/grpc-ecosystem/grpc-gateway/blob/master/protoc-gen-openapiv2/options/openapiv2.proto
133+
// for specific types.
134+
type: OBJECT
135+
}];
136+
137+
// indicated if operation has been committed to the blockchain
138+
string confirmation_status = 10 [ (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {
139+
description: "indicates if the event has been succesfully committed to the blockchain"
140+
read_only: true
141+
// see https://github.com/grpc-ecosystem/grpc-gateway/blob/master/protoc-gen-openapiv2/options/openapiv2.proto
142+
// for specific types.
143+
type: STRING
144+
}];
145+
146+
// NOTICE: We expect to retire simple hash and then remove all the top level dlt fields.
147+
148+
// hash of transaction committing this operation on blockchain
149+
string transaction_id = 11 [ (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {
150+
description: "hash of the transaction as a hex string `0x11bf5b37e0b842e08dcfdc8c4aefc000`"
151+
max_length: 4096
152+
}];
153+
154+
// block number of committing transaction
155+
uint64 block_number = 12 [ (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {
156+
description: "number of block event was commited on"
157+
read_only: true
158+
}];
159+
160+
// transaction index of committing transaction
161+
uint64 transaction_index = 13 [ (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {
162+
description: "index of event within commited block"
163+
read_only: true
164+
}];
165+
166+
// wallet address for the creator of this event
167+
string from = 15 [ (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {
168+
description: "wallet address for the creator of this event"
169+
read_only: true
170+
}];
171+
172+
string tenant_identity = 18 [ (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {
173+
description:
174+
"Identity of the tenant the that created this event"
175+
max_length: 1024
176+
}];
177+
178+
// An event has exactly one proof mechanism. This field caputures the proof
179+
// mechanism specific details supporting the trustworthyness of the event
180+
// record. We anticipate at least two proof mechs: merkle_log and
181+
// verkle_log. We use oneof to avoid repeating the scattering of randomly
182+
// re-purposed fields we currently have for simple hash vs khipu.
183+
oneof proof_details {
184+
// proof details for proof_mechanism MERKLE_LOG
185+
MerkleLogEntry merklelog_entry = 19 [ (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {
186+
description:
187+
"verifiable merkle mmr log entry details"
188+
max_length: 1024
189+
}];
190+
};
191+
}

datatrails-common-api/assets/v2/assets/merklelogentry.proto

Lines changed: 38 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -7,69 +7,66 @@ import "google/protobuf/timestamp.proto";
77

88
// MerkeLogCommit provides the log entry details for a single mmr leaf.
99
message MerkleLogCommit {
10+
1011
/* The mmr index */
1112
uint64 index = 1;
12-
/* The mmr *leaf* index */
13-
uint64 leaf_index = 2; // TBD: this may be redundant.
14-
/* time ordered and strictly unique per tenant. system wide
15-
* unique with very reasonable operational assumptions. */
16-
fixed64 idtimestamp = 3;
13+
14+
/* time ordered and strictly unique per tenant. system wide unique with very
15+
* reasonable operational assumptions. prefixed with time epoch if len > 8
16+
* bytes (after conversion back from hex). */
17+
string idtimestamp = 2;
1718
}
1819

19-
message MerkleLogCommitMongoDB {
20+
message MerkleLogConfirm {
2021

21-
// Note that should we ever have more than 2^63 events in a tenant log, the
22-
// index and leaf_index fields will not persist to mongo.
22+
// The following correspond to mmrblobs.MMRState
23+
uint64 mmr_size = 1;
2324

24-
/* The mmr index */
25-
uint64 index = 1;
26-
/* The mmr *leaf* index */
27-
uint64 leaf_index = 2; // TBD: this may be redundant.
28-
29-
/* time ordered and strictly unique per tenant. system wide
30-
* unique with very reasonable operational assumptions.
31-
*
32-
* EXPRESSED AS A 16 character padded hex string because mongo db does not
33-
* support unsigned integers and we need all 64 bits to get a sensible epoch
34-
* duration.
35-
*/
36-
string idtimestamp = 3;
25+
bytes root = 2;
26+
// The regular unix time the root was signed
27+
int64 timestamp = 3;
28+
// The idtimestamp of the last leaf under mmr_size. prefixed with time epoch if len > 8 bytes (after conversion back from hex)
29+
string idtimestamp = 4;
30+
// The signed merkle tree head state at mmr_size. Contains COSE Sign1 formatted message.
31+
bytes signed_tree_head = 5;
3732
}
3833

34+
message MerkleLogUnequivocal { }
35+
3936
// The message sent from forestrie to avid notifying that the corresponding
4037
// event is commited to the tenants log.
4138
message MerkleLogCommitMessage {
4239

4340
// The tenant identity and the event identity for the committed event.
4441
string tenant_identity = 1;
4542
string event_identity = 2;
46-
/* The time portion of idtimestamp that contributed to the hash of the event
47-
* (the idtimestamp is _also_ included.
48-
* This must be copied into event.timestamp_committed when the saas db is updated */
49-
google.protobuf.Timestamp timestamp = 6;
50-
51-
uint32 log_version = 3;
52-
uint32 log_epoch = 4;
53-
MerkleLogCommit commit = 5;
43+
// The time portion of idtimestamp that contributed to the hash of the event
44+
google.protobuf.Timestamp timestamp = 3;
45+
46+
MerkleLogCommit commit = 4;
5447
}
5548

49+
message MerkleLogConfirmMessage {
50+
51+
string tenant_identity = 1;
5652

53+
MerkleLogConfirm confirm = 2;
54+
}
55+
56+
message MerkleLogUnequivocalMessage {
57+
string tenant_identity = 1;
58+
MerkleLogUnequivocal unequivocal = 2;
59+
}
5760

5861
// The details stored in the SaaS db for a proof mech MERKLE_LOG commitment
5962
message MerkleLogEntry {
6063

61-
// The tenant log version and epoch when the log entry was created.
62-
uint32 log_version = 1;
63-
uint32 log_epoch = 2;
64-
65-
// Event trust level commited fields. Note that we have to use a special
66-
// message because mongo db does not support unsigned integers. If/when we
67-
// move away from that, we can move this ordinal safely into a oneof
68-
MerkleLogCommitMongoDB commit = 3;
69-
70-
// TODO: Event trust level confirmed fields
64+
// Event trust level COMMITTED details
65+
MerkleLogCommit commit = 1;
7166

72-
// signature over tenant mmr root
67+
// Event trust level CONFIRMED details
68+
MerkleLogConfirm confirm = 2;
7369

74-
// TODO: Event trust level uniquivocal fields
70+
// Event trust level UNEQUIVOCAL details
71+
MerkleLogUnequivocal unequivocal = 3;
7572
}

0 commit comments

Comments
 (0)