immudb 0.1.0 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +8 -0
- data/lib/immudb/client.rb +81 -47
- data/lib/immudb/database.rb +33 -0
- data/lib/immudb/dual_proof.rb +1 -1
- data/lib/immudb/{txe.rb → entry_spec.rb} +7 -11
- data/lib/immudb/grpc/schema_pb.rb +309 -17
- data/lib/immudb/grpc/schema_services_pb.rb +38 -11
- data/lib/immudb/htree.rb +0 -21
- data/lib/immudb/kv_metadata.rb +88 -0
- data/lib/immudb/linear_proof.rb +2 -8
- data/lib/immudb/schema.rb +119 -0
- data/lib/immudb/store.rb +56 -72
- data/lib/immudb/tx.rb +60 -23
- data/lib/immudb/tx_entry.rb +34 -0
- data/lib/immudb/tx_header.rb +62 -0
- data/lib/immudb/version.rb +1 -1
- data/lib/immudb.rb +6 -2
- metadata +10 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 0200e6229a8e67d2592feb14e0375910e5c62bf358ee826357fc4b0b03b17751
|
4
|
+
data.tar.gz: dcb8aab1b18fd45882517b7a4aaa76801ec0fdd8881676084df490e57af354b6
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a0b20a298d7deb3783b988486c414d7486e242709cbb7b13fbab8579159cdb757ff68f870233a38da5a0aa0813c6c98415967a07bf4f808fc4a48764bec4204b
|
7
|
+
data.tar.gz: 5d2f796fea4da4e067f197a47469ae6bb95ccb4a24b4e81982948e113c79c7244827be5e33e8010431268975854f6d5802b6610a1f65ccafe71b4b25a356e87e
|
data/CHANGELOG.md
CHANGED
data/lib/immudb/client.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
# Copyright
|
1
|
+
# Copyright 2022 CodeNotary, Inc. All rights reserved.
|
2
2
|
|
3
3
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
4
4
|
# you may not use this file except in compliance with the License.
|
@@ -76,51 +76,61 @@ module Immudb
|
|
76
76
|
nil
|
77
77
|
end
|
78
78
|
|
79
|
-
def verified_set(key, value)
|
79
|
+
def verified_set(key, value, metadata: nil)
|
80
|
+
schema_metadata = metadata_to_proto(metadata)
|
80
81
|
state = @rs.get
|
81
|
-
kv = Schema::KeyValue.new(key: key, value: value)
|
82
|
+
kv = Schema::KeyValue.new(key: key, value: value, metadata: schema_metadata)
|
82
83
|
|
83
84
|
raw_request = Schema::VerifiableSetRequest.new(
|
84
85
|
setRequest: Schema::SetRequest.new(KVs: [kv]),
|
85
86
|
proveSinceTx: state.txId
|
86
87
|
)
|
87
88
|
verifiable_tx = grpc.verifiable_set(raw_request)
|
88
|
-
tx
|
89
|
-
inclusion_proof = tx.proof(SET_KEY_PREFIX + key)
|
90
|
-
ekv = Store.encode_kv(key, value)
|
91
|
-
verifies = Store.verify_inclusion(inclusion_proof, ekv.digest, tx.eh)
|
92
|
-
unless verifies
|
89
|
+
if verifiable_tx.tx.header.nentries != 1 || verifiable_tx.tx.entries.length != 1
|
93
90
|
raise VerificationError
|
94
91
|
end
|
95
|
-
|
92
|
+
tx = Schema.tx_from_proto(verifiable_tx.tx)
|
93
|
+
entry_spec_digest = Store.entry_spec_digest_for(tx.header.version)
|
94
|
+
inclusion_proof = tx.proof(Database.encode_key(key))
|
95
|
+
md = tx.entries[0].metadata
|
96
|
+
|
97
|
+
if !md.nil? && md.deleted?
|
96
98
|
raise VerificationError
|
97
99
|
end
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
100
|
+
|
101
|
+
e = Database.encode_entry_spec(key, md, value)
|
102
|
+
|
103
|
+
verifies = Store.verify_inclusion(inclusion_proof, entry_spec_digest.call(e), tx.header.eh)
|
104
|
+
unless verifies
|
105
|
+
raise VerificationError
|
104
106
|
end
|
105
|
-
|
106
|
-
target_alh = tx.Alh
|
107
|
-
|
108
|
-
verifies = Store.verify_dual_proof(
|
109
|
-
HTree.dual_proof_from(verifiable_tx.dualProof),
|
110
|
-
source_id,
|
111
|
-
target_id,
|
112
|
-
source_alh,
|
113
|
-
target_alh
|
114
|
-
)
|
115
|
-
if !verifies
|
107
|
+
if tx.header.eh != Schema.digest_from_proto(verifiable_tx.dualProof.targetTxHeader.eH)
|
116
108
|
raise VerificationError
|
117
109
|
end
|
110
|
+
source_id = state.txId
|
111
|
+
source_alh = Schema.digest_from_proto(state.txHash)
|
112
|
+
target_id = tx.header.iD
|
113
|
+
target_alh = tx.header.alh
|
114
|
+
|
115
|
+
if state.txId > 0
|
116
|
+
verifies = Store.verify_dual_proof(
|
117
|
+
Schema.dual_proof_from_proto(verifiable_tx.dualProof),
|
118
|
+
source_id,
|
119
|
+
target_id,
|
120
|
+
source_alh,
|
121
|
+
target_alh
|
122
|
+
)
|
123
|
+
unless verifies
|
124
|
+
raise VerificationError
|
125
|
+
end
|
126
|
+
end
|
127
|
+
|
118
128
|
newstate = State.new(
|
119
129
|
db: state.db,
|
120
130
|
txId: target_id,
|
121
131
|
txHash: target_alh,
|
122
132
|
publicKey: verifiable_tx.signature&.publicKey,
|
123
|
-
signature: verifiable_tx.signature&.signature
|
133
|
+
signature: verifiable_tx.signature&.signature
|
124
134
|
)
|
125
135
|
if !verifying_key.nil?
|
126
136
|
newstate.verify(verifying_key)
|
@@ -142,43 +152,50 @@ module Immudb
|
|
142
152
|
)
|
143
153
|
ventry = grpc.verifiable_get(req)
|
144
154
|
|
145
|
-
|
146
|
-
|
155
|
+
entry_spec_digest = Store.entry_spec_digest_for(ventry.verifiableTx.tx.header.version.to_i)
|
156
|
+
inclusion_proof = Schema.inclusion_proof_from_proto(ventry.inclusionProof)
|
157
|
+
dual_proof = Schema.dual_proof_from_proto(ventry.verifiableTx.dualProof)
|
147
158
|
|
148
159
|
if ventry.entry.referencedBy.nil? || ventry.entry.referencedBy.key == ""
|
149
160
|
vTx = ventry.entry.tx
|
150
|
-
|
161
|
+
e = Database.encode_entry_spec(key, Schema.kv_metadata_from_proto(ventry.entry.metadata), ventry.entry.value)
|
151
162
|
else
|
152
|
-
|
153
|
-
|
163
|
+
ref = ventry.entry.referencedBy
|
164
|
+
vTx = ref.tx
|
165
|
+
e = Database.encode_reference(ref.key, Schema.kv_metadata_from_proto(ref.metadata), ventry.entry.key, ref.atTx)
|
154
166
|
end
|
155
167
|
|
156
168
|
if state.txId <= vTx
|
157
|
-
eh =
|
169
|
+
eh = Schema.digest_from_proto(ventry.verifiableTx.dualProof.targetTxHeader.eH)
|
158
170
|
source_id = state.txId
|
159
|
-
source_alh =
|
171
|
+
source_alh = Schema.digest_from_proto(state.txHash)
|
160
172
|
target_id = vTx
|
161
|
-
target_alh = dual_proof.
|
173
|
+
target_alh = dual_proof.targetTxHeader.alh
|
162
174
|
else
|
163
|
-
eh =
|
175
|
+
eh = Schema.digest_from_proto(ventry.verifiableTx.dualProof.sourceTxHeader.eH)
|
164
176
|
source_id = vTx
|
165
|
-
source_alh = dual_proof.
|
177
|
+
source_alh = dual_proof.sourceTxHeader.alh
|
166
178
|
target_id = state.txId
|
167
|
-
target_alh =
|
179
|
+
target_alh = Schema.digest_from_proto(state.txHash)
|
168
180
|
end
|
169
181
|
|
170
|
-
verifies = Store.verify_inclusion(inclusion_proof,
|
182
|
+
verifies = Store.verify_inclusion(inclusion_proof, entry_spec_digest.call(e), eh)
|
171
183
|
if !verifies
|
172
184
|
raise VerificationError
|
173
185
|
end
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
186
|
+
|
187
|
+
if state.txId > 0
|
188
|
+
verifies =
|
189
|
+
Store.verify_dual_proof(
|
190
|
+
dual_proof,
|
191
|
+
source_id,
|
192
|
+
target_id,
|
193
|
+
source_alh,
|
194
|
+
target_alh
|
195
|
+
)
|
196
|
+
if !verifies
|
197
|
+
raise VerificationError
|
198
|
+
end
|
182
199
|
end
|
183
200
|
newstate = State.new(
|
184
201
|
db: state.db,
|
@@ -362,5 +379,22 @@ module Immudb
|
|
362
379
|
name
|
363
380
|
end
|
364
381
|
end
|
382
|
+
|
383
|
+
def metadata_to_proto(metadata)
|
384
|
+
schema_metadata = nil
|
385
|
+
if metadata
|
386
|
+
schema_metadata = Schema::KVMetadata.new
|
387
|
+
if metadata.deleted?
|
388
|
+
schema_metadata.deleted = true
|
389
|
+
end
|
390
|
+
if metadata.expirable?
|
391
|
+
schema_metadata.expiration = Schema::Expiration.new(expiresAt: metadata.expiration_time.to_i)
|
392
|
+
end
|
393
|
+
if metadata.non_indexable?
|
394
|
+
schema_metadata.nonIndexable = true
|
395
|
+
end
|
396
|
+
end
|
397
|
+
schema_metadata
|
398
|
+
end
|
365
399
|
end
|
366
400
|
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
# Copyright 2022 CodeNotary, Inc. All rights reserved.
|
2
|
+
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
4
|
+
# you may not use this file except in compliance with the License.
|
5
|
+
# You may obtain a copy of the License at
|
6
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
7
|
+
# Unless required by applicable law or agreed to in writing, software
|
8
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
9
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
10
|
+
# See the License for the specific language governing permissions and
|
11
|
+
# limitations under the License.
|
12
|
+
|
13
|
+
module Immudb
|
14
|
+
module Database
|
15
|
+
class << self
|
16
|
+
def wrap_with_prefix(b, prefix)
|
17
|
+
prefix + b
|
18
|
+
end
|
19
|
+
|
20
|
+
def encode_key(key)
|
21
|
+
wrap_with_prefix(key, SET_KEY_PREFIX)
|
22
|
+
end
|
23
|
+
|
24
|
+
def encode_entry_spec(key, md, value)
|
25
|
+
EntrySpec.new(
|
26
|
+
key: wrap_with_prefix(key, SET_KEY_PREFIX),
|
27
|
+
md: md,
|
28
|
+
value: wrap_with_prefix(value, PLAIN_VALUE_PREFIX)
|
29
|
+
)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
data/lib/immudb/dual_proof.rb
CHANGED
@@ -12,6 +12,6 @@
|
|
12
12
|
|
13
13
|
module Immudb
|
14
14
|
class DualProof
|
15
|
-
attr_accessor :
|
15
|
+
attr_accessor :sourceTxHeader, :targetTxHeader, :inclusionProof, :consistencyProof, :targetBlTxAlh, :lastInclusionProof, :linearProof
|
16
16
|
end
|
17
17
|
end
|
@@ -1,4 +1,4 @@
|
|
1
|
-
# Copyright
|
1
|
+
# Copyright 2022 CodeNotary, Inc. All rights reserved.
|
2
2
|
|
3
3
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
4
4
|
# you may not use this file except in compliance with the License.
|
@@ -11,17 +11,13 @@
|
|
11
11
|
# limitations under the License.
|
12
12
|
|
13
13
|
module Immudb
|
14
|
-
class
|
15
|
-
|
14
|
+
class EntrySpec
|
15
|
+
attr_reader :key, :metadata, :value
|
16
16
|
|
17
|
-
def
|
18
|
-
@key = key
|
19
|
-
@
|
20
|
-
|
21
|
-
|
22
|
-
def digest
|
23
|
-
b = @key + @h_value
|
24
|
-
Digest::SHA256.digest(b)
|
17
|
+
def initialize(key:, md:, value:)
|
18
|
+
@key = key
|
19
|
+
@metadata = md
|
20
|
+
@value = value
|
25
21
|
end
|
26
22
|
end
|
27
23
|
end
|