diff --git a/doc/src/SUMMARY.md b/doc/src/SUMMARY.md index c9fc4cb01..1950ee979 100644 --- a/doc/src/SUMMARY.md +++ b/doc/src/SUMMARY.md @@ -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) diff --git a/doc/src/architecture/dna.md b/doc/src/architecture/dna.md deleted file mode 100644 index 47ac98e0b..000000000 --- a/doc/src/architecture/dna.md +++ /dev/null @@ -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`. diff --git a/doc/src/architecture/tx_lifetime.md b/doc/src/architecture/tx_lifetime.md index 690723946..9e38c1134 100644 --- a/doc/src/architecture/tx_lifetime.md +++ b/doc/src/architecture/tx_lifetime.md @@ -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, +} + +pub struct Transaction { + /// Calls executed in this transaction + pub calls: Vec, + /// Attached ZK proofs + pub proofs: Vec>, + /// Attached Schnorr signatures + pub signatures: Vec>, +} +``` + +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, + pub outputs: Vec, +} + +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, + 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, +} +``` + +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.