Эх сурвалжийг харах

Started writing round trip tests.

Matthew Carr 3 жил өмнө
parent
commit
3133134ee5

+ 1 - 0
crates/node/.vscode/settings.json

@@ -2,6 +2,7 @@
     "cSpell.words": [
         "Asym",
         "blocktree",
+        "Hashable",
         "newtype",
         "Xsalsa"
     ]

+ 12 - 0
crates/node/Cargo.lock

@@ -6,6 +6,8 @@ version = 3
 name = "node"
 version = "0.1.0"
 dependencies = [
+ "serde",
+ "serde-big-array",
  "serde_block_tree",
 ]
 
@@ -36,11 +38,21 @@ dependencies = [
  "serde_derive",
 ]
 
+[[package]]
+name = "serde-big-array"
+version = "0.4.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3323f09a748af288c3dc2474ea6803ee81f118321775bffa3ac8f7e65c5e90e7"
+dependencies = [
+ "serde",
+]
+
 [[package]]
 name = "serde_block_tree"
 version = "0.1.0"
 dependencies = [
  "serde",
+ "serde-big-array",
 ]
 
 [[package]]

+ 2 - 0
crates/node/Cargo.toml

@@ -8,3 +8,5 @@ edition = "2018"
 
 [dependencies]
 serde_block_tree = { path = "../serde_block_tree" }
+serde = { version = "1.0.136", features = ["derive"] }
+serde-big-array = { version = "0.4.1" }

+ 1 - 1
crates/node/README.md

@@ -4,4 +4,4 @@ This crate implements a blocktree node. It is responsible for the following:
   * Communicating over the network with other nodes.
   * Running programs in their own separate sandbox processes. 
   * Routing HTTP request to programs which have registered handlers.
-  * Receiving orders from its parent via stdout/stdin.
+  * Receiving orders from its parent via stdin.

+ 26 - 1
crates/node/src/main.rs

@@ -1,7 +1,16 @@
-use std::collections::HashMap;
+use std::{
+    collections::HashMap,
+    hash::Hash as Hashable,
+};
+use serde::{Serialize, Deserialize};
+use serde_big_array::BigArray;
+
+#[cfg(test)]
+mod serde_tests;
 
 /// A Block tagged with its version number.
 #[allow(dead_code)]
+#[derive(Debug, PartialEq, Serialize, Deserialize)]
 enum VersionedBlock {
     V0(Block)
 }
@@ -9,6 +18,7 @@ enum VersionedBlock {
 /// A container which binds together ciphertext along with the metadata needed to identify,
 /// verify and decrypt it.
 #[allow(dead_code)]
+#[derive(Debug, PartialEq, Serialize, Deserialize)]
 struct Block {
     /// Identifies this block and defines its location in the tree.
     path: Path,
@@ -27,6 +37,7 @@ struct Block {
 
 /// An envelopment of a key, which is tagged with the principal who the key is meant for.
 #[allow(dead_code)]
+#[derive(Debug, PartialEq, Serialize, Deserialize)]
 struct ReadCap {
     /// The principal this `ReadCap` was issued to.
     issued_to: Principal,
@@ -36,6 +47,7 @@ struct ReadCap {
 
 /// Verifies that a principal is authorized to write blocks in a tree.
 #[allow(dead_code)]
+#[derive(Debug, PartialEq, Serialize, Deserialize)]
 struct WriteCap {
     /// The principal this `WriteCap` was issued to.
     issued_to: Principal,
@@ -54,6 +66,7 @@ struct WriteCap {
 /// Fragments are created from blocks using Erasure Encoding and stored with other nodes in the
 /// network to provide availability and redundancy of data.
 #[allow(dead_code)]
+#[derive(Debug, PartialEq, Serialize, Deserialize)]
 struct Fragment {
     /// The path to the block this fragment is from.
     path: Path,
@@ -65,6 +78,7 @@ struct Fragment {
 
 /// The body of every non-leaf node in a tree contains this data structure.
 #[allow(dead_code)]
+#[derive(Debug, PartialEq, Serialize, Deserialize)]
 struct Directory {
     /// The nodes that are attached to the tree at this block.
     nodes: Vec<Principal>,
@@ -74,6 +88,7 @@ struct Directory {
 
 /// Keeps track of which principal is storing a fragment.
 #[allow(dead_code)]
+#[derive(Debug, PartialEq, Serialize, Deserialize)]
 struct FragmentRecord {
     /// The fragment serial number this record is for.
     serial: FragmentSerial,
@@ -82,35 +97,45 @@ struct FragmentRecord {
 }
 
 /// An identifier for a security principal, which is any entity that can be authenticated.
+#[derive(Debug, PartialEq, Eq, Serialize, Deserialize, Hashable)]
 struct Principal(Hash);
 
 /// Encrypted data.
+#[derive(Debug, PartialEq, Serialize, Deserialize)]
 struct Ciphertext<T>(T);
 
 /// An identifier for a block in a tree.
+#[derive(Debug, PartialEq, Serialize, Deserialize)]
 struct Path(Vec<String>);
 
 /// An instant in time represented by the number of seconds since January 1st 1970, 00:00:00 UTC.
+#[derive(Debug, PartialEq, Serialize, Deserialize)]
 struct Epoch(u64);
 
 /// The serial number of a block fragment.
+#[derive(Debug, PartialEq, Eq, Serialize, Deserialize, Hashable)]
 struct FragmentSerial(u32);
 
 /// A cryptographic hash.
 #[allow(dead_code)]
+#[derive(Debug, PartialEq, Eq, Serialize, Deserialize, Hashable)]
 enum Hash {
     Sha2_256([u8; 32]),
+    #[serde(with = "BigArray")]
     Sha2_512([u8; 64]),
 }
 
 /// A cryptographic signature.
 #[allow(dead_code)]
+#[derive(Debug, PartialEq, Serialize, Deserialize)]
 enum Signature {
+    #[serde(with = "BigArray")]
     Ed25519([u8; 64]),
 }
 
 /// A cryptographic key.
 #[allow(dead_code)]
+#[derive(Debug, PartialEq, Serialize, Deserialize)]
 enum Key {
     Xsalsa20Poly1305([u8; 32]),
 }

+ 21 - 0
crates/node/src/serde_tests.rs

@@ -0,0 +1,21 @@
+/// Tests which ensure that the main data structures can be round-tripped faithfully.
+
+use super::*;
+use serde_block_tree::{Result, from_vec, to_vec};
+
+static RANDOM_32ARRAY: [u8; 32] = [
+    0x75, 0x28, 0xA9, 0xE0, 0x9D, 0x24, 0xBA, 0xB3, 0x79, 0x56, 0x15, 0x68, 0xFD, 0xA4, 0xE2, 0xA4,
+    0xCF, 0xB2, 0xC, 0xE3, 0x96, 0xAE, 0xA2, 0x6E, 0x45, 0x15, 0x50, 0xED, 0xA6, 0xBE, 0x6D, 0xEC
+];
+
+#[test]
+fn roundtrip_fragment_record() -> Result<()> {
+    let expected = FragmentRecord {
+        serial: FragmentSerial(229),
+        stored_by: Principal(Hash::Sha2_256(RANDOM_32ARRAY))
+    };
+    let ser_result = to_vec(&expected);
+    let de_result = from_vec(&ser_result?);
+    assert_eq!(expected, de_result?);
+    Ok(())
+}