[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[gnunet-scheme] 05/07: Implement (gnu gnunet dht client) in terms of has
From: |
gnunet |
Subject: |
[gnunet-scheme] 05/07: Implement (gnu gnunet dht client) in terms of hashcodes. |
Date: |
Mon, 21 Nov 2022 16:09:07 +0100 |
This is an automated email from the git hooks/post-receive script.
maxime-devos pushed a commit to branch master
in repository gnunet-scheme.
commit c16f03512d94831403885f95bc8934eb4e2d17ff
Author: Maxime Devos <maximedevos@telenet.be>
AuthorDate: Mon Nov 21 16:03:41 2022 +0100
Implement (gnu gnunet dht client) in terms of hashcodes.
For consistency with the future FS API.
* doc/distributed-hash-table.scm: Adjust.
* gnu/gnunet/dht/client.scm: Adjust.
* gnu/gnunet/hashcode.scm (copy-hashcode:512): Add required procedure.
(copy-hashcode:256): Add for symmetry.
* tests/distributed-hash-table.scm: Adjust.
---
doc/distributed-hash-table.tm | 12 ++++----
gnu/gnunet/dht/client.scm | 51 ++++++++++++++++++----------------
gnu/gnunet/hashcode.scm | 15 +++++++++-
tests/distributed-hash-table.scm | 59 +++++++++++++++++++++++++---------------
4 files changed, 85 insertions(+), 52 deletions(-)
diff --git a/doc/distributed-hash-table.tm b/doc/distributed-hash-table.tm
index 8107321..4dcaa39 100644
--- a/doc/distributed-hash-table.tm
+++ b/doc/distributed-hash-table.tm
@@ -38,10 +38,10 @@
<var|#:expiration>)><index|make-datum>
<|explain>
Make a datum object of block type <var|type> (or its corresponding
- numeric value), with key <var|key> (a readable <scm|/hashcode:512>
- bytevector slice), value <var|value> (a readable bytevector slice) and
- expiring at <var|expiration> (<todo|type, epoch>). The keyword argument
- <var|expiration> is optional, see <reference|???>.
+ numeric value), with key <var|key> (a hashcode:512), value <var|value> (a
+ readable bytevector slice) and expiring at <var|expiration> (<todo|type,
+ epoch>). The keyword argument <var|expiration> is optional, see
+ <reference|???>.
The numeric value of the block type can be retrieved with the accessor
<scm|datum-type>. The accessors <scm|datum-key><index|datum-key>,
@@ -76,8 +76,8 @@
#:desired-replication-level)><index|make-query>
<|explain>
Make a query object for searching for a value of block type <var|type>
- (or its corresponding numeric value), with key <var|key> (a readable
- <scm|/hashcode:512> bytevector slice), at desired replication level
+ (or its corresponding numeric value), with key <var|key> (a
+ hashcode:512), at desired replication level
<scm|desired-replication-level> (see <reference|replication levels???>).
<todo|various options, xquery>
diff --git a/gnu/gnunet/dht/client.scm b/gnu/gnunet/dht/client.scm
index cb54f4d..bfc4bcc 100644
--- a/gnu/gnunet/dht/client.scm
+++ b/gnu/gnunet/dht/client.scm
@@ -75,6 +75,7 @@
(import (gnu extractor enum)
(gnu gnunet block)
(gnu gnunet hashcode struct)
+ (gnu gnunet hashcode)
(gnu gnunet mq)
(gnu gnunet mq handler)
(gnu gnunet mq envelope)
@@ -158,14 +159,11 @@ valid replication to the level, to the range the DHT
service likes."
(min %effective-maximum-replication-level replication-level)))
(define (validate-key key)
- "If @var{key} is, in-fact, a readable /hashcode:512, return it as a
-readable bytevector slice. If not, raise an appropriate exception. The 'what'
-in the @code{&missing-capabilities} condition, if any, is the symbol
-@code{key}."
- (verify-slice-readable 'key key)
- (if (= (slice-length key) (sizeof /hashcode:512 '()))
- (slice/read-only key)
- (error "length of key incorrect")))
+ "If @var{key} is, in-fact, a hashcode:512, return it. If not, raise an
+appropriate exception."
+ (if (hashcode:512? key)
+ key
+ (error "not a hashcode:512")))
(define (validate-datum datum)
"If @var{datum} is, in-fact, a datum, return it. Otherwise, raise an
@@ -225,9 +223,9 @@ appropriate exception."
(lambda (%make)
(lambda* (type key value #:key (expiration 0)) ; TODO default
expiration
"Make a datum object of block type @var{type} (or its corresponding
-numeric value), with key @var{key} (a readable @code{/hashcode:512} bytevector
-slice), value @var{value} (a readable bytevector slice) and expiring at
@var{expiration}.
-The keyword argument @var{expiration} is optional, see ???.
+numeric value), with key @var{key} (a hashcode:512), value @var{value} (a
readable
+bytevector slice) and expiring at @var{expiration}. The keyword argument
+@var{expiration} is optional, see ???.
The numeric value of the block type can be retrieved with the accessor
@code{datum-type}. The accessors @code{datum-key}, @code{datum-value} and
@@ -251,7 +249,7 @@ If this bound is exceeded, an appropriate
@code{&overly-large-datum} and
"Make a copy of the datum @var{old}, such that modifications to the
slices in @var{old} do not impact the new datum."
(make-datum (datum-type old)
- (slice-copy/read-only (datum-key old))
+ (copy-hashcode:512 (datum-key old))
(slice-copy/read-only (datum-value old))
#:expiration (datum-expiration old)))
@@ -288,9 +286,8 @@ slices in @var{old} do not impact the new insertion."
(lambda (%make)
(lambda* (type key #:key (desired-replication-level 3))
"Make a query object for searching for a value of block type
@var{type}
-(or its corresponding numeric value), with key @var{key} (a readable
-@code{/hashcode:512} bytevector slice), at desired replication level
-@var{desired-replication-level}.
+(or its corresponding numeric value), with key @var{key} (a hashcode:512}, at
+desired replication level @var{desired-replication-level}.
The numeric value of the block type, the key and the desired replication level
can be recovered with the accessors @code{query-type}, @code{query-key} and
@@ -304,7 +301,7 @@ query object with the predicate @code{query?}."
"Make a copy of the query object @var{old}, such that modifications to
the
slices in @var{old} do not impact the new query object."
(make-query (query-type old)
- (slice-copy/read-only (query-key old))
+ (copy-hashcode:512 (query-key old))
#:desired-replication-level
(query-desired-replication-level old)))
@@ -416,7 +413,8 @@ slices in @var{old} do not impact the new search result."
(set%!/get '(desired-replication-level)
(query-desired-replication-level query))
(set%!/get '(type) (query-type query))
- (slice-copy! (query-key query) (select /:msg:dht:client:get '(key) s))
+ (slice-copy! (hashcode:512->slice (query-key query))
+ (select /:msg:dht:client:get '(key) s))
(set%!/get '(unique-id) unique-id)
s)
@@ -432,7 +430,8 @@ get request with @var{unique-id} as unique id and @var{key}
as key."
(symbol-value message-type msg:dht:client:get:stop)))
(set%!/stop '(reserved) 0)
(set%!/stop '(unique-id) unique-id)
- (slice-copy! key (select /:msg:dht:client:get:stop '(key) s))
+ (slice-copy! (hashcode:512->slice key)
+ (select /:msg:dht:client:get:stop '(key) s))
s)
(define* (construct-client-put insertion #:optional (options 0))
@@ -456,7 +455,8 @@ object insertion with @var{options} as options."
(insertion-desired-replication-level insertion))
(set%!/put '(expiration) (datum-expiration datum))
;; Copy key-data pair to insert into the DHT.
- (slice-copy! (datum-key datum) (select /:msg:dht:client:put '(key)
header))
+ (slice-copy! (hashcode:512->slice (datum-key datum))
+ (select /:msg:dht:client:put '(key) header))
(slice-copy! (datum-value datum) rest)
message)
@@ -495,7 +495,8 @@ result object @var{search-result}, with @var{unique-id} as
‘unique id’"
(set%!/result '(put-path-length) put-path-length)
(set%!/result '(unique-id) unique-id)
(set%!/result '(expiration) expiration)
- (slice-copy! key (select /:msg:dht:client:result '(key) header))
+ (slice-copy! (hashcode:512->slice key)
+ (select /:msg:dht:client:result '(key) header))
;; TODO: get-path and put path!
(slice-copy! value rest)
message))
@@ -505,7 +506,8 @@ result object @var{search-result}, with @var{unique-id} as
‘unique id’"
the @code{/:msg:dht:client:result} message @var{message}. Xqueries are
currently unsupported."
(let^ ((! type (read% /:msg:dht:client:get '(type) message))
- (! key (select /:msg:dht:client:get '(key) message))
+ (! key (make-hashcode:512/share
+ (select /:msg:dht:client:get '(key) message)))
(! desired-replication-level
(read% /:msg:dht:client:get '(desired-replication-level)
message))
(! unique-id (read% /:msg:dht:client:get '(unique-id) message))
@@ -526,7 +528,9 @@ currently unsupported."
@code{/:msg:dht:client:put} message @var{message}."
(let^ ((! header (slice-slice message 0 (sizeof /:msg:dht:client:put
'())))
(! type (read% /:msg:dht:client:put '(type) header))
- (! key (select /:msg:dht:client:put '(key) header))
+ (! key
+ (make-hashcode:512/share
+ (select /:msg:dht:client:put '(key) header)))
(! value (slice-slice message (sizeof /:msg:dht:client:put '())))
(! desired-replication-level
(read% /:msg:dht:client:put '(desired-replication-level)
header))
@@ -563,7 +567,8 @@ currently unsupported."
(! datum
(make-datum
(read% /:msg:dht:client:result '(type) header)
- (select /:msg:dht:client:result '(key) header)
+ (make-hashcode:512/share
+ (select /:msg:dht:client:result '(key) header))
value
#:expiration
(read% /:msg:dht:client:result '(expiration) header)))
diff --git a/gnu/gnunet/hashcode.scm b/gnu/gnunet/hashcode.scm
index a605d4e..2137755 100644
--- a/gnu/gnunet/hashcode.scm
+++ b/gnu/gnunet/hashcode.scm
@@ -25,7 +25,8 @@
hashcode:512? hashcode:256?
make-hashcode:512/share make-hashcode:512
make-hashcode:256/share make-hashcode:256
- hashcode:512->slice hashcode:256->slice)
+ hashcode:512->slice hashcode:256->slice
+ copy-hashcode:512 copy-hashcode:256)
(import (rnrs base)
(gnu gnunet utils bv-slice)
(rnrs records syntactic))
@@ -56,6 +57,12 @@ bytevector slice). @var{slice} may not be mutated while the
constructed
hashcode is in use."
(make-hashcode:512/share (slice-copy/read-only slice)))
+ (define (copy-hashcode:512 hashcode:512)
+ "Make a copy of the hashcode:512 @var{hashcode:512}. This can be useful if
+the slice used during the construction of @var{hashcode:512} is potentially
+going to be mutated while a hashcode will still be in use."
+ (make-hashcode:512 (hashcode:512->slice hashcode:512)))
+
;; A 256-bit hashcode. Used under special conditions, like when space
;; is critical and security is not impacted by it.
(define-record-type (<hashcode:256> make-hashcode:256/share hashcode:256?)
@@ -71,6 +78,12 @@ while the constructed short hashcode is in use."
(assert (= (slice-length slice) hashcode:256-u8-length))
(%make (slice/read-only slice))))))
+ (define (copy-hashcode:256 hashcode:256)
+ "Make a copy of the hashcode:256 @var{hashcode:256}. This can be useful if
+the slice used during the construction of @var{hashcode:256} is potentially
+going to be mutated while a hashcode will still be in use."
+ (make-hashcode:256 (hashcode:256->slice hashcode:256)))
+
(define (bv->hashcode:512 bv)
"Read a hashcode from a bytevector (deprecated)."
(make-hashcode:512 (bv-slice/read-only bv)))
diff --git a/tests/distributed-hash-table.scm b/tests/distributed-hash-table.scm
index 96d05ec..fe6ba96 100644
--- a/tests/distributed-hash-table.scm
+++ b/tests/distributed-hash-table.scm
@@ -30,6 +30,7 @@
(gnu gnunet util struct)
(gnu gnunet netstruct syntactic)
(only (gnu gnunet netstruct procedural) u64/big)
+ (gnu gnunet hashcode)
(gnu gnunet hashcode struct)
(gnu gnunet block)
(gnu gnunet message protocols)
@@ -136,7 +137,9 @@
(define* (make-a-datum #:key
(type 0)
- (key (make-slice/read-write* (sizeof /hashcode:512 '())))
+ (key (make-hashcode:512
+ (make-slice/read-write*
+ (sizeof /hashcode:512 '()))))
(value (make-slice/read-write 0))
(expiration (random (expt 2 64))))
(make-datum type key value #:expiration expiration))
@@ -152,10 +155,10 @@
;; end ups with the value passed to the constructor, as a readable bytevector
;; slice -- the writability of the original slice, if any, is removed.
(define (slice-property-test test-case generate-slice stuff? slice->stuff
stuff-slice)
- (test-assert test-case
+ (begin ;test-assert test-case
;; only evaluate once, because eq? will be required
(let* ((slice (generate-slice))
- (stuff (slice->stuff slice))
+ (stuff (pk 'stuff (slice->stuff slice)))
(new-slice (stuff-slice stuff)))
(and (stuff? stuff)
(slice-readable? new-slice)
@@ -165,7 +168,9 @@
(define-syntax-rule (datum-key-test test-case k)
(slice-property-test test-case (lambda () k) datum?
- (lambda (s) (make-a-datum #:key s)) datum-key))
+ (lambda (s) (make-a-datum #:key
+ (make-hashcode:512/share s)))
+ (compose hashcode:512->slice datum-key)))
(define-syntax-rule (datum-value-test test-case v)
(slice-property-test test-case (lambda () v) datum?
(lambda (s) (make-a-datum #:value s)) datum-value))
@@ -182,12 +187,13 @@
(sizeof /hashcode:512 '()))))
(test-missing-caps
- "datum key must be readable"
- 'key
+ "hashcode slice must be readable"
+ 'slice ; TODO not documented, separate tests for (gnu gnunet hashcode)
CAP_WRITE
CAP_READ
- (make-a-datum #:key (slice/write-only (make-slice/read-write*
- (sizeof /hashcode:512 '())))))
+ (make-hashcode:512/share
+ (slice/write-only (make-slice/read-write*
+ (sizeof /hashcode:512 '())))))
;; AFAIK a zero length value is allowed, albeit somewhat pointless?
(datum-value-test "datum-value, length 0" (make-slice/read-write 0))
@@ -238,12 +244,13 @@
b)
(define (query->sexp z)
- (list (query-type z) (slice->bytevector (query-key z))
+ (list (query-type z)
+ (slice->bytevector (hashcode:512->slice (query-key z)))
(query-desired-replication-level z)))
(define (datum->sexp z)
(list (datum-type z)
- (slice->bytevector (datum-key z))
+ (slice->bytevector (hashcode:512->slice (datum-key z)))
(slice->bytevector (datum-value z))
(datum-expiration z)))
@@ -268,11 +275,14 @@
(define (insertion=? x y)
(equal? (insertion->sexp x) (insertion->sexp y)))
+(define (hashcode-independent? x y)
+ (slice-independent? (hashcode:512->slice x) (hashcode:512->slice y)))
+
(define (query-independent? x y)
- (slice-independent? (query-key x) (query-key y)))
+ (hashcode-independent? (query-key x) (query-key y)))
(define (datum-independent? x y)
- (and (slice-independent? (datum-key x) (datum-key y))
+ (and (hashcode-independent? (datum-key x) (datum-key y))
(slice-independent? (datum-value x) (datum-value y))))
(define (insertion-independent? x y)
@@ -289,7 +299,7 @@
(let* ((old-key (make-slice/read-write* (sizeof /hashcode:512 '())))
(type (random 65536))
(desired-replication-level (+ 1 %maximum-replication-level))
- (old (make-query type old-key))
+ (old (make-query type (make-hashcode:512/share old-key)))
(new (copy-query old)))
(and (query=? old new)
(query-independent? old new))))
@@ -298,7 +308,8 @@
;; A least in Guile 3.0.5, all bytevectors of length 0 are eq?,
;; so let the value be non-empty such that datum-independent?
;; can return #true.
- (let* ((old-key (make-slice/read-write* (sizeof /hashcode:512 '())))
+ (let* ((old-key (make-hashcode:512/share
+ (make-slice/read-write* (sizeof /hashcode:512 '()))))
(old-value (make-slice/read-write* 70))
(old (make-a-datum #:key old-key #:value old-value #:expiration 777))
(new (copy-datum old)))
@@ -451,10 +462,12 @@ supported. When @var{explode} is signalled, the
connection is closed."
(slice-copy! slice bv/slice)
bv)
(define (query->key query)
- (cons (query-type query) (slice->bv (query-key query))))
+ (cons (query-type query)
+ (slice->bv (hashcode:512->slice (query-key query)))))
(define (insertion->key insertion)
(define datum (insertion->datum insertion))
- (cons (datum-type datum) (slice->bv (datum-key datum))))
+ (cons (datum-type datum)
+ (slice->bv (hashcode:512->slice (datum-key datum)))))
;; Mapping from (numeric type + key bytevector)
;; --> (list of value . interested mq channels)
(define table (make-hash-table))
@@ -600,9 +613,9 @@ supported. When @var{explode} is signalled, the connection
is closed."
(define server
(connect config #:spawn spawn-fiber))
(define (round->key round)
- (define key (make-slice/read-write (sizeof /hashcode:512 '())))
- (slice-u64-set! key 0 round (endianness little))
- key)
+ (define key-slice (make-slice/read-write (sizeof /hashcode:512 '())))
+ (slice-u64-set! key-slice 0 round (endianness little))
+ (make-hashcode:512/share key-slice))
(define (make-a-insertion type round j)
(define key (round->key round))
(define value (make-slice/read-write 8))
@@ -729,7 +742,7 @@ supported. When @var{explode} is signalled, the connection
is closed."
(define (make-a-query round)
(define key (make-slice/read-write (sizeof /hashcode:512 '())))
(slice-u64-set! key 0 round (endianness big))
- (make-query type key))
+ (make-query type (make-hashcode:512/share key)))
(define (value round)
(expt 2 round))
(define done (make-condition))
@@ -740,7 +753,8 @@ supported. When @var{explode} is signalled, the connection
is closed."
(lambda (search-result)
(define d (search-result->datum search-result))
(assert (= round
- (slice-u64-ref (datum-key d) 0
+ (slice-u64-ref (hashcode:512->slice
+ (datum-key d)) 0
(endianness big))))
(assert (= (value round)
(slice-u64-ref (datum-value d) 0
@@ -757,7 +771,8 @@ supported. When @var{explode} is signalled, the connection
is closed."
(define value-s (make-slice/read-write (sizeof u64/big '())))
(slice-u64-set! key-s 0 round (endianness big))
(slice-u64-set! value-s 0 (value round) (endianness big))
- (put! server (datum->insertion (make-datum type key-s value-s)))
+ (put! server (datum->insertion
+ (make-datum type (make-hashcode:512/share key-s) value-s)))
(when (< round (- ROUNDS 1))
(loop (+ round 1))))
(wait done)
--
To stop receiving notification emails like this one, please contact
gnunet@gnunet.org.
- [gnunet-scheme] branch master updated (e57fe14 -> b5da87e), gnunet, 2022/11/21
- [gnunet-scheme] 02/07: hashcode: Correct name of hashcode:512->slice and hashcode:256->slice., gnunet, 2022/11/21
- [gnunet-scheme] 06/07: NEWS: Mention DHT and hashcode changes., gnunet, 2022/11/21
- [gnunet-scheme] 03/07: doc: Document hashcodes., gnunet, 2022/11/21
- [gnunet-scheme] 07/07: doc/network-structures: Add label for cross-references., gnunet, 2022/11/21
- [gnunet-scheme] 04/07: hashcode: Correct constructors., gnunet, 2022/11/21
- [gnunet-scheme] 01/07: hashcode: Correct exports., gnunet, 2022/11/21
- [gnunet-scheme] 05/07: Implement (gnu gnunet dht client) in terms of hashcodes.,
gnunet <=