Repository navigation
Expand file tree
/
Copy pathscope.proto
More file actions
248 lines (209 loc) · 11.4 KB
/
Copy pathscope.proto
File metadata and controls
248 lines (209 loc) · 11.4 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
syntax = "proto3";
package provenance.metadata.v1;
option go_package = "github.com/provenance-io/provenance/x/metadata/types";
option java_package = "io.provenance.metadata.v1";
option java_multiple_files = true;
import "cosmos/base/v1beta1/coin.proto";
import "gogoproto/gogo.proto";
import "google/protobuf/timestamp.proto";
import "google/protobuf/descriptor.proto";
import "provenance/metadata/v1/specification.proto";
/**
Overview
The structures in this file are used to efficiently store the data for the metadata module. The structure the core
concept of the Metadata module is a Scope that contains a list of Records/Facts. Updates to scopes are performed
in a session with details persisted in a Session. Each session contains a specification that details
constraints on parties that must sign, inputs, and outputs that can be recorded. Each Scope may contain a list of
allowed specifications that may be used.
Data Structures
Metadata Scope
A metadata scope contains a collection of records of data, each made up of a hash, data type, and ownership
information that establishes provenance.
Sessions
Typically multiple records will be established within a scope at the same time (see: Contract Memorialization). A
Session contains context for the recording of these records linking a set of records into a common process/
execution associated with a specification indicating allowed and required values.
Record
A single record collects information about a process that generated it, a collection of inputs, and one or more
outputs into a structure identified by a name that is unique within a scope.
KVStore State Data
Iterators
- Get All Scopes (<scope prefix>) []Scope
- Get All Sessions (<session prefix>:<scope_id>) []Session
* This method would be used to list all current session/transaction contexts with Records set on the scope
- Get All Scope Records (<records prefix>:<scope_id>) : []Record
Direct Access
- Get Scope (<scope prefix>:<scope_id>) Scope
- Get Session (<session prefix>:<scope_id>:<session_id>) : Session
- Get Record (<record prefix>:<scope_id>:<record_name_hash>) : Record
Indexes (special kvstore records for efficient cross reference/queries)
- Get Session Records - use filtered iterator over all scope records
- Get all scopes for a party/address?
- Get all scopes of a specific type (scope spec)?
- Get all sessions of a specific specification type?
- Get all Records of a type?
*/
// Scope defines a root reference for a collection of records owned by one or more parties.
message Scope {
option (gogoproto.goproto_stringer) = false;
option (gogoproto.stringer) = true;
// Unique ID for this scope. Implements sdk.Address interface for use where addresses are required in Cosmos
bytes scope_id = 1 [(gogoproto.nullable) = false, (gogoproto.customtype) = "MetadataAddress"];
// the scope specification that contains the specifications for data elements allowed within this scope
bytes specification_id = 2 [(gogoproto.nullable) = false, (gogoproto.customtype) = "MetadataAddress"];
// These parties represent top level owners of the records within. These parties must sign any requests that modify
// the data within the scope. These addresses are in union with parties listed on the sessions.
repeated Party owners = 3 [(gogoproto.nullable) = false];
// Addresses in this list are authorized to receive off-chain data associated with this scope.
repeated string data_access = 4;
// The address that controls the value associated with this scope.
//
// The value owner is actually tracked by the bank module using a coin with the denom "nft/<scope_id>".
// The value owner can be changed using WriteScope or anything that transfers funds, e.g. MsgSend.
//
// During WriteScope:
// - If this field is empty, it indicates that there should not be a change to the value owner.
// I.e. Once a scope has a value owner, it will always have one (until it's deleted).
// - If this field has a value, the existing value owner will be looked up, and
// - If there's already an existing value owner, they must be a signer,
// and the coin will be transferred to the new value owner.
// - If there isn't yet a value owner, the coin will be minted and sent to the new value owner.
// If the scope already exists, the owners must be signers (just like changing other fields).
// If it's a new scope, there's no special signer limitations related to the value owner.
string value_owner_address = 5;
// Whether all parties in this scope and its sessions must be present in this scope's owners field.
// This also enables use of optional=true scope owners and session parties.
bool require_party_rollup = 6;
}
// Session defines an execution context against a specific specification instance.
// The context will have a specification and set of parties involved.
//
// NOTE: When there are no more Records within a Scope that reference a Session, the Session is removed.
message Session {
option (gogoproto.goproto_stringer) = false;
option (gogoproto.stringer) = true;
bytes session_id = 1 [(gogoproto.nullable) = false, (gogoproto.customtype) = "MetadataAddress"];
// unique id of the contract specification that was used to create this session.
bytes specification_id = 2 [(gogoproto.nullable) = false, (gogoproto.customtype) = "MetadataAddress"];
// parties is the set of identities that signed this contract
repeated Party parties = 3 [(gogoproto.nullable) = false];
// name to associate with this session execution context, typically classname
string name = 4;
// context is a field for storing client specific data associated with a session.
bytes context = 5;
// Created by, updated by, timestamps, version number, and related info.
AuditFields audit = 99;
}
// A record (of fact) is attached to a session or each consideration output from a contract
message Record {
option (gogoproto.goproto_stringer) = false;
option (gogoproto.stringer) = true;
// name/identifier for this record. Value must be unique within the scope. Also known as a Fact name
string name = 1;
// id of the session context that was used to create this record (use with filtered kvprefix iterator)
bytes session_id = 2 [(gogoproto.nullable) = false, (gogoproto.customtype) = "MetadataAddress"];
// process contain information used to uniquely identify an execution on or off chain that generated this record
Process process = 3 [(gogoproto.nullable) = false];
// inputs used with the process to achieve the output on this record
repeated RecordInput inputs = 4 [(gogoproto.nullable) = false];
// output(s) is the results of executing the process on the given process indicated in this record
repeated RecordOutput outputs = 5 [(gogoproto.nullable) = false];
// specification_id is the id of the record specification that was used to create this record.
bytes specification_id = 6 [(gogoproto.nullable) = false, (gogoproto.customtype) = "MetadataAddress"];
}
// Process contains information used to uniquely identify what was used to generate this record
message Process {
option (gogoproto.goproto_stringer) = false;
// unique identifier for this process
oneof process_id {
// the address of a smart contract used for this process
string address = 1;
// the hash of an off-chain process used
string hash = 2;
}
// a name associated with the process (type_name, classname or smart contract common name)
string name = 3;
// method is a name or reference to a specific operation (method) within a class/contract that was invoked
string method = 4;
}
// Tracks the inputs used to establish this record
message RecordInput {
option (gogoproto.goproto_stringer) = false;
// Name value included to link back to the definition spec.
string name = 1;
// data source
oneof source {
// the address of a record on chain (For Established Records)
bytes record_id = 2 [(gogoproto.customtype) = "MetadataAddress"];
// the hash of an off-chain piece of information (For Proposed Records)
string hash = 3;
}
// from proposed fact structure to unmarshal
string type_name = 4;
// Indicates if this input was a recorded fact on chain or just a given hashed input
RecordInputStatus status = 5;
}
// A set of types for inputs on a record (of fact)
enum RecordInputStatus {
// RECORD_INPUT_STATUS_UNSPECIFIED indicates an invalid/unknown input type
RECORD_INPUT_STATUS_UNSPECIFIED = 0 [(gogoproto.enumvalue_customname) = "Unknown"];
// RECORD_INPUT_STATUS_PROPOSED indicates this input was an arbitrary piece of data that was hashed
RECORD_INPUT_STATUS_PROPOSED = 1 [(gogoproto.enumvalue_customname) = "Proposed"];
// RECORD_INPUT_STATUS_RECORD indicates this input is a reference to a previously recorded fact on blockchain
RECORD_INPUT_STATUS_RECORD = 2 [(gogoproto.enumvalue_customname) = "Record"];
}
// RecordOutput encapsulates the output of a process recorded on chain
message RecordOutput {
option (gogoproto.goproto_stringer) = false;
// Hash of the data output that was output/generated for this record
string hash = 1;
// Status of the process execution associated with this output indicating success,failure, or pending
ResultStatus status = 2;
}
// ResultStatus indicates the various states of execution of a record
enum ResultStatus {
// RESULT_STATUS_UNSPECIFIED indicates an unset condition
RESULT_STATUS_UNSPECIFIED = 0;
// RESULT_STATUS_PASS indicates the execution was successful
RESULT_STATUS_PASS = 1;
// RESULT_STATUS_SKIP indicates condition/consideration was skipped due to missing inputs or delayed execution
RESULT_STATUS_SKIP = 2;
// RESULT_STATUS_FAIL indicates the execution of the condition/consideration failed.
RESULT_STATUS_FAIL = 3;
}
// A Party is an address with/in a given role associated with a contract
message Party {
option (gogoproto.goproto_stringer) = false;
// address of the account (on chain)
string address = 1;
// a role for this account within the context of the processes used
PartyType role = 2;
// whether this party's signature is optional
bool optional = 3;
}
// AuditFields capture information about the last account to make modifications and when they were made
message AuditFields {
// the date/time when this entry was created
google.protobuf.Timestamp created_date = 1 [(gogoproto.stdtime) = true, (gogoproto.nullable) = false];
// the address of the account that created this record
string created_by = 2;
// the date/time when this entry was last updated
google.protobuf.Timestamp updated_date = 3 [(gogoproto.stdtime) = true, (gogoproto.nullable) = false];
// the address of the account that modified this record
string updated_by = 4;
// an optional version number that is incremented with each update
uint32 version = 5;
// an optional message associated with the creation/update event
string message = 6;
}
// NetAssetValue defines a scope's net asset value
message NetAssetValue {
// price is the complete value of the asset's volume
cosmos.base.v1beta1.Coin price = 1 [(gogoproto.nullable) = false];
// updated_block_height is the block height of last update
uint64 updated_block_height = 2;
// volume is the number of scope instances that were purchased for the price
// Typically this will be null (equivalent to one) or one. The only reason this would be more than
// one is for cases where the precision of the price denom is insufficient to represent the actual price
uint64 volume = 3;
}