Fix documentation (#1652)

* Markdown formating
This commit is contained in:
Quentin Le Sceller 2018-10-03 16:31:28 -04:00 committed by GitHub
parent f2b4c6dc07
commit 1e93b7fe65
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
23 changed files with 509 additions and 489 deletions

View file

@ -6,22 +6,24 @@ Longer term, most platforms will likely be supported to some extent.
Grin's programming language `rust` has build targets for most platforms.
What's working so far?
* Linux x86\_64 and MacOS [grin + mining + development]
* Not Windows 10 yet [grin kind-of builds. No mining yet. Help wanted!]
## Requirements
- rust 1.26+ (use [rustup]((https://www.rustup.rs/))- i.e. `curl https://sh.rustup.rs -sSf | sh; source $HOME/.cargo/env`)
- if rust is already installed, you can simply update version with `rustup update`
- clang
- ncurses and libs (ncurses, ncursesw5)
- zlib libs (zlib1g-dev or zlib-devel)
- pkg-config
- libssl-dev
- linux-headers (reported needed on Alpine linux)
* rust 1.26+ (use [rustup]((https://www.rustup.rs/))- i.e. `curl https://sh.rustup.rs -sSf | sh; source $HOME/.cargo/env`)
* if rust is already installed, you can simply update version with `rustup update`
* clang
* ncurses and libs (ncurses, ncursesw5)
* zlib libs (zlib1g-dev or zlib-devel)
* pkg-config
* libssl-dev
* linux-headers (reported needed on Alpine linux)
For Debian-based distributions (Debian, Ubuntu, Mint, etc), all in one line (except Rust):
```
```sh
apt install build-essential cmake git libgit2-dev clang libncurses5-dev libncursesw5-dev zlib1g-dev pkg-config libssl-dev
```
@ -32,15 +34,10 @@ git clone https://github.com/mimblewimble/grin.git
cd grin
cargo build --release
```
Grin can also be built in debug mode (without the `--release` flag, but using the `--debug` or the `--verbose` flag) but this will render fast sync prohibitively slow due to the large overhead of cryptographic operations.
## Mining in Grin
Please note that all mining functions for Grin have moved into a separate, standalone package called
[grin_miner](https://github.com/mimblewimble/grin-miner). Once your Grin code node is up and running,
you can start mining by building and running grin-miner against your running Grin node.
### Build errors
## Build errors
See [Troubleshooting](https://github.com/mimblewimble/docs/wiki/Troubleshooting)
@ -48,7 +45,7 @@ See [Troubleshooting](https://github.com/mimblewimble/docs/wiki/Troubleshooting)
A successful build gets you:
- `target/release/grin` - the main grin binary
* `target/release/grin` - the main grin binary
All data, configuration and log files created and used by grin are located in the hidden
`~/.grin` directory (under your user home directory) by default. You can modify all configuration
@ -56,7 +53,7 @@ values by editing the file `~/.grin/grin-server.toml`.
It is also possible to have grin create its data files in the current directory. To do this, run
```
```sh
grin server config
```
@ -67,18 +64,19 @@ the current directory for all of its data. Running grin from a directory that co
While testing, put the grin binary on your path like this:
```
```sh
export PATH=/path/to/grin/dir/target/debug:$PATH
```
Where path/to/grin/dir is your absolute path to the root directory of your Grin installation.
Where path/to/grin/dir is your absolute path to the root directory of your Grin installation.
You can then run `grin` directly (try `grin help` for more options).
# Configuration
## Configuration
Grin attempts to run with sensible defaults, and can be further configured via
the `grin-server.toml` file. This file is generated by grin on its first run, and
contains documentation on each available option.
contains documentation on each available option.
While it's recommended that you perform all grin server configuration via
`grin-server.toml`, it's also possible to supply command line switches to grin that
@ -86,33 +84,39 @@ override any settings in the file.
For help on grin commands and their switches, try:
```
```sh
grin help
grin wallet help
grin client help
```
# Using grin
The wiki page [How to use grin](https://github.com/mimblewimble/docs/wiki/How-to-use-grin)
and linked pages have more information on what features we have,
troubleshooting, etc.
## Docker
```
```sh
docker build -t grin .
```
You can bind-mount your grin cache to run inside the container.
```
```sh
docker run -it -d -v $HOME/.grin:/root/.grin grin
```
### Cross-platform builds
## Cross-platform builds
Rust (cargo) can build grin for many platforms, so in theory running `grin`
as a validating node on your low powered device might be possible.
To cross-compile `grin` on a x86 Linux platform and produce ARM binaries,
say, for a Raspberry Pi.
## Using grin
The wiki page [How to use grin](https://github.com/mimblewimble/docs/wiki/How-to-use-grin)
and linked pages have more information on what features we have,
troubleshooting, etc.
## Mining in Grin
Please note that all mining functions for Grin have moved into a separate, standalone package called
[grin_miner](https://github.com/mimblewimble/grin-miner). Once your Grin code node is up and running,
you can start mining by building and running grin-miner against your running Grin node.

View file

@ -1,5 +1,4 @@
Blockchain Syncing
==================
# Blockchain Syncing
We describe here the different methods used by a new node when joining the network
to catch up with the latest chain state. We start with reminding the reader of the
@ -87,13 +86,13 @@ with the network when it's actually is in a forged state. Multiple strategies ca
be attempted:
* Completely fake but valid horizon state (including header and proof of work).
Assuming at least one honest peer, neither the UTXO set root hash nor the block
hash will match other peers' horizon states.
Assuming at least one honest peer, neither the UTXO set root hash nor the block
hash will match other peers' horizon states.
* Valid block header but faked UTXO set. The UTXO set root hash from the header
will not match what the node calculates from the received UTXO set itself.
will not match what the node calculates from the received UTXO set itself.
* Completely valid block with fake total difficulty, which could lead the node down
a fake fork. The block hash changes if the total difficulty is changed, no honest
peer will produce a valid head for that hash.
a fake fork. The block hash changes if the total difficulty is changed, no honest
peer will produce a valid head for that hash.
#### A fork occurs that's older than the local UTXO history
@ -125,11 +124,11 @@ headers.
While this is a valid issue, several mitigation strategies exist:
* Peers must still provide valid block headers at horizon `Z`. This includes the
proof of work.
proof of work.
* A group of block headers around the horizon could be asked to increase the cost
of the attack.
of the attack.
* Differing block headers providing a proof of work significantly lower could be
rejected.
rejected.
* The user or node operator may be asked to confirm a block hash.
* In last resort, if none of the above strategies are effective, checkpoints could
be used.
be used.

View file

@ -1,8 +1,11 @@
# grin code structure
grin is built in [rust](https://www.rust-lang.org/), a memory safe, compiled language. Performance critical parts like the Cuckoo mining algorithm are built as plugins, making it easy to swap between algorithm implementations for various hardware. Grin comes with CPU and experimental GPU support.
# Grin code structure
Grin is built in [Rust](https://www.rust-lang.org/), a memory safe, compiled language. Performance critical parts like the Cuckoo mining algorithm are built as plugins, making it easy to swap between algorithm implementations for various hardware. Grin comes with CPU and experimental GPU support.
## Files in project root
List of files tracked in `git` and some files you'll create when you use grin.
- [CODE_OF_CONDUCT](../CODE_OF_CONDUCT.md) - How to behave if you want to participate. Taken from rust. Slightly modified.
- [CONTRIBUTING](../CONTRIBUTING.md) - How to help and become part of grin.
- [Cargo.toml](../Cargo.toml) and Cargo.lock (locally created, _not_ in git) - defines how to the project code is to be compiled and built
@ -11,46 +14,48 @@ List of files tracked in `git` and some files you'll create when you use grin.
- [rustfmt.toml](../rustfmt.toml) - configuration file for rustfmt. Required before contributing _new_ code.
## Folder structure
After checking out grin, building and using, these are the folders you'll have:
- api
Code for ApiEndpoints accessible over REST.
- chain
The blockchain implementation. Accepts a block (see pipe.rs) and adds it to the chain, or reject it.
- config
Code for handling configuration.
- core
All core types: Hash, Block, Input, Output, and how to serialize them. Core mining algorithm, and more.
- doc
All documentation.
- servers
Many parts (adapters, lib, miner, seed, server, sync, types) that the `grin` server needs, including mining server.
- keychain
Code for working safely with keys and doing blinding.
- p2p
All peer to peer connection and protocol-related logic (handshake, block propagation, etc.).
- pool
Code for the transaction pool implementation.
- server
A folder you're [supposed to create](build.md#running-a-node), before starting your server: cd to project root; mkdir server; cd server; grin server start (or run) and it will create a subfolder .grin
- .grin
- chain - a Rocksdb with the blockchain blocks and related information
- peers - a Rocksdb with the list of Grin peers you're connected to
- txhashset - contains folders kernel, rangeproof and output that each have a pmmr_dat.bin
- src
- `api`\
Code for ApiEndpoints accessible over REST.
- `chain`\
The blockchain implementation. Accepts a block (see pipe.rs) and adds it to the chain, or reject it.
- `config`\
Code for handling configuration.
- `core`\
All core types: Hash, Block, Input, Output, and how to serialize them. Core mining algorithm, and more.
- `doc`\
All documentation.
- `servers`\
Many parts (adapters, lib, miner, seed, server, sync, types) that the `grin` server needs, including mining server.
- `keychain`\
Code for working safely with keys and doing blinding.
- `p2p`\
All peer to peer connection and protocol-related logic (handshake, block propagation, etc.).
- `pool`\
Code for the transaction pool implementation.
- `server`\
A folder you're [supposed to create](build.md#running-a-node), before starting your server: cd to project root; mkdir server; cd server; grin server start (or run) and it will create a subfolder .grin
- `.grin`
- `chain` - a Rocksdb with the blockchain blocks and related information
- `peers` - a Rocksdb with the list of Grin peers you're connected to
- `txhashset` - contains folders kernel, rangeproof and output that each have a pmmr_dat.bin
- `src`\
Code for the `grin` binary.
- store
- `store`\
Data store - a thin wrapper for Rocksdb, a key-value database forked from LevelDB.
- target
- `target`\
Where the grin binary ends up, after the compile and build process finishes.
In case of trouble, see [troubleshooting](https://github.com/mimblewimble/docs/wiki/Troubleshooting)
- util
- `util`\
Low-level rust utilities.
- wallet
Simple command line wallet implementation. Will generate:
- wallet_data - a database storing your "outputs", that once confirmed and matured, can be spent with the [`grin wallet send`](wallet.md) command. (locally created, _not_ in git)
- wallet.seed - your secret wallet seed. (locally created, _not_ in git)
- `wallet`\
Simple command line wallet implementation. Will generate:
- `wallet_data` - a database storing your "outputs", that once confirmed and matured, can be spent with the [`grin wallet send`](wallet/usage.md) command. (locally created, *not* in git)
- `wallet.seed` - your secret wallet seed. (locally created, *not* in git)
## grin dependencies
- [secp256k1](https://github.com/mimblewimble/rust-secp256k1-zkp)
Integration and rust bindings for libsecp256k1, and some changes waiting to be upstreamed. Imported in util/Cargo.toml.

View file

@ -7,12 +7,13 @@ Bitcoin does something very similar, requiring 100 confirmations (Bitcoin blocks
Grin enforces coinbase maturity in both the transaction pool and the block validation pipeline. A transaction containing an input spending a coinbase output cannot be added to the transaction pool until it has sufficiently matured (based on current chain height and the height of the block producing the coinbase output).
Similarly a block is invalid if it contains an input spending a coinbase output before it has sufficiently matured, based on the height of the block containing the input and the height of the block that originally produced the coinbase output.
The maturity rule _only_ applies to coinbase outputs, regular transaction outputs have an effective lock height of zero.
The maturity rule *only* applies to coinbase outputs, regular transaction outputs have an effective lock height of zero.
An output consists of -
* features (currently coinbase vs. non-coinbase)
* commitment `rG+vH`
* rangeproof
* features (currently coinbase vs. non-coinbase)
* commitment `rG+vH`
* rangeproof
To spend a regular transaction output two conditions must be met. We need to show the output has not been previously spent and we need to prove ownership of the output.
@ -27,9 +28,9 @@ A Grin transaction consists of the following -
We can show the output is unspent by looking for the commitment in the current Output set. The Output set is authoritative; if the output exists in the Output set we know it has not yet been spent. If an output does not exist in the Output set we know it has either never existed, or that it previously existed and has been spent (we will not necessarily know which).
To prove ownership we can verify the transaction signature. We can _only_ have signed the transaction if the transaction sums to zero _and_ we know both `v` and `r`.
To prove ownership we can verify the transaction signature. We can *only* have signed the transaction if the transaction sums to zero *and* we know both `v` and `r`.
Knowing `v` and `r` we can uniquely identify the output (via its commitment) _and_ we can prove ownership of the output by validating the signature on the original coinbase transaction.
Knowing `v` and `r` we can uniquely identify the output (via its commitment) *and* we can prove ownership of the output by validating the signature on the original coinbase transaction.
Grin does not permit duplicate commitments to exist in the Output set at the same time.
But once an output is spent it is removed from the Output set and a duplicate commitment can be added back into the Output set.
@ -42,7 +43,7 @@ Several things complicate this situation -
1. It is possible (but not recommended) for a miner to reuse private keys.
Grin does not allow duplicate commitments to exist in the Output set simultaneously.
But the Output set is specific to the state of a particular chain fork. It _is_ possible for duplicate _identical_ commitments to exist simultaneously on different concurrent forks.
But the Output set is specific to the state of a particular chain fork. It *is* possible for duplicate *identical* commitments to exist simultaneously on different concurrent forks.
And these duplicate commitments may have different "lock heights" at which they mature and become spendable on the different forks.
* Output O<sub>1</sub> from block B<sub>1</sub> spendable at height h<sub>1</sub> (on fork f<sub>1</sub>)
@ -50,11 +51,11 @@ And these duplicate commitments may have different "lock heights" at which they
The complication here is that input I<sub>1</sub> will spend either O<sub>1</sub> or O<sub>1</sub>' depending on which fork the block containing I<sub>1</sub> exists on. And crucially I<sub>1</sub> may be valid at a particular block height on one fork but not the other.
Said another way - a commitment may refer to multiple outputs, all of which may have different lock heights. And we _must_ ensure we correctly identify which output is actually being spent and that the coinbase maturity rules are correctly enforced based on the current chain state.
Said another way - a commitment may refer to multiple outputs, all of which may have different lock heights. And we *must* ensure we correctly identify which output is actually being spent and that the coinbase maturity rules are correctly enforced based on the current chain state.
A coinbase output, locked with the coinbase maturity rule at a specific lock height, _cannot_ be uniquely identified, and _cannot_ be safely spent by their commitment alone. To spend a coinbase output we need to know one additional piece of information -
A coinbase output, locked with the coinbase maturity rule at a specific lock height, *cannot* be uniquely identified, and *cannot* be safely spent by their commitment alone. To spend a coinbase output we need to know one additional piece of information -
* The block the coinbase output originated from
* The block the coinbase output originated from
Given this, we can verify the height of the block and derive the "lock height" of the output (+ 1,000 blocks).
@ -62,6 +63,7 @@ Given this, we can verify the height of the block and derive the "lock height" o
Given a full archival node it is a simple task to identify which block the output originated from.
A full archival node stores the following -
* full block data of all blocks in the chain
* full output data for all outputs in these blocks
@ -86,7 +88,7 @@ A pruned node may only store the following (refer to pruning doc) -
Given this minimal set of data how do we know which block an output originated from?
And given we now know multiple outputs (multiple forks, potentially different lock heights) can all have the _same_ commitment, what additional information do we need to provide in the input to uniquely identify the output being spent?
And given we now know multiple outputs (multiple forks, potentially different lock heights) can all have the *same* commitment, what additional information do we need to provide in the input to uniquely identify the output being spent?
And to take it a step further - can we do all this without relying on having access to full output data? Can we use just the output MMR?
@ -96,9 +98,10 @@ We maintain an index mapping commitment to position in the output MMR.
If no entry in the index exists or no entry in the output MMR exists for a given commitment then we now the output is not spendable (either it was spent previously or it never existed).
If we find an entry in the output MMR then we know a spendable output exists in the Output set _but_ we do not know if this is the correct one. We do not if it is a coinbase output or not and we do not know the height of the block it originated from.
If we find an entry in the output MMR then we know a spendable output exists in the Output set *but* we do not know if this is the correct one. We do not if it is a coinbase output or not and we do not know the height of the block it originated from.
If the hash stored in the output MMR covers both the commitment and the output features and we require an input to provide both the commitment and the feature then we can do a further validation step -
* output exists in the output MMR (based on commitment), and
* the hash in the MMR matches the output data included in the input
@ -112,7 +115,6 @@ We cannot determine the block itself, but we can require the input to specify th
[tbd - overview of merkle proofs and how we will use these to prove inclusion based on merkle root in the block header]
To summarize -
Output MMR stores output hashes based on `commitment|features` (the commitment itself is not sufficient).
@ -122,14 +124,16 @@ We do not need to include the range proof or the switch commitment hash in the g
We do not need to encode the lock height in the switch commitment hash.
To spend an output we continue to need -
* `r` and `v` to build the commitment and to prove ownership
* `r` and `v` to build the commitment and to prove ownership
An input must provide -
* the commitment (to lookup the output in the MMR)
* the output features (hash in output MMR dependent on features|commitment)
* a merkle proof showing inclusion of the output in the originating block
* the block hash of originating blocks
* [tbd - maintain index based on merkle proof?]
* the commitment (to lookup the output in the MMR)
* the output features (hash in output MMR dependent on features|commitment)
* a merkle proof showing inclusion of the output in the originating block
* the block hash of originating blocks
* [tbd - maintain index based on merkle proof?]
From the commitment and the features we can determine if the correct output is currently unspent.
From the block and the output features we can determine the lock height (if any).

View file

@ -1,3 +1,5 @@
# Contract Ideas
## Atomic Swaps
"On another chain, Igno sends coins to me that I can only redeem by revealing a hash preimage (which he knows, I don't). On the MW chain we do this exchange so that Igno can take my coins by revealing the preimage. When he takes his coins, he reveals it, enabling me to take my coins.

View file

@ -1,3 +1,5 @@
# Contracts
This document describes smart contracts that can be setup using Grin even
though the Grin chain does not support scripting. All these contracts rely
on a few basic features that are built in the chain and compose them in
@ -10,18 +12,18 @@ Pryds Pedersen, Gregory Maxwell, Andrew Poelstra, John Tromp, Claus Peter
Schnorr. We apologize in advance for all those we couldn't name and recognize
that most computer science discoveries are incremental.
# Built-Ins
## Built-Ins
This section is meant as a reminder of some crucial features of the Grin chain.
We assume some prior reading as to how these are constructed and used.
## Pedersen Commitments
### Pedersen Commitments
All outputs include a Pedersen commitment of the form `r*G + v*H` with `r`
the blinding factor, `v` the value, and G and H two distinct generator points
on the same curve group.
## Aggregate Signatures (a.k.a. Schnorr, MuSig)
### Aggregate Signatures (a.k.a. Schnorr, MuSig)
We suppose we have the SHA256 hash function and the same G curve as above. In
its simplest form, an aggregate signature is built from:
@ -52,20 +54,20 @@ public key `r*G`, and allows to verify non-inflation for all Grin transactions
Because these signatures are built simply from a scalar and a public key, they
can be used to construct a variety of contracts using "simple" arithmetic.
## (Absolute) Timelocked Transactions
### (Absolute) Timelocked Transactions
Analogous to Bitcoin [nLockTime](https://en.bitcoin.it/wiki/Timelock#nLockTime).
A transaction can be time-locked with a few simple modifications:
* the message `M` to sign becomes the lock_height `h` at which the transaction
becomes spendable appended to the fee
* `M = fee | h`
becomes spendable appended to the fee
* `M = fee | h`
* the lock height `h` is included in the transaction kernel
* a block with a kernel that includes a lock height greater than the current
block height is rejected
block height is rejected
## (Relative) Timelocked Transactions
### (Relative) Timelocked Transactions
We can extend the concept of an absolute locktime on a tx by including a (kernel) commitment that we can define the lock_height relative to.
@ -74,16 +76,16 @@ The lock_height would be relative to the block height where the referenced kerne
Tx2 can then be restricted such that it would only be valid to include it in a block once `h` blocks have passed after first seeing Tx1 (via the referenced kernel commitment).
* the message `M` to sign would need to include the following -
* the `fee` as before
* the lock_height `h` (as before but interpreted as a relative value)
* a referenced kernel commitment `C`
* M = `fee | h | C`
* the `fee` as before
* the lock_height `h` (as before but interpreted as a relative value)
* a referenced kernel commitment `C`
* M = `fee | h | C`
For Tx2 to be accepted it would also need to include a Merkle proof identifying the block including `C` from Tx1. This proves the relative lock_height requirement has been met.
# Derived Contracts
## Derived Contracts
## Trustless Transactions
### Trustless Transactions
An aggregate (Schnorr) signature involving a single party is relatively simple
but does not demonstrate the full flexibility of the construction. We show
@ -99,21 +101,21 @@ transaction and specifically its kernel signature.
Alice wants to pay Bob in grins. She starts the transaction building process:
1. Alice selects her inputs and builds her change output. The sum of all
blinding factors (change output minus inputs) is `rs`.
2. Alice picks a random nonce ks and sends her partial transaction, `ks*G` and
`rs*G` to Bob.
3. Bob picks his own random nonce `kr` and the blinding factor for his output
`rr`. Using `rr`, Bob adds his output to the transaction.
4. Bob computes the message `M = fee | lock_height`, the Schnorr challenge
`e = SHA256(M | kr*G + ks*G | rr*G + rs*G)` and finally his side of the
signature `sr = kr + e * rr`.
5. Bob sends `sr`, `kr*G` and `rr*G` to Alice.
6. Alice computes `e` just like Bob did and can check that
`sr*G = kr*G + e*rr*G`.
7. Alice sends her side of the signature `ss = ks + e * rs` to Bob.
8. Bob validates `ss*G` just like Alice did for `sr*G` in step 5 and can
produce the final signature `s = (ss + sr, ks*G + kr*G)` as well as the final
transaction kernel including `s` and the public key `rr*G + rs*G`.
blinding factors (change output minus inputs) is `rs`.
1. Alice picks a random nonce ks and sends her partial transaction, `ks*G` and
`rs*G` to Bob.
1. Bob picks his own random nonce `kr` and the blinding factor for his output
`rr`. Using `rr`, Bob adds his output to the transaction.
1. Bob computes the message `M = fee | lock_height`, the Schnorr challenge
`e = SHA256(M | kr*G + ks*G | rr*G + rs*G)` and finally his side of the
signature `sr = kr + e * rr`.
1. Bob sends `sr`, `kr*G` and `rr*G` to Alice.
1. Alice computes `e` just like Bob did and can check that
`sr*G = kr*G + e*rr*G`.
1. Alice sends her side of the signature `ss = ks + e * rs` to Bob.
1. Bob validates `ss*G` just like Alice did for `sr*G` in step 5 and can
produce the final signature `s = (ss + sr, ks*G + kr*G)` as well as the final
transaction kernel including `s` and the public key `rr*G + rs*G`.
This protocol requires 3 data exchanges (Alice to Bob, Bob back to Alice,
and finally Alice to Bob) and is therefore said to be interactive. However
@ -126,7 +128,7 @@ can compute `e = SHA256(M | sum(ki*G) | sum(ri*G))` and their own signature
`si`. Finally, a finalizing party can then gather all the partial signatures
`si`, validate them and produce `s = (sum(si), sum(ki*G))`.
## Multiparty Outputs (multisig)
### Multiparty Outputs (multisig)
We describe here a way to build a transaction with an output that can only be
spent when multiple parties approve it. This construction is very similar to
@ -139,12 +141,12 @@ such that:
1. Bob picks a blinding factor `rb` and sends `rb*G` to Alice.
1. Alice picks a blinding factor `ra` and builds the commitment
`C = ra*G + rb*G + v*H`. She sends the commitment to Bob.
3. Bob creates a range proof for `v` using `C` and `rb` and sends it to Alice.
4. Alice generates her own range proof, aggregates it with Bob, finalizing
the multiparty output `Oab`.
5. The kernel is built following the same procedure as for Trustless
Transactions.
`C = ra*G + rb*G + v*H`. She sends the commitment to Bob.
1. Bob creates a range proof for `v` using `C` and `rb` and sends it to Alice.
1. Alice generates her own range proof, aggregates it with Bob, finalizing
the multiparty output `Oab`.
1. The kernel is built following the same procedure as for Trustless
Transactions.
We observe that for that new output `Oab`, neither party know the whole
blinding factor. To be able to build a transaction spending Oab, someone would
@ -152,18 +154,18 @@ need to know `ra + rb` to produce a kernel signature. To produce that spending
kernel, Alice and Bob need to collaborate. This, again, is done using a
protocol very close to Trustless Transactions.
## Multiparty Timelocks
### Multiparty Timelocks
This contract is a building block for multiple other contracts. Here, Alice
agrees to lock some funds to start a financial interaction with Bob and prove
to Bob she has funds. The setup is the following:
* Alice builds a a 2-of-2 multiparty transaction with an output she shares with
Bob, however she does not participate in building the kernel signature yet.
Bob, however she does not participate in building the kernel signature yet.
* Bob builds a refund transaction with Alice that sends the funds back to Alice
using a timelock (for example 1440 blocks ahead, about 24h).
using a timelock (for example 1440 blocks ahead, about 24h).
* Alice and Bob finish the 2-of-2 transaction by building the corresponding
kernel and broadcast it.
kernel and broadcast it.
Now Alice and Bob are free to build additional transactions distributing the
funds locked in the 2-of-2 output in any way they see fit. If Bob refuses to
@ -172,7 +174,7 @@ lock expires.
This contract can be trivially used for unidirectional payment channels.
## Conditional Output Timelocks
### Conditional Output Timelocks
Analogous to Bitcoin [CheckLockTimeVerify](https://en.bitcoin.it/wiki/Timelock#CheckLockTimeVerify).
@ -187,13 +189,15 @@ C<sub>3</sub> = C<sub>1</sub> + C<sub>2</sub>
Given _unconditional locktimes on txs_ we can leverage these to give us _conditional locktimes on outputs_ by "entangling" two outputs on two related txs together.
We can construct two txs (Tx<sub>1</sub>, Tx<sub>2</sub>) with two entangled outputs Out<sub>1</sub> and Out<sub>2</sub> such that -
* Out<sub>1</sub> (commitment C<sub>1</sub>) is from Tx<sub>1</sub> and built using Key<sub>1</sub>
* Out<sub>2</sub> (commitment C<sub>2</sub>) is from Tx<sub>2</sub> and built using Key<sub>2</sub>
* Tx<sub>2</sub> has an _unconditional_ lock_height on it
* Out<sub>1</sub> (commitment C<sub>1</sub>) is from Tx<sub>1</sub> and built using Key<sub>1</sub>
* Out<sub>2</sub> (commitment C<sub>2</sub>) is from Tx<sub>2</sub> and built using Key<sub>2</sub>
* Tx<sub>2</sub> has an _unconditional_ lock_height on it
If we do this (and we can manage the keys as necessary) -
* Out<sub>1</sub> + Out<sub>2</sub> can _only_ be spent as a pair using Key<sub>3</sub>
* They can _only_ be spent after lock_height from Tx<sub>2</sub>
* Out<sub>1</sub> + Out<sub>2</sub> can _only_ be spent as a pair using Key<sub>3</sub>
* They can _only_ be spent after lock_height from Tx<sub>2</sub>
Tx<sub>1</sub> (containing Out<sub>1</sub>) can be broadcast, accepted and confirmed on-chain immediately.
Tx<sub>2</sub> cannot be broadcast and accepted until lock_height has passed.
@ -204,7 +208,7 @@ If Bob on the other hand knows Key<sub>2</sub> then Out<sub>1</sub> can be spent
We have a _conditional_ timelock on Out<sub>1</sub> (confirmed, on-chain)
where it can be spent either with Key<sub>3</sub> (after lock_height), _or_ Key<sub>2</sub> immediately.
## (Relative) Conditional Output Timelocks
### (Relative) Conditional Output Timelocks
Analogous to Bitcoin [CheckSequenceVerify](https://en.bitcoin.it/wiki/Timelock#CheckSequenceVerify).
@ -213,7 +217,7 @@ By combining "Conditional Timelock on Output" with "(Relative) Timelocked Transa
Tx<sub>1</sub> (containing Out<sub>1</sub>) can be broadcast, accepted and confirmed on-chain immediately.
Tx<sub>2</sub> cannot be broadcast and accepted until the _relative_ lock_height has passed, relative to the referenced kernel from the earlier Tx<sub>1</sub>.
## Atomic Swap
### Atomic Swap
This setup can work on Bitcoin, Ethereum and likely other chains. It relies
on a time locked contract combined with a check for 2 public keys. On Bitcoin
@ -234,20 +238,20 @@ and Bob start as if they were building a normal trustless transaction as
specified in section 2.1.
1. Alice picks a random nonce `ks` and her blinding sum `rs` and sends `ks*G`
and `rs*G` to Bob.
2. Bob picks a random blinding factor `rr` and a random nonce `kr`. However
this time, instead of simply sending `sr = kr + e * rr` with his `rr*G` and
`kr*G`, Bob sends `sr' = kr + x + e * rr` as well as `x*G`.
3. Alice can validate that `sr'*G = kr*G + x*G + rr*G`. She can also check
that Bob has money locked with `x*G` on the other chain.
4. Alice sends back her `ss = ks + e * xs` as she normally would, now that she
can also compute `e = SHA256(M | ks*G + kr*G)`.
5. To complete the signature, Bob computes `sr = kr + e * rr` and the final
signature is `(sr + ss, kr*G + ks*G)`.
6. As soon as Bob broadcasts the final transaction to get his new grins, Alice
can compute `sr' - sr` to get `x`.
and `rs*G` to Bob.
1. Bob picks a random blinding factor `rr` and a random nonce `kr`. However
this time, instead of simply sending `sr = kr + e * rr` with his `rr*G` and
`kr*G`, Bob sends `sr' = kr + x + e * rr` as well as `x*G`.
1. Alice can validate that `sr'*G = kr*G + x*G + rr*G`. She can also check
that Bob has money locked with `x*G` on the other chain.
1. Alice sends back her `ss = ks + e * xs` as she normally would, now that she
can also compute `e = SHA256(M | ks*G + kr*G)`.
1. To complete the signature, Bob computes `sr = kr + e * rr` and the final
signature is `(sr + ss, kr*G + ks*G)`.
1. As soon as Bob broadcasts the final transaction to get his new grins, Alice
can compute `sr' - sr` to get `x`.
### Notes on the Bitcoin setup
#### Notes on the Bitcoin setup
Prior to completing the atomic swap, Bob needs to know Alice's public key. Bob
would then create an output on the Bitcoin blockchain with a 2-of-2 multisig
@ -261,6 +265,6 @@ it and check that her hash matches what's in the P2SH (step 2 in previous
section). Once she gets `x` (step 6), she can build the 2 signatures necessary
to spend the 2-of-2, having both private keys, and get her bitcoin.
## Hashed Timelocks (Lightning Network)
### Hashed Timelocks (Lightning Network)
TODO relative lock times

View file

@ -1,5 +1,6 @@
Dandelion in Grin: Privacy-Preserving Transaction Aggregation and Propagation
==================
# Dandelion in Grin: Privacy-Preserving Transaction Aggregation and Propagation
This document describes the implementation of Dandelion in Grin and its modification to handle transactions aggregation in the P2P protocol.
## Introduction
@ -16,7 +17,8 @@ We first define the original Dandelion propagation then the Grin adaptation of
Dandelion transaction propagation proceeds in two phases: first the “stem” phase, and then “fluff” phase. During the stem phase, each node relays the transaction to a *single* peer. After a random number of hops along the stem, the transaction enters the fluff phase, which behaves just like ordinary flooding/diffusion. Even when an attacker can identify the location of the fluff phase, it is much more difficult to identify the source of the stem.
Illustration:
<pre>
```
┌-> F ...
┌-> D --┤
| └-> G ...
@ -24,7 +26,7 @@ Illustration:
| ┌-> H ...
└-> E --┤
└-> I ...
</pre>
```
### Specifications
@ -42,9 +44,10 @@ The Dandelion protocol is based on three mechanisms:
Dandelion stem mode transactions are indicated by a new type of relay message type.
Stem transaction relay message type:
<pre>
```rust
Type::StemTransaction;
</pre>
```
After receiving a stem transaction, the node flips a biased coin to determine whether to propagate it in “stem mode”, or to switch to “fluff mode.” The bias is controlled by a parameter exposed to the configuration file, initially 90% chance of staying in stem mode (meaning the expected stem length would be 10 hops).
@ -55,9 +58,9 @@ Nodes that receives stem transactions are called stem relays. This relay is chos
The main implementation challenges are: (1) identifying a satisfactory tradeoff between Dandelions privacy guarantees and its latency/overhead, and (2) ensuring that privacy cannot be degraded through abuse of existing mechanisms. In particular, the implementation should prevent an attacker from identifying stem nodes without interfering too much with the various existing mechanisms for efficient and DoS-resistant propagation.
* The privacy afforded by Dandelion depends on 3 parameters: the stem probability, the number of outbound peers that can serve as dandelion relay, and the time between re-randomizations of the stem relay. These parameters define a tradeoff between privacy and broadcast latency/processing overhead. Lowering the stem probability harms privacy but helps reduce latency by shortening the mean stem length; based on theory, simulations, and experiments, we have chosen a default of 90%. Reducing the time between each nodes re-randomization of its stem relay reduces the chance of an adversary learning the stem relay for each node, at the expense of increased overhead.
* When receiving a Dandelion stem transaction, we avoid placing that transaction in <code>tracking_adapter</code>. This way, transactions can also travel back “up” the stem in the fluff phase.
* When receiving a Dandelion stem transaction, we avoid placing that transaction in `tracking_adapter`. This way, transactions can also travel back “up” the stem in the fluff phase.
* Like ordinary transactions, Dandelion stem transactions are only relayed after being successfully accepted to mempool. This ensures that nodes will never be punished for relaying Dandelion stem transactions.
* If a stem orphan transaction is received, it is added to the <code>orphan</code> pool, and also marked as stem-mode. If the transaction is later accepted to mempool, then it is relayed as a stem transaction or regular transaction (either stem mode or fluff mode, depending on a coin flip).
* If a stem orphan transaction is received, it is added to the `orphan` pool, and also marked as stem-mode. If the transaction is later accepted to mempool, then it is relayed as a stem transaction or regular transaction (either stem mode or fluff mode, depending on a coin flip).
* If a node receives a child transaction that depends on one or more currently-embargoed Dandelion transactions, then the transaction is also relayed in stem mode, and the embargo timer is set to the maximum of the embargo times of its parents. This helps ensure that parent transactions enter fluff mode before child transactions. Later on, this two transaction will be aggregated in one unique transaction removing the need for the timer.
* Transaction propagation latency should be minimally affected by opting-in to this privacy feature; in particular, a transaction should never be prevented from propagating at all because of Dandelion. The random timer guarantees that the embargo mechanism is temporary, and every transaction is relayed according to the ordinary diffusion mechanism after some maximum (random) delay on the order of 30-60 seconds.
@ -77,7 +80,7 @@ A simulation of this scenario is available [here](simulation.md).
## References
- [1] (Sigmetrics 2017) Dandelion: Redesigning the Bitcoin Network for Anonymity https://arxiv.org/abs/1701.04439
- [2] Dandelion BIP https://github.com/dandelion-org/bips/blob/master/bip-dandelion.mediawiki
- [3] (Sigmetrics 2018) Dandelion++: Lightweight Cryptocurrency Networking with Formal Anonymity Guarantees https://arxiv.org/abs/1805.11060
- [4] Dandelion Grin Pull Request #1067: https://github.com/mimblewimble/grin/pull/1067
* [1] (Sigmetrics 2017) [Dandelion: Redesigning the Bitcoin Network for Anonymity](https://arxiv.org/abs/1701.04439)
* [2] [Dandelion BIP](https://github.com/dandelion-org/bips/blob/master/bip-dandelion.mediawiki)
* [3] (Sigmetrics 2018) [Dandelion++: Lightweight Cryptocurrency Networking with Formal Anonymity Guarantees](https://arxiv.org/abs/1805.11060)
* [4] [Dandelion Grin Pull Request #1067](https://github.com/mimblewimble/grin/pull/1067)

View file

@ -1,5 +1,5 @@
Dandelion Simulation
==================
# Dandelion Simulation
This document describes a network of node using the Dandelion protocol with transaction aggregation.
In this scenario, we simulate a successful aggregation.
@ -26,7 +26,7 @@ A waits until he runs out of patience.
A runs out of patience, flips a coin and broadcasts the stem transaction to its Dandelion relay G.
G receives the stem transaction, add it to its stempool and starts the embargo timer for this transaction.
![t = 30](images/t30.png)
## T = 40

View file

@ -9,14 +9,14 @@ download full blocks.
In short, a fast-sync in Grin does the following:
1. Download all block headers, by chunks, on the most worked chain, as
advertized by other nodes.
2. Find a header sufficiently back from the chain head. This is called the node
horizon as it's the furthest a node can reorganize its chain on a new fork if
it were to occur without triggering another new full sync.
3. Download the full state as it was at the horizon, including the unspent
output, range proof and kernel data, as well as all corresponding MMRs. This is
just one large zip file.
4. Validate the full state.
5. Download full blocks since the horizon to get to the chain head.
advertized by other nodes.
1. Find a header sufficiently back from the chain head. This is called the node
horizon as it's the furthest a node can reorganize its chain on a new fork if
it were to occur without triggering another new full sync.
1. Download the full state as it was at the horizon, including the unspent
output, range proof and kernel data, as well as all corresponding MMRs. This is
just one large zip file.
1. Validate the full state.
1. Download full blocks since the horizon to get to the chain head.
In the rest of this section, we will elaborate on each of those steps.

View file

@ -1,5 +1,4 @@
Transaction Pool
==================
# Transaction Pool
This document describes some of the basic functionality and requirements of grin's transaction pool.
@ -57,5 +56,3 @@ Next, the state of the transaction and where it would be located in the graph is
## Adversarial Conditions
Under adversarial situations, the primary concerns to the transaction pool are denial-of-service attacks. The greatest concern should be maintaining the ability of the node to provide services to miners, by supplying ready made transactions to the mining service for inclusion in blocks. Resource consumption should be constrained as well. As we've seen on other chains, miners often have little incentive to include transactions if doing so impacts their ability to collect their primary reward.
###

View file

@ -1,5 +1,4 @@
Introduction to MimbleWimble and Grin
=====================================
# Introduction to MimbleWimble and Grin
*Read this in other languages: [English](intro.md), [简体中文](intro.zh-cn.md).*
@ -15,7 +14,7 @@ cryptocurrency deployment.
The main goal and characteristics of the Grin project are:
* Privacy by default. This enables complete fungibility without precluding
the ability to selectively disclose information as needed.
the ability to selectively disclose information as needed.
* Scales mostly with the number of users and minimally with the number of
transactions (<100 byte `kernel), resulting in a large space saving compared
to other blockchains.
@ -25,7 +24,7 @@ The main goal and characteristics of the Grin project are:
* Community driven, using an asic-resistant mining algorithm (Cuckoo Cycle)
encouraging mining decentralization.
# Tongue Tying for Everyone
## Tongue Tying for Everyone
This document is targeted at readers with a good
understanding of blockchains and basic cryptography. With that in mind, we attempt
@ -39,7 +38,7 @@ description of some relevant properties of Elliptic Curve Cryptography (ECC) to
foundation on which Grin is based and then describe all the key elements of a
MimbleWimble blockchain's transactions and blocks.
## Tiny Bits of Elliptic Curves
### Tiny Bits of Elliptic Curves
We start with a brief primer on Elliptic Curve Cryptography, reviewing just the
properties necessary to understand how MimbleWimble works and without
@ -70,7 +69,7 @@ two private keys (`k*H + j*H`). In the Bitcoin blockchain, Hierarchical
Deterministic wallets heavily rely on this principle. MimbleWimble and the Grin
implementation do as well.
## Transacting with MimbleWimble
### Transacting with MimbleWimble
The structure of transactions demonstrates a crucial tenet of MimbleWimble:
strong privacy and confidentiality guarantees.
@ -78,16 +77,16 @@ strong privacy and confidentiality guarantees.
The validation of MimbleWimble transactions relies on two basic properties:
* **Verification of zero sums.** The sum of outputs minus inputs always equals zero,
proving that the transaction did not create new funds, _without revealing the actual amounts_.
proving that the transaction did not create new funds, _without revealing the actual amounts_.
* **Possession of private keys.** Like with most other cryptocurrencies, ownership of
transaction outputs is guaranteed by the possession of ECC private keys. However,
the proof that an entity owns those private keys is not achieved by directly signing
the transaction.
transaction outputs is guaranteed by the possession of ECC private keys. However,
the proof that an entity owns those private keys is not achieved by directly signing
the transaction.
The next sections on balance, ownership, change and proofs details how those two
fundamental properties are achieved.
### Balance
#### Balance
Building upon the properties of ECC we described above, one can obscure the values
in a transaction.
@ -148,7 +147,7 @@ As a final note, this idea is actually derived from Greg Maxwell's
which is itself derived from an Adam Back proposal for homomorphic values applied
to Bitcoin.
### Ownership
#### Ownership
In the previous section we introduced a private key as a blinding factor to obscure the
transaction's values. The second insight of MimbleWimble is that this private
@ -187,7 +186,7 @@ steal the money back from Carol!
To solve this, Carol uses a private key of her choosing.
She picks 113 say, and what ends up on the blockchain is:
Y - Xi = (113*G + 3*H) - (28*G + 3*H) = 85*G + 0*H
Y - Xi = (113*G + 3*H) - (28*G + 3*H) = 85*G + 0*H
Now the transaction no longer sums to zero and we have an _excess value_ on _G_
(85), which is the result of the summation of all blinding factors. But because `85*G` is
@ -207,15 +206,15 @@ which then validates that:
This signature, attached to every transaction, together with some additional data (like mining
fees), is called a _transaction kernel_ and is checked by all validators.
### Some Finer Points
#### Some Finer Points
This section elaborates on the building of transactions by discussing how change is
introduced and the requirement for range proofs so all values are proven to be
non-negative. Neither of these are absolutely required to understand MimbleWimble and
Grin, so if you're in a hurry, feel free to jump straight to
[Putting It All Together](#transaction-conclusion).
[Putting It All Together](#putting-it-all-together).
#### Change
##### Change
Let's say you only want to send 2 coins to Carol from the 3 you received from
Alice. To do this you would send the remaining 1 coin back to yourself as change.
@ -230,8 +229,7 @@ And the signature is again built with the excess value, 97 in this example.
(12*G + 1*H) + (113*G + 2*H) - (28*G + 3*H) = 97*G + 0*H
#### Range Proofs
##### Range Proofs
In all the above calculations, we rely on the transaction values to always be positive. The
introduction of negative amounts would be extremely problematic as one could
@ -251,8 +249,7 @@ zero and does not overflow.
It's also important to note that in order to create a valid range proof from the example above, both of the values 113 and 28 used in creating and signing for the excess value must be known. The reason for this, as well as a more detailed description of range proofs are further detailed in the [range proof paper](https://eprint.iacr.org/2017/1066.pdf).
<a name="transaction-conclusion"></a>
### Putting It All Together
#### Putting It All Together
A MimbleWimble transaction includes the following:
@ -263,9 +260,9 @@ A MimbleWimble transaction includes the following:
* A range proof that shows that v is non-negative.
* An explicit transaction fee, in clear.
* A signature, computed by taking the excess blinding value (the sum of all
outputs plus the fee, minus the inputs) and using it as a private key.
outputs plus the fee, minus the inputs) and using it as a private key.
## Blocks and Chain State
### Blocks and Chain State
We've explained above how MimbleWimble transactions can provide
strong anonymity guarantees while maintaining the properties required for a valid
@ -279,16 +276,17 @@ concept: _cut-through_. With this addition, a MimbleWimble chain gains:
eliminated over time, without compromising security.
* Further anonymity by mixing and removing transaction data.
* And the ability for new nodes to sync up with the rest of the network very
efficiently.
efficiently.
### Transaction Aggregation
#### Transaction Aggregation
Recall that a transaction consists of the following -
* a set of inputs that reference and spent a set of previous outputs
* a set of new outputs (Pedersen commitments)
* a transaction kernel, consisting of
* kernel excess (Pedersen commitment to zero)
* transaction signature (using kernel excess as public key)
* kernel excess (Pedersen commitment to zero)
* transaction signature (using kernel excess as public key)
A tx is signed and the signature included in a _transaction kernel_. The signature is generated using the _kernel excess_ as a public key proving that the transaction sums to 0.
@ -298,47 +296,47 @@ The public key in this example being `28*G`.
We can say the following is true for any valid transaction (ignoring fees for simplicity) -
sum(outputs) - sum(inputs) = kernel_excess
sum(outputs) - sum(inputs) = kernel_excess
The same holds true for blocks themselves once we realize a block is simply a set of aggregated inputs, outputs and transaction kernels. We can sum the tx outputs, subtract the sum of the tx inputs and compare the resulting Pedersen commitment to the sum of the kernel excesses -
sum(outputs) - sum(inputs) = sum(kernel_excess)
sum(outputs) - sum(inputs) = sum(kernel_excess)
Simplifying slightly, (again ignoring transaction fees) we can say that MimbleWimble blocks can be treated exactly as MimbleWimble transactions.
#### Kernel Offsets
##### Kernel Offsets
There is a subtle problem with MimbleWimble blocks and transactions as described above. It is possible (and in some cases trivial) to reconstruct the constituent transactions in a block. This is clearly bad for privacy. This is the "subset" problem - given a set of inputs, outputs and transaction kernels a subset of these will recombine to reconstruct a valid transaction.
For example, given the following two transactions -
(in1, in2) -> (out1), (kern1)
(in3) -> (out2), (kern2)
(in1, in2) -> (out1), (kern1)
(in3) -> (out2), (kern2)
We can aggregate them into the following block (or aggregate transaction) -
(in1, in2, in3) -> (out1, out2), (kern1, kern2)
(in1, in2, in3) -> (out1, out2), (kern1, kern2)
It is trivially easy to try all possible permutations to recover one of the transactions (where it sums successfully to zero) -
(in1, in2) -> (out1), (kern1)
(in1, in2) -> (out1), (kern1)
We also know that everything remaining can be used to reconstruct the other valid transaction -
(in3) -> (out2), (kern2)
(in3) -> (out2), (kern2)
To mitigate this we include a _kernel offset_ with every transaction kernel. This is a blinding factor (private key) that needs to be added back to the kernel excess to verify the commitments sum to zero -
sum(outputs) - sum(inputs) = kernel_excess + kernel_offset
sum(outputs) - sum(inputs) = kernel_excess + kernel_offset
When we aggregate transactions in a block we store a _single_ aggregate offset in the block header. And now we have a single offset that cannot be decomposed into the individual transaction kernel offsets and the transactions can no longer be reconstructed -
sum(outputs) - sum(inputs) = sum(kernel_excess) + kernel_offset
sum(outputs) - sum(inputs) = sum(kernel_excess) + kernel_offset
We "split" the key `k` into `k1+k2` during transaction construction. For a transaction kernel `(k1+k2)*G` we publish `k1*G` (the excess) and `k2` (the offset) and sign the transaction with `k1*G` as before.
During block construction we can simply sum the `k2` offsets to generate a single aggregate `k2` offset to cover all transactions in the block. The `k2` offset for any individual transaction is unrecoverable.
### Cut-through
#### Cut-through
Blocks let miners assemble multiple transactions into a single set that's added
to the chain. In the following block representations, containing 3 transactions,
@ -358,9 +356,9 @@ in a previous block is marked with a lower-case x.
We notice the two following properties:
* Within this block, some outputs are directly spent by included inputs (I3
spends O2 and I4 spends O3).
spends O2 and I4 spends O3).
* The structure of each transaction does not actually matter. As all transactions
individually sum to zero, the sum of all transaction inputs and outputs must be zero.
individually sum to zero, the sum of all transaction inputs and outputs must be zero.
Similarly to a transaction, all that needs to be checked in a block is that ownership
has been proven (which comes from _transaction kernels_) and that the whole block did
@ -392,14 +390,14 @@ guarantees:
* Intermediate (cut-through) transactions will be represented only by their transaction kernels.
* All outputs look the same: just very large numbers that are impossible to
differentiate from one another. If one wanted to exclude some outputs, they'd have
to exclude all.
differentiate from one another. If one wanted to exclude some outputs, they'd have
to exclude all.
* All transaction structure has been removed, making it impossible to tell which output
was matched with each input.
was matched with each input.
And yet, it all still validates!
### Cut-through All The Way
#### Cut-through All The Way
Going back to the previous example block, outputs x1 and x2, spent by I1 and
I2, must have appeared previously in the blockchain. So after the addition of
@ -418,17 +416,17 @@ height (its distance from the genesis block). And both the unspent outputs and t
transaction kernels are extremely compact. This has 2 important consequences:
* The state a given node in a MimbleWimble blockchain needs to maintain is very
small (on the order of a few gigabytes for a bitcoin-sized blockchain, and
potentially optimizable to a few hundreds of megabytes).
small (on the order of a few gigabytes for a bitcoin-sized blockchain, and
potentially optimizable to a few hundreds of megabytes).
* When a new node joins a network building up a MimbleWimble chain, the amount of
information that needs to be transferred is also very small.
information that needs to be transferred is also very small.
In addition, the complete set of unspent outputs cannot be tampered with, even
only by adding or removing an output. Doing so would cause the summation of all
blinding factors in the transaction kernels to differ from the summation of blinding
factors in the outputs.
## Conclusion
### Conclusion
In this document we covered the basic principles that underlie a MimbleWimble
blockchain. By using the addition properties of Elliptic Curve Cryptography, we're

View file

@ -81,7 +81,6 @@ Design requirements:
1. Support for serialization and efficient merging of pruned trees from partial archival nodes.
## Proposed Merkle Structure
**The following design is proposed for all trees: a sum-MMR where every node
@ -147,7 +146,6 @@ In the output set each node also commits to a sum of its unspent children, so
a validator knows if it is missing data on unspent coins by checking whether or
not this sum on a pruned node is zero.
## Algorithms
(To appear alongside an implementation.)

View file

@ -145,5 +145,6 @@ Height
0 1 7 10 11 15 18
```
[1] Peter Todd, https://github.com/opentimestamps/opentimestamps-server/blob/master/doc/merkle-mountain-range.md
[2] https://en.wikipedia.org/wiki/Merkle_tree
[1] Peter Todd, [merkle-mountain-range](https://github.com/opentimestamps/opentimestamps-server/blob/master/doc/merkle-mountain-range.md)
[2] [Wikipedia, Merkle Tree](https://en.wikipedia.org/wiki/Merkle_tree)

View file

@ -1,5 +1,4 @@
Grin's Proof-of-Work
====================
# Grin's Proof-of-Work
This document is meant to outline, at a level suitable for someone without prior knowledge,
the algorithms and processes currently involved in Grin's Proof-of-Work system. We'll start
@ -10,7 +9,7 @@ the other systems that combine with Cuckoo Cycle to form the entirety of mining
Please note that Grin is currently under active development, and any and all of this is subject to
(and will) change before a general release.
# Graphs and Cuckoo Cycle
## Graphs and Cuckoo Cycle
Grin's basic Proof-of-Work algorithm is called Cuckoo Cycle, which is specifically designed
to be resistant to Bitcoin style hardware arms-races. It is primarily a memory bound algorithm,
@ -29,7 +28,7 @@ in which John Tromp talks at length about Cuckoo Cycle; recommended listening fo
more background on Cuckoo Cycle, including more technical detail, the history of the algorithm's development
and some of the motivations behind it.
## Cycles in a Graph
### Cycles in a Graph
Cuckoo Cycle is an algorithm meant to detect cycles in a bipartite graph of N nodes
and M edges. In plainer terms, a bipartite graph is one in which edges (i.e. lines connecting nodes)
@ -87,9 +86,9 @@ The answer is left as an exercise to the reader, but the overall takeaways are:
* Detecting cycles in a graph becomes more difficult exercise as the size of a graph grows.
* The probability of a cycle of a given length in a graph increases as M/N becomes larger,
i.e. you add more edges relative to the number of nodes in a graph.
i.e. you add more edges relative to the number of nodes in a graph.
## Cuckoo Cycle
### Cuckoo Cycle
The Cuckoo Cycle algorithm is a specialized algorithm designed to solve exactly this problem, and it does
so by inserting values into a structure called a 'Cuckoo Hashtable' according to a hash which maps nodes
@ -101,24 +100,23 @@ However, there are a few details following from the above that we need to keep i
technical aspects of Grin's proof-of-work.
* The 'random' edges in the graph demonstrated above are not actually random but are generated by
putting edge indices (0..N) through a seeded hash function, SIPHASH. Each edge index is put through the
SIPHASH function twice to create two edge endpoints, with the first input value being 2 * edge_index,
and the second 2 * edge_index+1. The seed for this function is based on a hash of a block header,
outlined further below.
putting edge indices (0..N) through a seeded hash function, SIPHASH. Each edge index is put through the
SIPHASH function twice to create two edge endpoints, with the first input value being 2 * edge_index,
and the second 2 * edge_index+1. The seed for this function is based on a hash of a block header,
outlined further below.
* The 'Proof' created by this algorithm is a set of nonces that generate a cycle of length 42,
which can be trivially validated by other peers.
which can be trivially validated by other peers.
* Two main parameters, as explained above, are passed into the Cuckoo Cycle algorithm that affect the probability of a solution, and the
time it takes to search the graph for a solution:
* The M/N ratio outlined above, which controls the number of edges relative to the size of the graph.
time it takes to search the graph for a solution:
* The M/N ratio outlined above, which controls the number of edges relative to the size of the graph.
Cuckoo Cycle fixes M at N/2, which limits the number of cycles to a few at most.
* The size of the graph itself
* The size of the graph itself
How these parameters interact in practice is looked at in more [detail below](#mining-loop-difficulty-control-and-timing).
Now, (hopefully) armed with a basic understanding of what the Cuckoo Cycle algorithm is intended to do, as well as the parameters that affect how difficult it is to find a solution, we move on to the other portions of Grin's POW system.
# Mining in Grin
## Mining in Grin
The Cuckoo Cycle outlined above forms the basis of Grin's mining process, however Grin uses Cuckoo Cycle in tandem with several other systems to create a Proof-of-Work.
@ -155,35 +153,32 @@ All of these systems are put together in the mining loop, which attempts to crea
valid Proofs-of-Work to create the latest block in the chain. The following is an outline of what the main mining loop does during a single iteration:
* Get the latest chain state and build a block on top of it, which includes
* A Block Header with new values particular to this mining attempt, which are:
* The latest target difficulty as selected by the [evolving network difficulty](#evolving-network-difficulty) algorithm
* A set of transactions available for validation selected from the transaction pool
* A coinbase transaction (which we're hoping to give to ourselves)
* The current timestamp
* A randomly generated nonce to add further randomness to the header's hash
* The merkle root of the UTXO set and fees (not yet implemented)
* Then, a sub-loop runs for a set amount of time, currently configured at 2 seconds, where the following happens:
* The new block header is hashed to create a hash value
* The cuckoo graph generator is initialized, which accepts as parameters:
* The hash of the potential block header, which is to be used as the key to a SIPHASH function
that will generate pairs of locations for each element in a set of nonces 0..N in the graph.
* The size of the graph (a consensus value).
* An easiness value, (a consensus value) representing the M/N ratio described above denoting the probability
of a solution appearing in the graph
* The Cuckoo Cycle detection algorithm tries to find a solution (i.e. a cycle of length 42) within the generated
graph.
* If a cycle is found, a Blake2b hash of the proof is created and is compared to the current target
difficulty, as outlined in [Additional Difficulty Control](#additional-difficulty-control) above.
* If the Blake2b Hash difficulty is greater than or equal to the target difficulty, the block is sent to the
transaction pool, propagated amongst peers for validation, and work begins on the next block.
* If the Blake2b Hash difficulty is less than the target difficulty, the proof is thrown out and the timed loop continues.
* If no solution is found, increment the nonce in the header by 1, and update the header's timestamp so the next iteration
hashes a different value for seeding the next loop's graph generation step.
* If the loop times out with no solution found, start over again from the top, collecting new transactions and creating
a new block altogether.
* A Block Header with new values particular to this mining attempt, which are:
* The latest target difficulty as selected by the [evolving network difficulty](#evolving-network-difficulty) algorithm
* A set of transactions available for validation selected from the transaction pool
* A coinbase transaction (which we're hoping to give to ourselves)
* The current timestamp
* A randomly generated nonce to add further randomness to the header's hash
* The merkle root of the UTXO set and fees (not yet implemented)
* Then, a sub-loop runs for a set amount of time, currently configured at 2 seconds, where the following happens:
* The new block header is hashed to create a hash value
* The cuckoo graph generator is initialized, which accepts as parameters:
* The hash of the potential block header, which is to be used as the key to a SIPHASH function
that will generate pairs of locations for each element in a set of nonces 0..N in the graph.
* The size of the graph (a consensus value).
* An easiness value, (a consensus value) representing the M/N ratio described above denoting the probability
of a solution appearing in the graph
* The Cuckoo Cycle detection algorithm tries to find a solution (i.e. a cycle of length 42) within the generated
graph.
* If a cycle is found, a Blake2b hash of the proof is created and is compared to the current target
difficulty, as outlined in [Additional Difficulty Control](#additional-difficulty-control) above.
* If the Blake2b Hash difficulty is greater than or equal to the target difficulty, the block is sent to the
transaction pool, propagated amongst peers for validation, and work begins on the next block.
* If the Blake2b Hash difficulty is less than the target difficulty, the proof is thrown out and the timed loop continues.
* If no solution is found, increment the nonce in the header by 1, and update the header's timestamp so the next iteration
hashes a different value for seeding the next loop's graph generation step.
* If the loop times out with no solution found, start over again from the top, collecting new transactions and creating
a new block altogether.
### Mining Loop Difficulty Control and Timing

View file

@ -35,14 +35,14 @@ the set of UTXO commitments is strictly required for a node to function.
There may be several contexts in which data can be pruned:
* A fully validating node may get rid of some data it has already validated to
free space.
free space.
* A partially validating node (similar to SPV) may not be interested in either
receiving or keeping all the data.
receiving or keeping all the data.
* When a new node joins the network, it may temporarily behave as a partially
validating node to make it available for use faster, even if it ultimately becomes
a fully validating node.
validating node to make it available for use faster, even if it ultimately becomes
a fully validating node.
# Validation of Fully Pruned State
## Validation of Fully Pruned State
Pruning needs to remove as much data as possible while keeping all the
guarantees of a full MimbleWimble-style validation. This is necessary to keep
@ -53,24 +53,24 @@ The full validation of the chain state requires that:
* All kernel signatures verify against their public keys.
* The sum of all UTXO commitments, minus the supply is a valid public key (can
be used to sign the empty string).
be used to sign the empty string).
* The sum of all kernel pubkeys equals the sum of all UTXO commitments, minus
the supply.
the supply.
* The root hashes of the UTXO PMMR, the range proofs PMMR and the kernels MMR
match a block header with a valid Proof of Work chain.
match a block header with a valid Proof of Work chain.
* All range proofs are valid.
In addition, while not necessary to validate the full chain state, to be able
to accept and validate new blocks additional data is required:
* The output features and switch commitments, making the full output data
necessary for all UTXOs.
necessary for all UTXOs.
At minimum, this requires the following data:
* The block headers chain.
* All kernels, in order of inclusion in the chain. This also allows the
reconstruction of the kernel MMR.
reconstruction of the kernel MMR.
* All unspent outputs.
* The UTXO MMR and the range proof MMR (to learn the hashes of pruned data).

View file

@ -1,4 +1,4 @@
# Grin - Instruction of Release
# Grin - Instruction of Release
**Note**: *[totally draft doc! to be reviewed and discussed]*
@ -7,17 +7,21 @@
In Grin, we're using [Semantic Versioning 2.0.0](https://semver.org). For a short description of the rule:
A version number include MAJOR.MINOR.PATCH, and increment the:
1. MAJOR version when you make incompatible API changes,
2. MINOR version when you add functionality in a backwards-compatible manner, and
3. PATCH version when you make backwards-compatible bug fixes.
And **additional labels for pre-release** and **build metadata** are available as extensions to the MAJOR.MINOR.PATCH format.
The examples of the release version of Grin:
- 0.3.0
- 0.3.1
- 1.5.90
The examples of **label of pre-release**:
- 1.0.0-alpha.1
- 1.0.0-beta.2
- 1.0.0-test.5
@ -25,9 +29,11 @@ The examples of **label of pre-release**:
In Grin, **build metadata** is used as the build number which comes from the Travis-CI job ID of building jobs, it's an unique ID for each building. **Note**: for the moment, this metadata is only used in the name of the released binary, and it's auto generated, no need to set it manually.
Here is an example of the build metadata of Grin release version:
- 0.3.1-430839304
And as the end of this section, here's an example of the whole encoded version string:
- 0.3.1-pre.1-430839316
## Release Files (Binaries)
@ -35,12 +41,12 @@ And as the end of this section, here's an example of the whole encoded version s
So far, Grin support both Mac and Linux, and 64bits only. There're 2 binaries in one version release, plus md5 checksum for each binary.
For example:
- grin-0.3.1-pre.1-430839316-oxs.tgz
- grin-0.3.1-pre.1-430839316-oxs.tgz-md5sum.txt
- grin-0.3.1-pre.1-430839318-linux-amd64.tgz
- grin-0.3.1-pre.1-430839318-linux-amd64.tgz-md5sum.txt
## Change Log of Release
Currently, Grin release is using automatic change log generating, thanks to [github-changelog-generator](https://github.com/github-changelog-generator/github-changelog-generator). These change logs are fully automated generated, and normally there's no human editing on these change logs, but in case of any exception display on release page, we could do a little manual fixing on that.
@ -71,11 +77,12 @@ As opposite, all closed issues with the following labels will be automatically e
- **invalid**
- **wontfix**
For more details, please run `github_changelog_generator --help`, or check its github repo: https://github.com/github-changelog-generator/github-changelog-generator
For more details, please run `github_changelog_generator --help`, or check its github repo: [github-changelog-generator](https://github.com/github-changelog-generator/github-changelog-generator)
### Rules of Pull-Request
And regarding to merged **pull-requests**, it will be put into group "all merged pull-requests". And it's strongly recommended that each pull-request give a commit message with prefix:
- **feat**: A new feature
- **fix**: A bug fix
- **docs**: Documentation only changes
@ -94,25 +101,29 @@ There's no need to fully follow Angular.js commit message conventions. We just n
Each time when Grin release a new version, there's definitely a tag there with same version number. But it's not mandatory to have a **branch** with this version release.
We define the following rules for the **release branch**:
1. Only **MAJOR.MINOR** version could have a release branch, but also NOT mandatory.
2. Only when a fix is needed for a **MAJOR.MINOR** version, we create a **release branch** on the name of **MAJOR.MINOR** from the tag of **MAJOR.MINOR.0**, and only one branch for all the fixes on this **MAJOR.MINOR** version.
3. New version based on this **release branch** must have same **MAJOR.MINOR** version number, only **.PATCH** can be changed.
1. Only when a fix is needed for a **MAJOR.MINOR** version, we create a **release branch** on the name of **MAJOR.MINOR** from the tag of **MAJOR.MINOR.0**, and only one branch for all the fixes on this **MAJOR.MINOR** version.
1. New version based on this **release branch** must have same **MAJOR.MINOR** version number, only **.PATCH** can be changed.
## Release Instruction
### 1. TAG
To trigger a version release, the ONLY thing which need to do manually is to make a tag. As the **owner** of a github repo, he/she just need to run 2 commands locally:
```
```bash
git tag 0.3.1-pre1 -m "0.3.1 pre release 1"
git push origin 0.3.1-pre1
```
Done.
Remember to replace `0.3.1-pre1` as the real version, and warmly remind the [[Version Number Rule]]. For official release, just use `0.3.1` or something like that.
If you're NOT the owner of the github repo, but at least you have to be a committer which has the right to do a release, the following steps are needed to trigger a version release:
1. Go to release page of the repo, click **Draft a new release**, remember to check the branch is what you're working on! set the **Tag version** to the release number (for example: `0.3.1-pre1`), and set anything in **Release title** and **description**, then click **Publish release**. Don't worry the title and description parts because we need delete it in next step.
2. Because github **release** will be auto-created by our `auto-release` building script, we MUST delete the **release** which we just created in previous step! (Unfortunately, there's no way to only create **tag** by web.)
1. Go to release page of the repo, click **Draft a new release**, remember to check the branch is what you're working on! set the **Tag version** to the release number (for example: `0.3.1-pre1`), and set anything in **Release title** and **description**, then click **Publish release**. Don't worry the title and description parts because we need delete it in next step.
1. Because github **release** will be auto-created by our `auto-release` building script, we MUST delete the **release** which we just created in previous step! (Unfortunately, there's no way to only create **tag** by web.)
Even normally Travis-CI need tens of minutes to complete building, I suggest you complete step 2 quickly, otherwise the `auto-release` script will fail on error "release already exist".
@ -126,9 +137,6 @@ So, the point is: the release building job is that one tagged with `TEST_DIR=non
Note: `auto-release` script will only be executed on `deploy` stage, and according to Travis-CI, it will be skipped for any **pull-request** trigger, and since we set `tag: true` it will be only executed when triggered by a tag.
### 3. Check the Release Page
The last step is to check the Github release page, after Travis-CI complete the whole building, normally it need half an hour or one hour.

View file

@ -7,10 +7,10 @@
The full state of a Grin chain consists of all the following data:
1. The full unspent output (UTXO) set.
2. The range proof for each output.
3. All the transaction kernels.
4. A MMR for each of the above (with the exception that the output MMR includes
hashes for *all* outputs, not only the unspent ones).
1. The range proof for each output.
1. All the transaction kernels.
1. A MMR for each of the above (with the exception that the output MMR includes
hashes for *all* outputs, not only the unspent ones).
In addition, all headers in the chain are required to anchor the above state
with a valid proof of work (the state corresponds to the most worked chain).
@ -23,15 +23,15 @@ a node to function anymore.
With a full Grin state, we can validate the following:
1. The kernel signature is valid against its commitment (public key). This
proves the kernel is valid.
2. The sum of all kernel commitments equals the sum of all UTXO commitments
minus the total supply. This proves that kernels and output commitments are all
valid and no coins have unexpectedly been created.
3. All UTXOs, range proofs and kernels hashes are present in their respective
MMR and those MMRs hash to a valid root.
4. A known block header with the most work at a given point in time includes
the roots of the 3 MMRs. This validates the MMRs and proves that the whole
state has been produced by the most worked chain.
proves the kernel is valid.
1. The sum of all kernel commitments equals the sum of all UTXO commitments
minus the total supply. This proves that kernels and output commitments are all
valid and no coins have unexpectedly been created.
1. All UTXOs, range proofs and kernels hashes are present in their respective
MMR and those MMRs hash to a valid root.
1. A known block header with the most work at a given point in time includes
the roots of the 3 MMRs. This validates the MMRs and proves that the whole
state has been produced by the most worked chain.
### MMRs and Pruning
@ -39,10 +39,10 @@ The data used to produce the hashes for leaf nodes in each MMR (in addition to
their position is the following:
* The output MMR hashes the feature field and the commitments of all outputs
since genesis.
since genesis.
* The range proof MMR hashes the whole range proof data.
* The kernel MMR hashes all fields of the kernel: feature, fee, lock height,
excess commitment and excess signature.
excess commitment and excess signature.
Note that all outputs, range proofs and kernels are added in their respective
MMRs in the order they occur in each block (recall that block data is required

View file

@ -6,16 +6,16 @@ This document describes the current Stratum RPC protocol implemented in Grin.
1. [Messages](#messages)
1. [getjobtemplate](#getjobtemplate)
2. [job](#job)
3. [keepalive](#keepalive)
4. [login](#login)
5. [status](#status)
6. [submit](#submit)
1. [Error Messages](#errormessages)
1. [Miner Behavior](#minerbehavior)
1. [Reference Implementation](#referenceimplementation)
1. [job](#job)
1. [keepalive](#keepalive)
1. [login](#login)
1. [status](#status)
1. [submit](#submit)
1. [Error Messages](#error-messages)
1. [Miner Behavior](#miner-behavior)
1. [Reference Implementation](#reference-implementation)
## Messages <a name="messages"></a>
## Messages
In this section, we detail each message and the potential response.
@ -65,7 +65,7 @@ Example:
}
```
### ```getjobtemplate``` <a name="getjobtemplate"></a>
### ```getjobtemplate```
A message initiated by the miner.
Miner can request a job with this message.
@ -141,7 +141,7 @@ Example:
}
```
### ```job``` <a name="job"></a>
### ```job```
A message initiated by the Stratum server.
Stratum server will send job automatically to connected miners.
@ -178,7 +178,7 @@ Example:
No response is required for this message.
### ```keepalive``` <a name="keepalive"></a>
### ```keepalive```
A message initiated by the miner in order to keep the connection alive.
@ -228,7 +228,7 @@ Example:
```
### ```login``` <a name="login"></a>
### ```login```
***
@ -293,7 +293,7 @@ Example:
Not yet implemented. Should return error -32500 "Login first".
### ```status``` <a name="status"></a>
### ```status```
A message initiated by the miner.
This message allows a miner to get the status of its current worker and the network.
@ -351,7 +351,7 @@ Example:
}
```
### ```submit``` <a name="submit"></a>
### ```submit```
A message initiated by the miner.
When a miner find a share, it will submit it to the node.
@ -526,7 +526,7 @@ Example:
}
```
## Error Messages <a name="errormessages"></a>
## Error Messages
Grin Stratum protocol implementation contains the following error message:
@ -540,7 +540,7 @@ Grin Stratum protocol implementation contains the following error message:
| -32600 | Invalid Request |
| -32601 | Method not found |
## Miner behavior <a name="minerbehavior"></a>
## Miner behavior
Miners SHOULD, MAY or MUST respect the following rules:
@ -552,6 +552,6 @@ Miners SHOULD, MAY or MUST respect the following rules:
- Miners MAY send a login request (to identify which miner finds shares / solutions in the logs), the login request MUST have all 3 params.
- Miners MUST return the supplied job_id with submit messages.
## Reference Implementation <a name="referenceimplementation"></a>
## Reference Implementation
The current reference implementation is available at [mimblewimble/grin-miner](https://github.com/mimblewimble/grin-miner/blob/master/src/bin/client.rs).

View file

@ -1,13 +1,15 @@
# Documentation structure
## Explaining grin
- [intro](intro.md) - Technical introduction to grin
- [grin4bitcoiners](grin4bitcoiners.md) - Explaining grin from a bitcoiner's perspective
## Understand the grin implementation
- [chain_sync](chain/chain_sync.md) - About how Grin's blockchain is synchronized
- [blocks_and_headers](chain/blocks_and_headers.md) - How Grin tracks blocks and headers on the chain
- [contractideas](contractideas.md) - Ideas on how to implement contracts
- [contract_ideas](contract_ideas.md) - Ideas on how to implement contracts
- [dandelion/dandelion](dandelion/dandelion.md) - About transaction propagation and cut-through. Stemming and fluffing!
- [dandelion/simulation](dandelion/simulation.md) - Dandelion simulation - aggregating transaction without lock_height Stemming and fluffing!
- [internal/pool](internal/pool.md) - Technical explanation of the transaction pool
@ -18,12 +20,14 @@
- [transaction UML](transaction/aggregating transaction without lock_height) - UML of an interactive transaction
## Build and use
- [build](build.md) - Explaining how to build and run the Grin binaries
- [release](release_instruction.md) - Instructions of making a release
- [usage](usage.md) - Explaining how to use grin in Testnet3
- [wallet](wallet/usage.md) - Explains the wallet design and `grin wallet` sub-commands
# External (wiki)
## External (wiki)
- [FAQ](https://github.com/mimblewimble/docs/wiki/FAQ) - Frequently Asked Questions
- [Building grin](https://github.com/mimblewimble/docs/wiki/Building)
- [How to use grin](https://github.com/mimblewimble/docs/wiki/How-to-use-grin)

View file

@ -8,33 +8,33 @@ more widely.
* What is Grin?
* [Introduction to MimbleWimble](intro.md)
* Cryptographic Primitives
* Pedersen Commitments
* Pedersen Commitments
* Aggregate (Schnorr) Signatures
* Bulletproofs
* Bulletproofs
* Block and Transaction Format
* Transaction
* Input, output
* Kernel
* Block
* Header
* Body
* Compact Block
* Transaction
* Input, output
* Kernel
* Block
* Header
* Body
* Compact Block
* Chain State and Merkle Mountain Range
* Motivation
* [Merkle Mountain Range](mmr.md)
* [State and Storage](state.md)
* [Fast Sync](fast-sync.md)
* Merkle Proofs
* Motivation
* [Merkle Mountain Range](mmr.md)
* [State and Storage](state.md)
* [Fast Sync](fast-sync.md)
* Merkle Proofs
* Proof of Work
* Cuckoo Cycle
* Difficulty Algorithm
* Cuckoo Cycle
* Difficulty Algorithm
* Wire protocol
* Seeding and Sync
* Propagation
* Low-level Messages
* Seeding and Sync
* Propagation
* Low-level Messages
* Dandelion & Aggregation
* Building Transactions
* Important Parameters
* Fees and Transaction Weight
* Reward and Block Weight
* Fees and Transaction Weight
* Reward and Block Weight
* [Smart Contracts](contracts.md)

View file

@ -1,20 +1,21 @@
### Grin Wallet + Library Design
# Grin Wallet + Library Design
![wallet design](wallet-arch.png)
**High Level Wallet Design Overview**
## High Level Wallet Design Overview
The current Grin `wallet` crate provides several layers of libraries, services, and traits that can be mixed, matched and reimplemented to support
various needs within the default Grin wallet as well as provide a set of useful library functions for 3rd-party implementors. At a very high level,
various needs within the default Grin wallet as well as provide a set of useful library functions for 3rd-party implementors. At a very high level,
the code is organized into the following components (from highest-level to lowest):
* **Command Line Client** - The command line client invoked by `grin wallet [command]`, simply instantiates the other components below
* **Command Line Client** - The command line client invoked by `grin wallet [command]`, simply instantiates the other components below
and parses command line arguments as needed.
* **Web Wallet Client** - [Work In Progress] A web wallet client accessible from the local machine only. Current code can be viewed here:
https://github.com/mimblewimble/grin-web-wallet
* **Web Wallet Client** - [Work In Progress] A web wallet client accessible from the local machine only. Current code can be viewed here:
https://github.com/mimblewimble/grin-web-wallet
* **Static File Server** - [TBD] A means of serving up the web wallet client above to the user (still under consideration)
* **libWallet** - A high level wallet library that provides functions for the default grin wallet. The functions in here can be somewhat
specific to how the grin wallet does things, but could still be reused by 3rd party implementors following the same basic principles as grin
does. Major functionality is split into:
specific to how the grin wallet does things, but could still be reused by 3rd party implementors following the same basic principles as grin
does. Major functionality is split into:
* **Owner API** - An API that provides information that should only be viewable by the wallet owner
* **Foreign API** - An API to communicate with other wallets and external grin nodes
* **Service Controller** - A Controller that instantiates the above APIs (either locally or via web services)
@ -22,17 +23,17 @@ https://github.com/mimblewimble/grin-web-wallet
results from a Grin node, etc.
* **libTx** - Library that provides lower-level transaction building, rangeproof and signing functions, highly-reusable by wallet implementors.
* **Wallet Traits** - A set of generic traits defined within libWallet and the `keychain` crate . A wallet implementation such as Grin's current
default only needs to implement these traits in order to provide a wallet:
default only needs to implement these traits in order to provide a wallet:
* **WalletClient** - Defines communication between the wallet, a running grin node and/or other wallets
* **WalletBackend** - Defines the storage implementation of the wallet
* **KeyChain** - Defines key derivation operations
### Module-Specific Notes
## Module-Specific Notes
A full API-Description for each of these parts is still TBD (and should be generated by rustdoc rather than repeated here). However a few design
notes on each module are worth mentioning here.
##### Web Wallet Client / Static File Server
### Web Wallet Client / Static File Server
This component is not a 3rd-party hosted 'Web Wallet' , but a client meant to be run on the local machine only by the wallet owner. It should provide
a usable browser interface into the wallet, that should be functionally equivalent to using the command line but (hopefully) far easier to use.
@ -40,31 +41,31 @@ It is currently not being included by a default grin build, although the require
component, see instructions on the [project page](https://github.com/mimblewimble/grin-web-wallet). The 'Static File Server' is still under
discussion, and concerns how to provide the web-wallet to the user in a default Grin build.
##### Owner API / Foreign API
### Owner API / Foreign API
The high-level wallet API has been split into two, to allow for different requirements on each. For instance, the Foreign API would listen on
an external-facing port, and therefore potentially has different security requirements from the Owner API, which can simply be bound to localhost
only.
##### libTX
### libTX
Transactions are built using the concept of a 'Slate', which is a data structure that gets passed around to all participants in a transaction,
with each appending their Inputs, Outputs or Signatures to it to build a completed wallet transaction. Although the current mode of operation in
the default client only supports single-user - single recipient, an arbitrary number of participants to a transaction is supported within libTX.
##### Wallet Traits
### Wallet Traits
In the current code, a Wallet implementation is just a combination of these three traits. The vast majority of functions within libwallet
and libTX have a signature similar to the following:
```
```rust
pub fn retrieve_outputs<T: ?Sized, C, K>(
!·wallet: &mut T,
!·show_spent: bool,
!·tx_id: Option<u32>,
!·wallet: &mut T,
!·show_spent: bool,
!·tx_id: Option<u32>,
) -> Result<Vec<OutputData>, Error>
where
!·T: WalletBackend<C, K>,
where
!·T: WalletBackend<C, K>,
!·C: WalletClient,
!·K: Keychain,
{
@ -73,21 +74,16 @@ where
With `T` in this instance being a class that implements the `WalletBackend` trait, which is further parameterized with implementations of
`WalletClient` and `Keychain`.
There is currently only a single implementation of the Keychain trait within the Grin code, in the `keychain` crate exported as `ExtKeyChain`.
The `Keychain` trait makes several assumptions about the underlying implementation, particularly that it will adhere to a
There is currently only a single implementation of the Keychain trait within the Grin code, in the `keychain` crate exported as `ExtKeyChain`.
The `Keychain` trait makes several assumptions about the underlying implementation, particularly that it will adhere to a
[BIP-38 style](https://github.com/bitcoin/bips/blob/master/bip-0038.mediawiki) 'master key -> child key' model.
There are two implementations of `WalletClient` within the code, the main version being the `HTTPWalletClient` found within `wallet/src/client.rs` and
the seconds a test client that communicates with an in-process instance of a chain. The WalletClient isolates all network calls, so upgrading wallet
There are two implementations of `WalletClient` within the code, the main version being the `HTTPWalletClient` found within `wallet/src/client.rs` and
the seconds a test client that communicates with an in-process instance of a chain. The WalletClient isolates all network calls, so upgrading wallet
communication from the current simple http interaction to a more secure protocol (or allowing for many options) should be a simple
matter of dropping in different `WalletClient` implementations.
There are also two implementations of `WalletBackend` within the code at the base of the `wallet` crate. `LMDBBackend` found within
There are also two implementations of `WalletBackend` within the code at the base of the `wallet` crate. `LMDBBackend` found within
`wallet/src/lmdb_wallet.rs` is the main implementation, and is now used by all grin wallet commands. The earlier `FileWallet` still exists
within the code, however it is not invoked, and given there are no real advantages to running it over a DB implementation, development on it
has been dropped in favour of the LMDB implementation.
has been dropped in favour of the LMDB implementation.

View file

@ -18,22 +18,22 @@ While not being exhaustive, the different ways we can imagine wallet software
working with Grin are the following:
1. A receive-only online wallet server. This should have some well-known network
address that can be reached by a client. There should be a spending key kept
offline.
2. A fully offline interaction. The sender uses her wallet to dump a file that's
sent to the receiver in any practical way. The receiver builds upon that file,
sending it back to the sender. The sender finalizes the transaction and sends it
to a Grin node.
3. Fully online interaction through a non-trusted 3rd party. In this mode
receiver and sender both connect to a web server that facilitates the
interaction. Exchanges can be all be encrypted.
4. Hardware wallet. Similar to offline but the hardware wallet interacts with
a computer to produce required public keys and signatures.
5. Web wallet. A 3rd party runs the required software behind the scenes and
handles some of the key generation. This could be done in a custodial,
non-custodial and multisig fashion.
6. Fully programmatic. Similar to the online server, but both for receiving and
sending, most likely by an automated bot of some sorts.
address that can be reached by a client. There should be a spending key kept
offline.
1. A fully offline interaction. The sender uses her wallet to dump a file that's
sent to the receiver in any practical way. The receiver builds upon that file,
sending it back to the sender. The sender finalizes the transaction and sends it
to a Grin node.
1. Fully online interaction through a non-trusted 3rd party. In this mode
receiver and sender both connect to a web server that facilitates the
interaction. Exchanges can be all be encrypted.
1. Hardware wallet. Similar to offline but the hardware wallet interacts with
a computer to produce required public keys and signatures.
1. Web wallet. A 3rd party runs the required software behind the scenes and
handles some of the key generation. This could be done in a custodial,
non-custodial and multisig fashion.
1. Fully programmatic. Similar to the online server, but both for receiving and
sending, most likely by an automated bot of some sorts.
As part of the Grin project, we will only consider the first 2 modes of
interaction. We hope that other projects and businesses will tackle other modes
@ -51,14 +51,14 @@ to build and manipulate commitments, related bulletproofs and aggregate
signatures we can kill many birds with one stone:
* Make the job of wallet implementers easier. The underlying cryptographic
concepts can be quite complex.
concepts can be quite complex.
* Make wallet implementations more secure. As we provide a higher level API,
there is less risk in misusing lower-level constructs.
there is less risk in misusing lower-level constructs.
* Provide some standardization in the way aggregations are done. There are
sometimes multiple ways to build a commitment or aggregate signatures or proofs
in a multiparty output.
sometimes multiple ways to build a commitment or aggregate signatures or proofs
in a multiparty output.
* Provide more eyeballs and more security to the standard library. We need to
have the wallet APIs thoroughly reviewed regardless.
have the wallet APIs thoroughly reviewed regardless.
Receive-only Online Wallet
--------------------------

View file

@ -4,7 +4,8 @@
A Grin wallet maintains its state in an LMDB database, with the master seed stored in a separate file.
When creating a new wallet, the file structure should be:
```
```sh
~/[Wallet Directory]
-wallet_data/
-db/
@ -15,29 +16,30 @@ When creating a new wallet, the file structure should be:
```
* `grin-wallet.toml` contains configuration information for the wallet. You can modify values within
to change ports, the address of your grin node, or logging values.
to change ports, the address of your grin node, or logging values.
* `wallet_data/wallet.seed` is your master seed file. You must back this file up somewhere in order to
be able to recover or restore your wallet (along with its password, if given).
be able to recover or restore your wallet (along with its password, if given).
##### Data Directory
### Data Directory
By default grin will create all wallet files in the hidden directory `.grin` under your home directory (i.e. `~/.grin`).
You can also create and use a wallet with data files in the current directory, as explained in the `grin wallet init`
You can also create and use a wallet with data files in the current directory, as explained in the `grin wallet init`
command below.
### Logging + Output
#### Logging + Output
Logging configuration for the wallet is read from `grin-wallet.toml`.
### Switches common to all wallet commands
#### Switches common to all wallet commands
##### Grin Node Address
The wallet generally needs to talk to a running grin node in order to remain up-to-date and verify its contents. By default, the wallet
tries to contact a node at `127.0.0.1:13413`. To change this, modify the value in the wallet's `grin_wallet.toml` file. Alternatively,
you can provide the `-a` switch to the wallet command, e.g.:
```
```sh
[host]$ grin wallet -a "http://192.168.0.2:1341" info
```
@ -47,10 +49,10 @@ and the results verified against the latest chain information.
##### Password
All keys generated by your wallet are combinations of the master seed + a password. If no password is provided, it's assumed this
password is blank. If you do provide a password, all operations will use the seed+password and you will need the password to view or
password is blank. If you do provide a password, all operations will use the seed+password and you will need the password to view or
spend any generated outputs. The password is specified with `-p`
```
```sh
[host]$ grin wallet -p mypassword info
```
@ -61,31 +63,29 @@ spend any generated outputs. The password is specified with `-p`
### init
Before using a wallet a new `grin-wallet.toml` configuration file, seed file `wallet.seed` and storage database need
Before using a wallet a new `grin-wallet.toml` configuration file, seed file `wallet.seed` and storage database need
to be generated via the init command as follows:
By default this will place your wallet files into `~/.grin`. It is VERY IMPORTANT that you back up the `~/.grin/wallet_data/wallet.seed`
file somewhere safe and private, and ensure you somehow remember the password used to generate the wallet.
Alternatively, if you'd like to run a wallet in a directory other than the default, you can run:
```
```sh
[host]$ grin wallet [-p password] init -h
```
This will create a `grin-wallet.toml` file in the current directory configured to use the data files in the current directory,
as well as all needed data files. When running any `grin wallet` command, grin will check the current directory to see if
as well as all needed data files. When running any `grin wallet` command, grin will check the current directory to see if
a `grin-wallet.toml` file exists. If not it will use the default in `~/.grin`
### info
A summary of the wallet's contents can be retrieved from the wallet using the `info` command. Note that the `Total` sum may appear
inflated if you have a lot of unconfirmed outputs in your wallet (especially ones where a transaction is initiated by other parties
who then never it by posting to the chain). `Currently Spendable` is the most accurate field to look at here.
```
```sh
____ Wallet Summary Info as of 49 ____
Total | 3000.000000000
@ -100,17 +100,20 @@ ____ Wallet Summary Info as of 49 ____
### listen
This opens a listener on the specified port, which will listen for:
* Coinbase Transaction from a mining server
* Transactions initiated by other parties
By default the `listen` commands runs in a manner that only allows access from the local machine. To open this port up
to other machines, use the `-e` switch:
```
```sh
[host]$ grin wallet -e listen
```
To change the port on which the wallet is listening, either configure `grin-wallet.toml` or use the `-l` flag, e.g:
```
```sh
[host]$ grin wallet -l 14000 listen
```
@ -124,12 +127,12 @@ this is how you send Grins to another party.
The most important fields here are the destination (`-d`) and the amount itself. To send an amount to another listening wallet:
```
```sh
[host]$ grin wallet send -d "http://192.168.0.10:13415" 60.00
```
This will create a transaction with the other wallet listening at 192.168.0.10, port 13415 which credits the other wallet 60 grins
while debiting the 60 Grin + fees from your wallet.
while debiting the 60 Grin + fees from your wallet.
It's important to understand exactly what happens during a send command, so at a very basic level the `send` interaction goes as follows:
@ -146,25 +149,25 @@ Other flags here are:
* `-m` 'Method', which can be 'http' or 'file'. In the first case, the transaction will be sent to the IP address which follows the `-d` flag. In the second case, Grin wallet will generate a partial transaction file under the file name specified in the `-d` flag. This file needs to be signed by the recipient using the `grin wallet receive -i filename` command and finalize by the sender using the `grin wallet finalize -i filename.response` command. To create a partial transaction file, use:
```
```sh
[host]$ grin wallet send -d "transaction" -m file 60.00
```
* `-s` 'Selection strategy', which can be 'all' or 'smallest'. Since it's advantageous for outputs to be removed from the Grin chain,
the default strategy for selecting inputs in Step 1 above is to use as many outputs as possible to consolidate your balance into a
couple of outputs. This also drastically reduces your wallet size, so everyone wins. The downside is that the entire contents of
your wallet remains locked until the transaction is mined validated on the chain. To instead only select just enough inputs to
cover the amount you want to send + fees, use:
the default strategy for selecting inputs in Step 1 above is to use as many outputs as possible to consolidate your balance into a
couple of outputs. This also drastically reduces your wallet size, so everyone wins. The downside is that the entire contents of
your wallet remains locked until the transaction is mined validated on the chain. To instead only select just enough inputs to
cover the amount you want to send + fees, use:
```
```sh
[host]$ grin wallet send -d "http://192.168.0.10:13415" -s smallest 60.00
```
* `-f` 'Fluff' Grin uses a protocol called 'Dandelion' which bounces your transaction directly through several listening nodes in a
'Stem Phase' before randomly 'Fluffing', i.e. broadcasting it to the entire network. This reduces traceability at the cost of lengthening
the time before your transaction appears on the chain. To ignore the stem phase and broadcast immediately:
* `-f` 'Fluff' Grin uses a protocol called 'Dandelion' which bounces your transaction directly through several listening nodes in a
'Stem Phase' before randomly 'Fluffing', i.e. broadcasting it to the entire network. This reduces traceability at the cost of lengthening
the time before your transaction appears on the chain. To ignore the stem phase and broadcast immediately:
```
```sh
[host]$ grin wallet send -f -d "http://192.168.0.10:13415" 60.00
```
@ -172,66 +175,66 @@ the time before your transaction appears on the chain. To ignore the stem phase
Simply displays all the the outputs in your wallet: e.g:
```
```sh
[host]$ grin wallet outputs
Wallet Outputs - Block Height: 49
Wallet Outputs - Block Height: 49
------------------------------------------------------------------------------------------------------------------------------------------------
Key Id Child Key Index Block Height Locked Until Status Is Coinbase? Num. of Confirmations Value Transaction
Key Id Child Key Index Block Height Locked Until Status Is Coinbase? Num. of Confirmations Value Transaction
================================================================================================================================================
13aea76c742ec6298360 2 1 4 Unspent true 49 60.000000000 37
13aea76c742ec6298360 2 1 4 Unspent true 49 60.000000000 37
------------------------------------------------------------------------------------------------------------------------------------------------
ef619c4cdda170f9a4eb 3 2 5 Unspent true 48 60.000000000 38
ef619c4cdda170f9a4eb 3 2 5 Unspent true 48 60.000000000 38
------------------------------------------------------------------------------------------------------------------------------------------------
be5a6f68db3ff4b88786 4 3 6 Unspent true 47 60.000000000 1
be5a6f68db3ff4b88786 4 3 6 Unspent true 47 60.000000000 1
------------------------------------------------------------------------------------------------------------------------------------------------
753a4086bf73246f8206 5 4 7 Unspent true 46 60.000000000 2
753a4086bf73246f8206 5 4 7 Unspent true 46 60.000000000 2
------------------------------------------------------------------------------------------------------------------------------------------------
b2bf4c3e64a67158989f 6 5 8 Unspent true 45 60.000000000 4
b2bf4c3e64a67158989f 6 5 8 Unspent true 45 60.000000000 4
------------------------------------------------------------------------------------------------------------------------------------------------
db427d890fe59824ee64 7 6 9 Unspent true 44 60.000000000 11
```
db427d890fe59824ee64 7 6 9 Unspent true 44 60.000000000 11
```
Spent outputs are not shown by default. To show them, provide the `-s` flag.
```
```sh
[host]$ grin wallet -s outputs
```
### txs
Every time an operation is performed in your wallet (receive coinbase, send, receive), an entry is added to an internal transaction log
Every time an operation is performed in your wallet (receive coinbase, send, receive), an entry is added to an internal transaction log
containing vital information about the transaction. Because the Mimblewimble chain contains no identifying information whatsoever,
this transaction log is necessary in order to allow your wallet to keep track of what was sent and received. To view the contents of the
transaction log, use the `txs`
```
```sh
[host]$ grin wallet txs
Transaction Log - Block Height: 49
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Id Type Shared Transaction Id Creation Time Confirmed? Confirmation Time Num. Inputs Num. Outputs Amount Credited Amount Debited Fee Net Difference
==========================================================================================================================================================================================================================================
1 Confirmed Coinbase None 2018-07-20 19:46:45.658263284 UTC true 2018-07-20 19:46:45.658264768 UTC 0 1 60.000000000 0.000000000 None 60.000000000
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
2 Confirmed Coinbase None 2018-07-20 19:46:45.658424352 UTC true 2018-07-20 19:46:45.658425102 UTC 0 1 60.000000000 0.000000000 None 60.000000000
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
3 Confirmed Coinbase None 2018-07-20 19:46:45.658541297 UTC true 2018-07-20 19:46:45.658542029 UTC 0 1 60.000000000 0.000000000 None 60.000000000
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
4 Confirmed Coinbase None 2018-07-20 19:46:45.658657246 UTC true 2018-07-20 19:46:45.658657970 UTC 0 1 60.000000000 0.000000000 None 60.000000000
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
5 Confirmed Coinbase None 2018-07-20 19:46:45.658864074 UTC true 2018-07-20 19:46:45.658864821 UTC 0 1 60.000000000 0.000000000 None 60.000000000
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
6 Received Tx 03715cf6-f29b-4a3a-bda5-b02cba6bf0d9 2018-07-20 19:46:46.120244904 UTC false None 0 1 60.000000000 0.000000000 None 60.000000000
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Transaction Log - Block Height: 49
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Id Type Shared Transaction Id Creation Time Confirmed? Confirmation Time Num. Inputs Num. Outputs Amount Credited Amount Debited Fee Net Difference
==========================================================================================================================================================================================================================================
1 Confirmed Coinbase None 2018-07-20 19:46:45.658263284 UTC true 2018-07-20 19:46:45.658264768 UTC 0 1 60.000000000 0.000000000 None 60.000000000
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
2 Confirmed Coinbase None 2018-07-20 19:46:45.658424352 UTC true 2018-07-20 19:46:45.658425102 UTC 0 1 60.000000000 0.000000000 None 60.000000000
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
3 Confirmed Coinbase None 2018-07-20 19:46:45.658541297 UTC true 2018-07-20 19:46:45.658542029 UTC 0 1 60.000000000 0.000000000 None 60.000000000
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
4 Confirmed Coinbase None 2018-07-20 19:46:45.658657246 UTC true 2018-07-20 19:46:45.658657970 UTC 0 1 60.000000000 0.000000000 None 60.000000000
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
5 Confirmed Coinbase None 2018-07-20 19:46:45.658864074 UTC true 2018-07-20 19:46:45.658864821 UTC 0 1 60.000000000 0.000000000 None 60.000000000
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
6 Received Tx 03715cf6-f29b-4a3a-bda5-b02cba6bf0d9 2018-07-20 19:46:46.120244904 UTC false None 0 1 60.000000000 0.000000000 None 60.000000000
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
```
To see the inputs/outputs associated with a particular transaction, use the `-i` switch providing the Id of the given transaction, e.g:
```
```sh
[host]$ grin wallet txs -i 6
Transaction Log - Block Height: 49
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Id Type Shared Transaction Id Creation Time Confirmed? Confirmation Time Num. Inputs Num. Outputs Amount Credited Amount Debited Fee Net Difference
Id Type Shared Transaction Id Creation Time Confirmed? Confirmation Time Num. Inputs Num. Outputs Amount Credited Amount Debited Fee Net Difference
===========================================================================================================================================================================================================
6 Received Tx 03715cf6-f29b-4a3a-bda5-b02cba6bf0d9 2018-07-20 19:46:46.120244904 UTC false None 0 1 60.000000000 0.000000000 None 60.000000000
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
@ -239,32 +242,32 @@ Transaction Log - Block Height: 49
Wallet Outputs - Block Height: 49
------------------------------------------------------------------------------------------------------------------------------------------------
Key Id Child Key Index Block Height Locked Until Status Is Coinbase? Num. of Confirmations Value Transaction
Key Id Child Key Index Block Height Locked Until Status Is Coinbase? Num. of Confirmations Value Transaction
================================================================================================================================================
a7aebee71fdd78396ae6 9 5 0 Unconfirmed false 0 60.000000000 6
a7aebee71fdd78396ae6 9 5 0 Unconfirmed false 0 60.000000000 6
------------------------------------------------------------------------------------------------------------------------------------------------
```
##### cancel
#### cancel
Everything before Step 6 in the send phase above happens completely locally in the wallets' data storage and separately from the chain.
Since it's very easy for a sender, (through error or malice,) to fail to post a transaction to the chain, it's very possible for the contents
of a wallet to become locked, with all outputs unable to be selected because the wallet is waiting for a transaction that will never hit
Everything before Step 6 in the send phase above happens completely locally in the wallets' data storage and separately from the chain.
Since it's very easy for a sender, (through error or malice,) to fail to post a transaction to the chain, it's very possible for the contents
of a wallet to become locked, with all outputs unable to be selected because the wallet is waiting for a transaction that will never hit
the chain to complete. For example, in the output from `grin wallet txs -i 6` above, the transaction is showing as `confirmed == false`
meaning the wallet has not seen any of the associated outputs on the chain. If it's evident that this transaction will never be posted, locked
outputs can be unlocked and associate unconfirmed outputs removed with the `cancel` command.
Running against the data above:
```
```sh
[host]$ grin wallet cancel -i 6
[host]$ grin wallet txs -i 6
Transaction Log - Block Height: 49
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Id Type Shared Transaction Id Creation Time Confirmed? Confirmation Time Num. Inputs Num. Outputs Amount Credited Amount Debited Fee Net Difference
Id Type Shared Transaction Id Creation Time Confirmed? Confirmation Time Num. Inputs Num. Outputs Amount Credited Amount Debited Fee Net Difference
=======================================================================================================================================================================================================================
6 Received Tx - Cancelled 03715cf6-f29b-4a3a-bda5-b02cba6bf0d9 2018-07-20 19:46:46.120244904 UTC false None 0 1 60.000000000 0.000000000 None 60.000000000
6 Received Tx - Cancelled 03715cf6-f29b-4a3a-bda5-b02cba6bf0d9 2018-07-20 19:46:46.120244904 UTC false None 0 1 60.000000000 0.000000000 None 60.000000000
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
```
@ -298,30 +301,29 @@ If for some reason the wallet cancel commands above don't work, or you need to r
To do this, generate an empty wallet somewhere with:
```
```sh
grin wallet init -h
```
Delete the newly generated wallet data directory and seed file:
```
```sh
[host@new_wallet_dir]# rm -rf wallet_data/db
[host@new_wallet_dir]# rm wallet_data/wallet.seed
```
Then copy your backed up `wallet.seed` file into the new `wallet_data` directory, ensuring it's called `wallet.seed`
```
```sh
[host@new_wallet_dir]# cp OLD_WALLET.seed wallet_data/wallet.seed
```
Then ensure that you're running a grin node, and makes sure nothing is attempting to mine into your wallet. Then, in the
wallet directory:
```
```sh
grin wallet restore
```
Note this operation can potentially take a long time. Once it's done, your wallet outputs should be restored, and you can
transact with your restored wallet as before the backup.
transact with your restored wallet as before the backup.