book: Remove DNA, add payment transaction stub.

This commit is contained in:
parazyd
2022-12-09 11:08:49 +01:00
parent 71e04f6bf9
commit 8f43901fc3
3 changed files with 99 additions and 114 deletions

View File

@@ -13,7 +13,6 @@
- [Blockchain](architecture/blockchain.md)
- [Consensus](architecture/consensus.md)
- [Transactions](architecture/tx_lifetime.md)
- [DNA](architecture/dna.md)
- [Smart Contracts](architecture/smart_contracts.md)
- [Tooling](architecture/tooling.md)
- [Client](clients/clients.md)

View File

@@ -1,112 +0,0 @@
DarkFi Node Architecture (DNA)
==============================
The DarkFi ecosystem runs as a network of P2P nodes, where these nodes
interact with each other over specific programs (or layers). In this
section, we'll explain how each of the layers fit together and when
combined create a functioning network that becomes DarkFi.
The layers are organized as a bottom-up pyramid, much like the
DarkFi logo:
$$ \setminus validatord / $$
$$ \setminus darkfid / $$
$$ \setminus drk / $$
We will start with the top-level daemon - `validatord` - which
serves as the consensus and data storage layer, then we will explain
`darkfid` and its communication with the layer above (`validatord`),
and the layer below (`drk`).
An abstract view of the network looks like the following:
```
[drk] <--> [darkfid] <--> [validatord] <-+
|
[drk] <--> [darkfid] <--> [validatord] <-+
```
## validatord
`validatord` is the DarkFi consensus and data storage layer. Everyone
that runs a validator participates in the network as a data archive,
and is able to store incoming transactions, and relay them to
other validators over the P2P network and protocol. Additionally,
storing this data allows others to replicate it and participate in
the same way.
Provided there is a locked stake on a running validator, the node
can also participate in the Proof-of-Stake consensus, enabling the
ability to vote on incoming transactions rather than just relaying
(and validating) them.
In case the node is not participating in the consensus, it should still
relay incoming transactions to other (ideally consensus-participating)
validators in the network.
### Inner workings
In its database, `validatord` stores transactions and blocks that
have reached consensus. This is commonly known as a _"blockchain"_.
The blockchain is a shared state that is replicated between all
validators in the network.
Additionally, validators keep a pool of incoming transactions
and proposed blocks, which get validated and voted on by the
consensus-participating validators.
The lifetime of an incoming transaction (and block) is as follows:
1. Wait for a transaction
2. Validate incoming transaction (and go back to 1. if invalid)
3. Broadcast transaction to other validators in the network
4. Other validators validate transaction (and go back to 1. if invalid)
5. Leader validates the state transition and proposes a block
6. Consensus-participating nodes validate the state transition and
vote on the proposed block if the state transition is valid.
7. If the block is confirmed, it is appended to the _blockchain_ and
is replicated between all validators in the network.
## darkfid
`TODO: Initial sync and retrieving wallet state?`
`darkfid` is the client layer of DarkFi used for wallet management
and transaction broadcasting. The wallet keeps a history of balances,
_coins_, _nullifiers_, and _merkle roots_ that are necessary in order
to create new transactions.
By design, `darkfid` is a light client, since `validatord` stores all
the blockchain data, and `darkfid` can simply query for anything it
is interested in. This allows us to avoid data duplication and simply
utilize our modular architecture. This also means that `darkfid` can
easily be replaced with more specific tooling, if need be.
### Inner workings
Using the P2P network and protocol, `darkfid` can subscribe to
`validatord` in order to receive new _nullifiers_ and _merkle roots_
whenever a new block is confirmed. This allows `darkfid` to update
its local state and enables it to create new valid transactions.
`darkfid` exposes a JSON-RPC endpoint for clients to interact with it.
This allows a number of things, such as: listing balances, creating
and submitting transactions, key management, and more.
When creating a new transactions, `darkfid` uses the local synced state
in order to create new _coins_ and combine them in a transaction. This
transaction is then submitted to the above validator layer where the
transaction will get validated and voted on in order to be included
into a block.
## drk
`drk` is a client tool that interacts with `darkfid` in a user-friendly
way and provides a command-line interface to the DarkFi network and
its functionality.
The interaction with `darkfid` is done over the JSON-RPC protocol
and communicates with the endpoint exposed by `darkfid`.

View File

@@ -1,7 +1,9 @@
# Transaction behaviour
# Transactions
_(Temporary document, to be integrated into other docs)_
## Transaction behaviour
In our network context, we have two types of nodes.
1. Consensus Participant (`CP`)
@@ -96,3 +98,99 @@ for any fork(including canonical) or it get finalized.
Unproposed transactions refers to all $tx$ not included in a proposal of any fork.
If a fork that can be finalized fails to validate all its transactions(14), it should be dropped.
## The `Transaction` object
```rust
pub struct ContractCall {
/// The contract ID to which the payload is fed to
pub contract_id: ContractId,
/// Arbitrary payload for the contract call
pub payload: Vec<u8>,
}
pub struct Transaction {
/// Calls executed in this transaction
pub calls: Vec<ContractCall>,
/// Attached ZK proofs
pub proofs: Vec<Vec<Proof>>,
/// Attached Schnorr signatures
pub signatures: Vec<Vec<Signature>>,
}
```
A generic DarkFi transaction object is simply an array of smart
contract calls, along with attached ZK proofs and signatures needed
to properly verify the contracts' execution. A transaction can have
any number of calls, and proofs, provided it does not exhaust a set
gas limit.
In DarkFi, every operation is a smart contract. This includes payments,
which we'll explain in the following section.
## Payments
For A -> B payments in DarkFi we use the Sapling scheme that originates
from zcash. A payment transaction has a number of _inputs_ (which are
coins being burned/spent), and a number of _outputs_ (which are coins
being minted/created). An explanation for the ZK proofs for this scheme
can be found in the Zkas section of this book, under Sapling.
In code, the structs we use are the following:
```rust
pub struct MoneyTransferParams {
pub inputs: Vec<Input>,
pub outputs: Vec<Output>,
}
pub struct Input {
/// Pedersen commitment for the input's value
pub value_commit: ValueCommit,
/// Pedersen commitment for the input's token ID
pub token_commit: ValueCommit,
/// Revealed nullifier
pub nullifier: Nullifier,
/// Revealed Merkle root
pub merkle_root: MerkleNode,
/// Public key for the Schnorr signature
pub signature_public: PublicKey,
}
pub struct Output {
/// Pedersen commitment for the output's value
pub value_commit: ValueCommit,
/// Pedersen commitment for the output's token ID
pub token_commit: ValueCommit,
/// Minted coin: poseidon_hash(pubkey, value, token, serial, blind)
pub coin: Coin,
/// The encrypted note ciphertext
pub encrypted_note: EncryptedNote,
}
pub struct EncryptedNote {
pub ciphertext: Vec<u8>,
pub ephemeral_key: PublicKey,
}
pub struct Note {
/// Serial number of the coin, used to derive the nullifier
pub serial: pallas::Base,
/// Value of the coin
pub value: u64,
/// Token ID of the coin
pub token_id: TokenId,
/// Blinding factor for the coin bulla
pub coin_blind: pallas::Base,
/// Blinding factor for the value Pedersen commitment
pub value_blind: ValueBlind,
/// Blinding factor for the token ID Pedersen commitment
pub token_blind: ValueBlind,
/// Attached memo (arbitrary data)
pub memo: Vec<u8>,
}
```
In the blockchain state, every minted coin must be added into a Merkle
tree of all existing coins. Once added, the new tree root is used to
prove existence of this coin when it's being spent.