diff --git a/datatrails-common-api/assets/v2/assets/eventresponse.proto b/datatrails-common-api/assets/v2/assets/eventresponse.proto index 24f0066..8dbca76 100644 --- a/datatrails-common-api/assets/v2/assets/eventresponse.proto +++ b/datatrails-common-api/assets/v2/assets/eventresponse.proto @@ -1,5 +1,10 @@ // Maintainers, please refer to the style guide here: // https://developers.google.com/protocol-buffers/docs/style +// Provides our internal, native, event response data. The data that is returned +// over our apis doe NOT fit this shape. To marshal api data into a golang type, +// see EventResponseJSONAPI instead. +// The EventResponse message here MUST be kept up to date with EventResponseJSONAPI + syntax = "proto3"; package archivist.v2; option go_package="github.com/datatrails/go-datatrails-common-api-gen/assets/v2/assets;assets"; @@ -168,19 +173,18 @@ message EventResponse { max_length: 1024 }]; - // An event has exactly one proof mechanism. This field caputures the proof - // mechanism specific details supporting the trustworthyness of the event - // record. We anticipate at least two proof mechs: merkle_log and - // verkle_log. We use oneof to avoid repeating the scattering of randomly - // re-purposed fields we currently have for simple hash vs khipu. - + // An event has exactly one proof mechanism. On any event only the entry + // corresponding to the chosen proof mechanism will be present. (Note that + // onfof exposes us to to many tooling compatibility issues) // proof details for proof_mechanism MERKLE_LOG - MerkleLogEntry merklelog_entry = 19 [ (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { - description: - "verifiable merkle mmr log entry details", - // see https://github.com/grpc-ecosystem/grpc-gateway/blob/master/protoc-gen-openapiv2/options/openapiv2.proto - // for specific types. - type: OBJECT - }]; + oneof proof_details { + MerkleLogEntry merklelog_entry = 19 [ (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { + description: + "verifiable merkle mmr log entry details", + // see https://github.com/grpc-ecosystem/grpc-gateway/blob/master/protoc-gen-openapiv2/options/openapiv2.proto + // for specific types. + type: OBJECT + }]; + } } \ No newline at end of file diff --git a/datatrails-common-api/assets/v2/assets/eventresponsejsonapi.proto b/datatrails-common-api/assets/v2/assets/eventresponsejsonapi.proto new file mode 100644 index 0000000..f3634ee --- /dev/null +++ b/datatrails-common-api/assets/v2/assets/eventresponsejsonapi.proto @@ -0,0 +1,191 @@ +// Maintainers, please refer to the style guide here: +// https://developers.google.com/protocol-buffers/docs/style +// +// This file provides a type that can marshal the event data a customer sees +// from our apis. It is typically used for demo and api code in go-lang that +// needs to work with our api responses. +// +// NOTE: It MUST be kept up to date with the EventResponse message definition + +syntax = "proto3"; +package archivist.v2; +option go_package="github.com/datatrails/go-datatrails-common-api-gen/assets/v2/assets;assets"; +import "protoc-gen-openapiv2/options/annotations.proto"; +import "datatrails-common-api/assets/v2/assets/enums.proto"; +import "datatrails-common-api/assets/v2/assets/principal.proto"; +import "datatrails-common-api/assets/v2/assets/merklelogentry.proto"; + + +// EventResponseJSONAPI represents how the consumer of the events api sees the event data. +message EventResponseJSONAPI { + option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_schema) = { + json_schema: { + description: "This describes an Event." + } + example:"{ " + "\"identity\": \"assets/add30235-1424-4fda-840a-d5ef82c4c96f/events/11bf5b37-e0b8-42e0-8dcf-dc8c4aefc000\", " + "\"asset_identity\": \"assets/add30235-1424-4fda-840a-d5ef82c4c96f\", " + "\"operation\": \"Record\", " + "\"behaviour\": \"RecordEvidence\", " + "\"event_attributes\": { " + " \"arc_attachments\": [" + " {" + " \"arc_attachment_identity\": \"blobs/1754b920-cf20-4d7e-9d36-9ed7d479744d\"," + " \"arc_hash_value\": \"01ba4719c80b6fe911b091a7c05124b64eeece964e09c058ef8f9805daca546b\"," + " \"arc_display_name\": \"Picture from yesterday\"," + " \"arc_hash_alg\": \"sha256\"" + " }" + " ]" + "}, " + "\"asset_attributes\": { " + " \"arc_firmware_version\": \"3.2.1\", " + " \"arc_home_location_identity\": \"locations/42054f10-9952-4c10-a082-9fd0d10295ae\"" + "}, " + "\"timestamp_accepted\": \"2019-11-27T14:44:19Z\", " + "\"timestamp_declared\": \"2019-11-27T14:44:19Z\", " + "\"timestamp_committed\": \"2019-11-27T14:44:19Z\", " + "\"principal_declared\": { " + " \"issuer\": \"job.idp.server/1234\", \"subject\":\"bob@job\" " + " }, " + " \"principal_accepted\": { " + " \"issuer\": \"job.idp.server/1234\", \"subject\":\"bob@job\" " + "}, " + "\"confirmation_status\": \"CONFIRMED\", " + "\"block_number\": 12, " + "\"transaction_index\": 5, " + "\"transaction_id\": \"0x07569\", " + "\"tenant_identity\": \"tenant/8e0b600c-8234-43e4-860c-e95bdcd695a9\" " + "}" + }; + + // Relative Resource Name for the operation event + string identity = 1 [ (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { + description: "identity of a event resource" + read_only: true + }]; + + // relative resource name for associated asset ( asset the operation is performed on - has to have specific behaviour enabled) + string asset_identity = 2 [ (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { + description: "identity of a related asset resource `assets/11bf5b37-e0b8-42e0-8dcf-dc8c4aefc000`" + read_only: true + }]; + + // map of event attributes. Specific behaviours define required and optional event attributes for each supported operation. + map event_attributes = 16 [ + (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { + description: "key value mapping of event attributes" + } + ]; + + // map of asset attributes. Specific behaviours define required and optional asset attributes. These attributes cause the corresponding attributes on the asset to be updated. + map asset_attributes = 17 [ + (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { + description: "key value mapping of asset attributes" + } + ]; + + // name of operation on this behviour + string operation = 4 [ (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { + description: "The operation represented by the event. `Record`" + read_only: true + max_length: 4096 + }]; + + // name of this behaviour + string behaviour = 14 [ (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { + description: "The behaviour used to create event. `RecordEvidence`" + read_only: true + max_length: 4096 + }]; + + // timestamp when operation was actually performed - if not provided will be set to timestamp_accepted + string timestamp_declared = 5 [ (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { + description: "RFC 3339 time of event as declared by the user" + read_only: true + }]; + + // timestamp when system received operation request + string timestamp_accepted = 6 [ (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { + description: "RFC 3339 time of event as recorded by the server" + read_only: true + }]; + + // timestamp for when the event was committed to a verifiable log + string timestamp_committed = 7 [ (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { + description: "RFC 3339 time of event as recorded in verifiable storage" + read_only: true + }]; + + // principal information associated with event - if not provided will be set to principal_accepted + Principal principal_declared = 8 [ (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { + description: "principal provided by the user" + read_only: true + // see https://github.com/grpc-ecosystem/grpc-gateway/blob/master/protoc-gen-openapiv2/options/openapiv2.proto + // for specific types. + type: OBJECT + }]; + + // principal logged into the system that performed the operation + Principal principal_accepted = 9 [ (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { + description: "principal recorded by the server" + read_only: true + // see https://github.com/grpc-ecosystem/grpc-gateway/blob/master/protoc-gen-openapiv2/options/openapiv2.proto + // for specific types. + type: OBJECT + }]; + + // indicated if operation has been committed to the blockchain + string confirmation_status = 10 [ (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { + description: "indicates if the event has been succesfully committed to the blockchain" + read_only: true + // see https://github.com/grpc-ecosystem/grpc-gateway/blob/master/protoc-gen-openapiv2/options/openapiv2.proto + // for specific types. + type: STRING + }]; + + // NOTICE: We expect to retire simple hash and then remove all the top level dlt fields. + + // hash of transaction committing this operation on blockchain + string transaction_id = 11 [ (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { + description: "hash of the transaction as a hex string `0x11bf5b37e0b842e08dcfdc8c4aefc000`" + max_length: 4096 + }]; + + // block number of committing transaction + uint64 block_number = 12 [ (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { + description: "number of block event was commited on" + read_only: true + }]; + + // transaction index of committing transaction + uint64 transaction_index = 13 [ (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { + description: "index of event within commited block" + read_only: true + }]; + + // wallet address for the creator of this event + string from = 15 [ (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { + description: "wallet address for the creator of this event" + read_only: true + }]; + + string tenant_identity = 18 [ (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { + description: + "Identity of the tenant the that created this event" + max_length: 1024 + }]; + + // An event has exactly one proof mechanism. This field caputures the proof + // mechanism specific details supporting the trustworthyness of the event + // record. We anticipate at least two proof mechs: merkle_log and + // verkle_log. We use oneof to avoid repeating the scattering of randomly + // re-purposed fields we currently have for simple hash vs khipu. + oneof proof_details { + // proof details for proof_mechanism MERKLE_LOG + MerkleLogEntry merklelog_entry = 19 [ (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { + description: + "verifiable merkle mmr log entry details" + max_length: 1024 + }]; + }; +} \ No newline at end of file diff --git a/datatrails-common-api/assets/v2/assets/merklelogentry.proto b/datatrails-common-api/assets/v2/assets/merklelogentry.proto index 580b80d..a4fb7f5 100644 --- a/datatrails-common-api/assets/v2/assets/merklelogentry.proto +++ b/datatrails-common-api/assets/v2/assets/merklelogentry.proto @@ -7,35 +7,32 @@ import "google/protobuf/timestamp.proto"; // MerkeLogCommit provides the log entry details for a single mmr leaf. message MerkleLogCommit { + /* The mmr index */ uint64 index = 1; - /* The mmr *leaf* index */ - uint64 leaf_index = 2; // TBD: this may be redundant. - /* time ordered and strictly unique per tenant. system wide - * unique with very reasonable operational assumptions. */ - fixed64 idtimestamp = 3; + + /* time ordered and strictly unique per tenant. system wide unique with very + * reasonable operational assumptions. prefixed with time epoch if len > 8 + * bytes (after conversion back from hex). */ + string idtimestamp = 2; } -message MerkleLogCommitMongoDB { +message MerkleLogConfirm { - // Note that should we ever have more than 2^63 events in a tenant log, the - // index and leaf_index fields will not persist to mongo. + // The following correspond to mmrblobs.MMRState + uint64 mmr_size = 1; - /* The mmr index */ - uint64 index = 1; - /* The mmr *leaf* index */ - uint64 leaf_index = 2; // TBD: this may be redundant. - - /* time ordered and strictly unique per tenant. system wide - * unique with very reasonable operational assumptions. - * - * EXPRESSED AS A 16 character padded hex string because mongo db does not - * support unsigned integers and we need all 64 bits to get a sensible epoch - * duration. - */ - string idtimestamp = 3; + bytes root = 2; + // The regular unix time the root was signed + int64 timestamp = 3; + // The idtimestamp of the last leaf under mmr_size. prefixed with time epoch if len > 8 bytes (after conversion back from hex) + string idtimestamp = 4; + // The signed merkle tree head state at mmr_size. Contains COSE Sign1 formatted message. + bytes signed_tree_head = 5; } +message MerkleLogUnequivocal { } + // The message sent from forestrie to avid notifying that the corresponding // event is commited to the tenants log. message MerkleLogCommitMessage { @@ -43,33 +40,33 @@ message MerkleLogCommitMessage { // The tenant identity and the event identity for the committed event. string tenant_identity = 1; string event_identity = 2; - /* The time portion of idtimestamp that contributed to the hash of the event - * (the idtimestamp is _also_ included. - * This must be copied into event.timestamp_committed when the saas db is updated */ - google.protobuf.Timestamp timestamp = 6; - - uint32 log_version = 3; - uint32 log_epoch = 4; - MerkleLogCommit commit = 5; + // The time portion of idtimestamp that contributed to the hash of the event + google.protobuf.Timestamp timestamp = 3; + + MerkleLogCommit commit = 4; } +message MerkleLogConfirmMessage { + + string tenant_identity = 1; + MerkleLogConfirm confirm = 2; +} + +message MerkleLogUnequivocalMessage { + string tenant_identity = 1; + MerkleLogUnequivocal unequivocal = 2; +} // The details stored in the SaaS db for a proof mech MERKLE_LOG commitment message MerkleLogEntry { - // The tenant log version and epoch when the log entry was created. - uint32 log_version = 1; - uint32 log_epoch = 2; - - // Event trust level commited fields. Note that we have to use a special - // message because mongo db does not support unsigned integers. If/when we - // move away from that, we can move this ordinal safely into a oneof - MerkleLogCommitMongoDB commit = 3; - - // TODO: Event trust level confirmed fields + // Event trust level COMMITTED details + MerkleLogCommit commit = 1; - // signature over tenant mmr root + // Event trust level CONFIRMED details + MerkleLogConfirm confirm = 2; - // TODO: Event trust level uniquivocal fields + // Event trust level UNEQUIVOCAL details + MerkleLogUnequivocal unequivocal = 3; } \ No newline at end of file