Deirdre Connolly
362f773762
Tidy tests
2020-02-13 15:04:04 -05:00
Deirdre Connolly
30a7647682
Move over various EncryptedCiphertext types from transaction/ module
2020-02-13 15:04:04 -05:00
Deirdre Connolly
ecaaa21d1c
Improve test for Memo::from support
2020-02-13 15:04:04 -05:00
Deirdre Connolly
b8f7487e54
Use AsRef<[u8]>> in From impl
2020-02-13 15:04:04 -05:00
Deirdre Connolly
8572c70716
impl From<String> for Memo
...
I want From<str> but need Sized
2020-02-13 15:04:04 -05:00
Deirdre Connolly
d4d1cf8d7b
Add memo type with Debug impl and some test cases
2020-02-13 15:04:04 -05:00
Henry de Valence
3c6fda8e0b
Make the BlockHeaderHash conversions work on borrows.
2020-02-10 09:03:56 -08:00
Henry de Valence
5f6bf188ff
Derive Hash for BlockHeaderHash.
...
This allows using BlockHeaderHashes in HashSets, HashMaps, etc.
2020-02-10 09:03:56 -08:00
Henry de Valence
ebf60b8840
Make BlockHeader fields public.
2020-02-10 09:03:56 -08:00
Deirdre Connolly
824f206dbe
Add several Debug impls for existing types
...
Resolves #237
2020-02-07 21:30:48 -08:00
Deirdre Connolly
866acde6e8
Add BLOCK_MAINNET_415000_BYTES test vector and a test to deserialize it
...
And println! it, for human eyeballs checking.
Resolves #218
Also changes the header constant to use _BYTES.
2020-02-07 13:42:21 -08:00
Henry de Valence
972d16518f
Make ZcashSerialize infallible mod its Writer.
...
Closes #158 .
As discussed on the issue, this makes it possible to safely serialize
data into hashes, and encourages serializable data to make illegal
states unrepresentable.
2020-02-05 19:48:43 -05:00
Henry de Valence
f04f4f0b98
Apply clippy fixes
2020-02-05 12:42:32 -08:00
Deirdre Connolly
b860461644
Update test block header hash
2020-02-04 18:04:53 -05:00
Deirdre Connolly
6dedb7e101
Write and read the equihash solution compactsize on (de)serialize
2020-02-04 18:04:53 -05:00
Deirdre Connolly
a79969b38f
Add comment around sha256d_flush test
2020-02-04 18:04:53 -05:00
Deirdre Connolly
4fcb66ad3b
Read and write the block header version, which is fixed at 4
2020-02-04 18:04:53 -05:00
Deirdre Connolly
7ebb5ccd41
Add a simple test to check that our mainnet blockheader test vector deserializes without error
2020-02-04 18:04:53 -05:00
Deirdre Connolly
9257d838bd
Use Result::expect() in test (de)serializations
2020-02-04 18:04:53 -05:00
Deirdre Connolly
9b6a9d8e86
Remove debugging variable assignments
2020-02-04 18:04:53 -05:00
Deirdre Connolly
d12db25acb
Cleanup
2020-02-04 18:04:53 -05:00
Deirdre Connolly
54628d889e
Add proptests-regressions/block/tests.txt
2020-02-04 18:04:53 -05:00
Deirdre Connolly
36e9bb162f
Move block type tests and proptest support impls to block::tests
2020-02-04 18:04:53 -05:00
Deirdre Connolly
6508540a92
Remove derive(Arbitrary) on BlockHeader
2020-02-04 18:04:53 -05:00
Deirdre Connolly
b758a8f753
Extend blockheaderhash unit test to check a single (de)serialization case roundtrip
2020-02-04 18:04:53 -05:00
Deirdre Connolly
dab99ba861
Impl Zcash(De)Serialization for Block
2020-02-04 18:04:53 -05:00
Deirdre Connolly
f5c135ee1b
Use updated EquihashSolution in BlockHeader
2020-02-04 18:04:53 -05:00
Deirdre Connolly
4d7bd3e2d7
derive(Copy) on SaplingNoteTreeRootHash
2020-02-04 18:04:53 -05:00
Deirdre Connolly
0f4d3e4a6d
derive(Arbitrary) on MerkleTreeRootHash
2020-02-04 18:04:53 -05:00
Deirdre Connolly
d5800e168c
Add a roundtrip (de)serialization proptest for EquihashSolution
2020-02-04 18:04:53 -05:00
Deirdre Connolly
c2bb6c15f8
Implement a bunch of traits for EquihashSolution
2020-02-04 18:04:53 -05:00
Deirdre Connolly
e82cf0f5a8
Add BlockHeaderHash (de)serialization roundtrip proptest
2020-02-04 18:04:53 -05:00
Deirdre Connolly
69164a6943
Add test for BlockHeaderHash::from(BlockHeader)
2020-02-04 18:04:53 -05:00
Deirdre Connolly
29e1be2442
Impl Zcash(De)Serialize for BlockHeader
2020-02-04 18:04:53 -05:00
Deirdre Connolly
e9d1f91d67
Make MerkleTreeRootHash wrapped array public
2020-02-04 18:04:53 -05:00
Deirdre Connolly
3ea4a6a9ab
Move transaction test vectors around
...
Resolves #210
2020-02-04 18:04:53 -05:00
Deirdre Connolly
1ca55846eb
Little test to exercise sha256dWriter::flush()
2020-02-04 18:04:53 -05:00
dependabot-preview[bot]
73463c33f4
Bump ed25519-zebra from 0.1.0 to 0.2.0
...
Bumps [ed25519-zebra](https://github.com/ZcashFoundation/ed25519-zebra ) from 0.1.0 to 0.2.0.
- [Release notes](https://github.com/ZcashFoundation/ed25519-zebra/releases )
- [Changelog](https://github.com/ZcashFoundation/ed25519-zebra/blob/main/CHANGELOG.md )
- [Commits](https://github.com/ZcashFoundation/ed25519-zebra/compare/0.1.0...0.2.0 )
Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2020-01-30 20:51:20 -08:00
Deirdre Connolly
359a7dc5eb
Add some proptest shrinkage
2020-01-28 03:48:23 -05:00
Deirdre Connolly
46fa30a66a
Don't use Utc::now() in our LockTime strategy
2020-01-28 03:48:23 -05:00
Deirdre Connolly
ac3c31b1c2
Rearrange and tidy imports
2020-01-28 03:48:23 -05:00
Deirdre Connolly
157add149a
Note that shielded_data::EncryptedCiphertext should move as part of note encryption work
...
Co-Authored-By: Henry de Valence <hdevalence@hdevalence.ca>
2020-01-28 03:48:23 -05:00
Deirdre Connolly
101f0a5c0a
Remove commented out asserts in serialize
...
Co-Authored-By: Henry de Valence <hdevalence@hdevalence.ca>
2020-01-28 03:48:23 -05:00
Deirdre Connolly
cdeaeaa3d6
Remove commented out asserts
...
Co-Authored-By: Henry de Valence <hdevalence@hdevalence.ca>
2020-01-28 03:48:23 -05:00
Deirdre Connolly
09e34f258f
Note that joinsplit::EncryptedCiphertext structs should move as part of note encryption work
...
Co-Authored-By: Henry de Valence <hdevalence@hdevalence.ca>
2020-01-28 03:48:23 -05:00
Deirdre Connolly
283d06bb08
Add (de)serialization roundtrip proptext for shielded_data::(Encrypted,Out)Ciphertext
2020-01-28 03:48:23 -05:00
Deirdre Connolly
2df20b9e6c
Add (de)serialization roundtrip proptext for joinsplit::EncryptedCiphertext
2020-01-28 03:48:23 -05:00
Deirdre Connolly
f379b36208
Add v4 transaction proptest shrinkage
2020-01-28 03:48:23 -05:00
Deirdre Connolly
a259a6b4b1
Add and use v4_strategy()
2020-01-28 03:48:23 -05:00
Deirdre Connolly
a93e2db44b
Add and use OutCiphertext
...
Instead of [u64; 10].
2020-01-28 03:48:23 -05:00
Deirdre Connolly
289f8ec9ca
impl Arbitrary for SpendDescription and refine impl for ShieldedData
2020-01-28 03:48:23 -05:00
Deirdre Connolly
f8781c3415
Refine Arbitrary impl for JoinSplitData<P>
2020-01-28 03:48:23 -05:00
Deirdre Connolly
90086d4d2d
derive(Arbitrary) on Sapling*Note*Tree types
2020-01-28 03:48:23 -05:00
Deirdre Connolly
100c5b15ec
Impl Arbitrary for ShieldedData and derive it for other types
...
Wraps the construction of redjubjub Signature so we don't
need an explicit impl for it.
2020-01-28 03:48:23 -05:00
Deirdre Connolly
7632863454
Impl Arbitrary for JoinSplitData<P>
...
Wraps the construction of ed25519 PublicKeyBytes and Signature so we don't
need an explicit impl for ed25519 types.
2020-01-28 03:48:23 -05:00
Deirdre Connolly
7e34a543ff
Impl Arbitrary for Groth16Proof
2020-01-28 03:48:23 -05:00
Deirdre Connolly
b47e886eed
Add transaction v3 proptest strategy
2020-01-28 03:48:23 -05:00
Deirdre Connolly
b786e1e19c
derive Arbitrary on BlockHeight
2020-01-28 03:48:23 -05:00
Deirdre Connolly
9cbc60a2d7
Proptest v1 and v2 transaction variants
2020-01-28 03:48:23 -05:00
Deirdre Connolly
31b759a924
Update (de)serialization to use EncryptedCiphertext types
2020-01-28 03:48:23 -05:00
Deirdre Connolly
ffd64d4b71
Add shielded_data::EncryptedCiphertext
2020-01-28 03:48:23 -05:00
Deirdre Connolly
95f3c61e53
Add joinsplit::EncryptedCiphertext and derive(Arbitrary) on JoinSplit*
2020-01-28 03:48:23 -05:00
Deirdre Connolly
7d520f8133
Impl Arbitrary for Bctv14Proof
2020-01-28 03:48:23 -05:00
Deirdre Connolly
f4df61eb47
Remove commented out extra Arbitrary impl for Locktime
2020-01-28 03:48:23 -05:00
Deirdre Connolly
b0c0055915
Transaction::V1 round trip proptest
2020-01-28 03:48:23 -05:00
Deirdre Connolly
dfb28b7854
Stubbing out an Arbitrary impl for variant V1 of the Transaction enum
2020-01-28 03:48:23 -05:00
Deirdre Connolly
1ee79b79d3
Add proptest-regressions for transaction/tests.rs
2020-01-28 03:48:23 -05:00
Deirdre Connolly
eb5b3dfefc
Add zcash_[de]serialize roundtrip proptest for Script type
2020-01-28 03:48:23 -05:00
Deirdre Connolly
86f631f9b7
Truncate LockTime::Time datetimes to only seconds for proptests
2020-01-28 03:48:23 -05:00
Deirdre Connolly
71d5571e39
Add roundtrip proptest for LockTime serialization/deserialization
...
Relates to #150
2020-01-28 03:48:23 -05:00
Henry de Valence
60f3f35d89
Refine Ed25519 byte arrays to ed25519-zebra types.
2020-01-24 16:43:31 -05:00
Henry de Valence
2e04610be3
Fix doc errors (missing links, etc).
2020-01-24 13:38:23 -08:00
Henry de Valence
4d5c8c7940
Clarify Transaction docs to point to iterator methods.
...
Closes #191 .
2020-01-24 13:38:23 -08:00
Henry de Valence
41021c65ad
Implement transaction (de)serialization.
2019-12-31 02:46:39 -05:00
Henry de Valence
53cae4647e
Make invalid ShieldedData unrepresentable.
...
ShieldedData objects must have at least one spend or output; using Either
ensures that at least one must be present. This is similar to the
JoinSplitData case, but slightly more complicated: rather than enforcing that
one list has at least one element (which can be done as `(first, rest)`), here
we need to use Either. This has the downside that it is possible to construct
multiple equivalent internal representations (choosing whether a spend or
output goes in the `first` slot), but this easily fixed with a custom PartialEq
implementation.
2019-12-31 02:46:39 -05:00
Henry de Valence
3a7ddbad2d
Add another convenience method for arrays, this time 64 bytes.
2019-12-31 02:46:39 -05:00
Henry de Valence
049998c751
Fix publicity for SaplingNoteTreeRootHash
2019-12-31 02:46:39 -05:00
Henry de Valence
8ff4139c1f
Use Groth16Proof in ShieldedData, not just JoinSplits.
2019-12-31 02:46:39 -05:00
Henry de Valence
92ddf0542f
Provide impl Zcash[De]Serialize for Vec<T: Zcash[De]Serialize>.
...
This replaces the read_list function and makes the code significantly cleaner.
The only downside is that it loses exact preallocation, but this is probably not a big deal.
2019-12-31 02:46:39 -05:00
Henry de Valence
1199cfa23e
impl Zcash[De]Serialize for Script
2019-12-31 02:46:39 -05:00
Henry de Valence
392825c4cb
Add Zcash[De]Serialize bound to ZkSnarkProof.
2019-12-31 02:46:39 -05:00
Henry de Valence
fa1e168fb5
Ensure that invalid JoinSplitDatas are unrepresentable.
...
All JoinSplitDatas must contain at least one JoinSplit.
2019-12-31 02:46:39 -05:00
Henry de Valence
c26304d983
Correct an error in transaction modeling.
...
In the previous transaction modeling I defined the structs so that the number
of old and new commitments for a JoinSplit were variable, when in fact the
Sprout design fixes both to be 2. So now they are hardcoded as 2 in the source
code as well. This commit also fixes some missing `pub` fields on the
`JoinSplit` struct.
2019-12-31 02:46:39 -05:00
Henry de Valence
056127dc94
Copy a transaction test vector from librustzcash.
2019-12-31 02:46:39 -05:00
Henry de Valence
2965187b91
Upgrade tokio, futures, hyper to released versions.
2019-12-13 17:42:15 -05:00
Henry de Valence
4315235d52
Use RedJubjub types in zebra-chain. ( #142 )
2019-12-12 14:23:19 -05:00
Henry de Valence
c013895cd7
Update Transaction definition. ( #105 )
...
* Added a few more top-level fields for the Transaction struct
* Add a placeholder Script type.
This could alternately use bytes::Bytes to save some allocations
but I don't think this is important to get perfectly now. In the future, we
will want to have all of the script handling code in the zebra-script crate,
but we will need to have a container type for an encoded script in zebra-chain,
because otherwise zebra-chain would depend on zebra-script and not the other
way around.
* Rename Transaction{Input,Output} -> Transparent{Input,Output}.
These are only *transparent* inputs and outputs, so by putting Transparent in
the name (instead of Transaction) it's more clear that a transaction's inputs
or outputs can also be shielded.
* Add a LockTime enum.
* First attempt at a Transaction enum.
This attempts to map the versioning and field presence rules into an ADT, so
that structurally invalid transactions (e.g., a BCTV14 proof in a Sapling
transaction) are unrepresentable.
* Update zebra-chain/src/transaction.rs
Co-Authored-By: Daira Hopwood <daira@jacaranda.org>
* Add fixme note on type refinement.
* Rename Transaction variants according to version.
* Split transaction.rs into submodules.
* Start filling in spend, output descriptions.
* Progress on JoinSplit data structures.
This has a lot of duplication and should really use generics to abstract over
Sprout-on-BCTV14 or Sprout-on-Groth16.
* Add data types for Bctv14 and Groth16 proofs.
This also adds a trait to abstract over them.
* Make JoinSplit descriptions generic over the proof system.
* Update zebra-chain/src/transaction/joinsplit.rs
2019-12-05 15:56:58 -05:00
Deirdre Connolly
51b888c0ff
Impl custom Debug for TransactionHash
...
Resolves #104
2019-12-05 10:07:47 -08:00
Henry de Valence
f00c16a624
Require that compactsize encodings are canonical.
2019-11-20 11:59:54 -05:00
Henry de Valence
68a6837cc1
Add a bytes round-trip test for compactsize encoding.
2019-11-20 11:59:54 -05:00
Henry de Valence
986b5ee46b
Fix overlapping range in compactsize encoding.
2019-11-20 11:59:54 -05:00
Henry de Valence
ca24aaf58e
Add the seed for the failing proptest case.
2019-11-20 11:59:54 -05:00
Henry de Valence
2b9991e4e7
Add a basic proptest for compactsize encodings.
...
There's a compiler warning about overlapping ranges so this test should catch the bug.
2019-11-20 11:59:54 -05:00
Henry de Valence
5b801400c1
Update zebra-chain/Cargo.toml
2019-10-17 09:33:10 -07:00
Deirdre Connolly
96ad551681
Remove unnecessary write_all impl
2019-10-17 09:33:10 -07:00
Deirdre Connolly
65d988471a
Implement custom Debug for Sha256dChecksum
...
Relates to #63
2019-10-17 09:33:10 -07:00
Deirdre Connolly
539a16979b
Implement custom Debug impl for BlockHeaderHash
...
Includes a testcase and write_all implementation for Sha256dWriter.
Related to #63
2019-10-17 09:33:10 -07:00
Henry de Valence
f6e62b0f5e
Remove failure from zebra-chain, zebra-network.
...
Failure uses a distinct Fail trait rather than the standard library's
Error trait, which causes a lot of interoperability problems with tower
and other Error-using crates. Since failure was created, the standard
library's Error trait was improved, and its conveniences are now
available without the custom Fail trait using `thiserror` (for easy
error derives) and `anyhow` (for a better boxed Error).
2019-10-16 13:16:52 -04:00
Deirdre Connolly
e1f2eaa446
Add details about max_count to read_list docstring
2019-10-09 22:25:37 -04:00
Deirdre Connolly
dd1b9166b0
Implement Zcash(De)Serialize for BlockHeaderHash, use general read_list for getheaders/headers
2019-10-09 22:25:37 -04:00
Deirdre Connolly
eed69063f6
Add read_list to ReadZcashExt
2019-10-09 22:25:37 -04:00
Henry de Valence
92dc7a5ea1
Fix authorship, license information. ( #55 )
...
* Fix authorship, license information.
I *thought* I had done a sed pass over the Cargo defaults when doing
repository initialization, but I guess I missed it or something.
Anyways, fixed now.
2019-10-08 09:25:59 -07:00
Henry de Valence
47513b1ae7
Suppress warnings from stub functions.
...
This just replaces a bunch of variable names with underscored variants
while the function bodies are still `unimplemented!()`.
2019-09-30 21:32:57 -04:00
Henry de Valence
1323fa7af7
Update zebra-chain/src/transaction.rs
2019-09-27 19:22:34 -07:00
Deirdre Connolly
2739970113
Fill out TransactionHash and rename
...
Resolves #35
2019-09-27 19:22:34 -07:00
Deirdre Connolly
b21b09bf8e
Moved stub TxHash into zebra_chain::transaction
2019-09-27 19:22:34 -07:00
Deirdre Connolly
29591df47e
Use the BlockHeaderHash from zebra-chain in the Inv message parsing
2019-09-27 19:22:34 -07:00
Henry de Valence
958fca8e68
Parse inv messages, refactor inventory vectors.
...
This removes the inventory vector structs from `zebra-chain` (as they
are really part of the network protocol) and refactors them into a
single `InventoryHash` type. This corresponds to Bitcoin's "inventory
vector" but with a different, better name (it's not a vector, it's just
a typed hash of some other item).
2019-09-27 20:41:45 -04:00
Henry de Valence
64b210b53c
Add a read_32_bytes helper method.
...
These are starting to stack up but I think until generic arrays arrive
the cure is worse than the disease :S
2019-09-27 20:41:45 -04:00
Deirdre Connolly
19258d6f54
Remove duplicate from MerkleTree
2019-09-26 23:41:25 -04:00
Deirdre Connolly
b4b72829b2
Sanity: checked
2019-09-26 23:41:25 -04:00
Deirdre Connolly
6236909210
Update zebra-chain/src/transaction.rs
...
Co-Authored-By: Henry de Valence <hdevalence@hdevalence.ca>
2019-09-26 23:41:25 -04:00
Deirdre Connolly
4e85bdb51b
Explain in BlockHeaderHash docstrings block hash vs block header hash
2019-09-26 23:41:25 -04:00
Deirdre Connolly
df5a5f56dd
Add equihash_solution to the lib.rs, impl Zcash(De)Serialize for Block
2019-09-26 23:41:25 -04:00
Deirdre Connolly
f4a6fec2d8
Comment out EquihashSolution::fmt for now
2019-09-26 23:41:25 -04:00
Deirdre Connolly
3f2a1b4f2c
Move around MerkleTree* structs
2019-09-26 23:41:25 -04:00
Deirdre Connolly
677d53897f
Use Vec<u8> for the equihash solution instead of [u8; 1344] for now
2019-09-26 23:41:25 -04:00
Deirdre Connolly
c4547ea806
Derive Clone, Debug, Default, Eq, and PartialEq for new structs
2019-09-26 23:41:25 -04:00
Deirdre Connolly
38015c11a6
Add stubbed-out *NoteCommitmentTree* structs
2019-09-26 23:41:25 -04:00
Deirdre Connolly
90e5ae2f4b
Add improved doc comments
2019-09-26 23:41:25 -04:00
Deirdre Connolly
cecbb1cc0a
Fill out the Block Message type
...
Should we serialize out `Block` or leave explicit like so? ¯\_(ツ)_/¯
2019-09-26 23:41:25 -04:00
Deirdre Connolly
d77dfb2344
Remove unused imports
2019-09-26 23:41:25 -04:00
Deirdre Connolly
0f84a6d38e
Implement Zcash(De)serialize traits specifically for MerkleTree<Transaction>
...
This is a general placeholder for now.
2019-09-26 23:41:25 -04:00
Deirdre Connolly
7340c7d9ce
Adding BlockHeader, BlockHash, MerkleRootHash, Sha256dWriter
2019-09-26 23:41:25 -04:00
Deirdre Connolly
00494d4963
Block and BlockHeader types
2019-09-26 23:41:25 -04:00
Henry de Valence
fe95ad3824
Suppress unused import warning in ReadZcashExt.
2019-09-25 14:59:47 -07:00
Henry de Valence
b3e094bc40
Clean parsing via ReadZcashExt read-array helpers.
...
This adds convenience methods to `ReadZcashExt` that read 4 and 12 byte
fixed size arrays from the `Reader`, making the actual parsing code more
legible.
Closes #10 .
2019-09-19 12:53:16 -04:00
Deirdre Connolly
73740841e1
Move `Transaction` and related types to their own module ( #9 )
...
* Move `Transaction` and related types to their own module
Resolves #6
* Fix references to `Transaction` after move
2019-09-19 07:45:37 -07:00
Deirdre Connolly
60fb4f6bb0
Remove InventoryType::MsgCmpctBlock
...
From BIP-152, which is not implemented by Zcash.
2019-09-18 17:32:06 -04:00
Deirdre Connolly
65632e9f42
Correct comment about pzec bytes::Bytes
2019-09-18 17:32:06 -04:00
Deirdre Connolly
46984cbb27
Add `tx` message, along with `Transaction`, `Transaction(In|Out)put`, and `OutPoint` types
2019-09-18 17:32:06 -04:00
Henry de Valence
733d090b9b
Add missing derives to newtypes.
2019-09-18 17:32:06 -04:00
Henry de Valence
32cf74db39
Move serialization to zebra-chain, rework traits.
...
The core serialization logic is now in zebra-chain and consists of two
pairs of traits:
These are analogues of the Serde `Serialize` and `Deserialize` traits,
but explicitly intended for consensus-critical serialization formats.
Thus some struct `Foo` may have derived `Serialize` and `Deserialize`
implementations for (internal) use with Serde, and explicitly-written
`ZcashSerialize` and `ZcashDeserialize` implementations for use in
consensus-critical contexts. The consensus-critical implementations
provide `zcash`-prefixed `zcash_serialize` and `zcash_deserialize`
methods to make it clear in client contexts that the serialization is
consensus-critical.
These are utility traits, analogous to the `ReadBytesExt` and
`WriteBytesExt` traits provided by `byteorder`. A generic
implementation is provided for any `io::Read` or `io::Write`, so that
bringing the traits into scope adds additional Zcash-specific traits to
generic readers and writers -- for instance, writing a `u64` in the
Bitcoin "CompactSize" format.
2019-09-18 17:32:06 -04:00
Henry de Valence
42cb9c1ff9
Add a `Sha256dChecksum` type for truncated double SHA256.
2019-09-18 17:32:06 -04:00
Deirdre Connolly
a2e50833be
Add InventoryType, InventoryVector, and Message::{Inventory, GetData, NotFound}
2019-09-18 17:32:06 -04:00
Deirdre Connolly
ac0d9732a0
WIP: Version message and various sub structures
...
Co-authored-by: Henry de Valence <hdevalence@hdevalence.ca>
2019-09-18 17:32:06 -04:00
Henry de Valence
ec363d2d41
Create workspace skeleton based on design.md
2019-08-29 14:46:54 -07:00