17 Commits

Author SHA1 Message Date
Dave Hrycyszyn
073ce25306 Minor readme edit 2024-10-19 17:28:09 +01:00
Dave Hrycyszyn
5f6f4a0409 Re-arranged the README a bit. 2024-10-19 17:11:19 +01:00
Dave Hrycyszyn
0af7d1b2b0 Noting that this thing is strictly an experiment 2024-10-19 16:56:09 +01:00
Dave Hrycyszyn
e821ed2a57 Renamed binaries to make things a bit more general 2024-10-19 16:50:45 +01:00
Dave Hrycyszyn
4cf3d03349 Added a note about commit-reveal 2024-07-17 13:18:17 +01:00
Dave Hrycyszyn
f6db54ac34 Adding a few use case ideas while working on the larger Side problem 2024-07-15 17:03:31 +01:00
Dave Hrycyszyn
d711ca50d5 Adding a few things to the README 2024-07-15 14:57:47 +01:00
Dave Hrycyszyn
a3ee17119d Getting rid of unused field warning 2024-07-15 14:56:34 +01:00
Dave Hrycyszyn
e1a48c3fca Explaining how to use the stdin watcher for each Side Node 2024-06-27 11:16:09 +01:00
Dave Hrycyszyn
d7dfa9cc24 Noting the lack of chain catch-up 2024-06-27 11:12:50 +01:00
Dave Hrycyszyn
447f99edf4 Minor changes to the README to distinguish between Side chain and BFT-CRDT chains 2024-06-27 11:10:07 +01:00
Dave Hrycyszyn
a3794e64f5 Fixing unused imports 2024-06-27 11:08:10 +01:00
Dave Hrycyszyn
e5c9c1364c Moved the crdt stdin listener to into the CRDT module 2024-06-27 11:06:49 +01:00
Dave Hrycyszyn
3595675d41 Create LICENSE 2024-06-27 11:03:27 +01:00
Dave Hrycyszyn
b206c0e6ce Fixed README formatting 2024-06-27 10:59:46 +01:00
Dave Hrycyszyn
d937f9ffaa Merge branch 'experiments/bitcoin-native' 2024-06-27 10:57:18 +01:00
Dave Hrycyszyn
d537e80de1 Noting that we should remove the proc macro stuff 2024-06-18 15:41:13 +01:00
32 changed files with 126 additions and 97 deletions

8
.idea/modules.xml generated
View File

@@ -1,8 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectModuleManager">
<modules>
<module fileurl="file://$PROJECT_DIR$/.idea/side.iml" filepath="$PROJECT_DIR$/.idea/side.iml" />
</modules>
</component>
</project>

View File

@@ -6,9 +6,9 @@
<sourceFolder url="file://$MODULE_DIR$/crates/bft-json-crdt/bft-crdt-derive/src" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/crates/bft-json-crdt/src" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/crates/bft-json-crdt/tests" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/side-node/src" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/side-node/tests" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/side-watcher/src" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/crdt-node/src" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/crdt-node/tests" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/crdt-relayer/src" isTestSource="false" />
<excludeFolder url="file://$MODULE_DIR$/target" />
</content>
<orderEntry type="inheritedJdk" />

6
.idea/vcs.xml generated
View File

@@ -1,6 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="" vcs="Git" />
</component>
</project>

82
Cargo.lock generated
View File

@@ -951,6 +951,47 @@ dependencies = [
"cfg-if",
]
[[package]]
name = "crdt-node"
version = "0.1.0"
dependencies = [
"anyhow",
"async-trait",
"bdk",
"bdk_esplora",
"bdk_sqlite",
"bdk_wallet",
"bft-crdt-derive",
"bft-json-crdt",
"bitcoin 0.32.2",
"clap 4.5.7",
"dirs",
"electrum-client 0.20.0",
"ezsockets",
"fastcrypto",
"indexmap 2.2.6",
"reqwest",
"serde",
"serde_json",
"sha256",
"tokio",
"toml",
"tracing",
"uuid",
]
[[package]]
name = "crdt-relayer"
version = "0.1.0"
dependencies = [
"async-trait",
"ezsockets",
"sha256",
"tokio",
"tracing",
"tracing-subscriber",
]
[[package]]
name = "criterion"
version = "0.4.0"
@@ -3333,47 +3374,6 @@ version = "1.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64"
[[package]]
name = "side-node"
version = "0.1.0"
dependencies = [
"anyhow",
"async-trait",
"bdk",
"bdk_esplora",
"bdk_sqlite",
"bdk_wallet",
"bft-crdt-derive",
"bft-json-crdt",
"bitcoin 0.32.2",
"clap 4.5.7",
"dirs",
"electrum-client 0.20.0",
"ezsockets",
"fastcrypto",
"indexmap 2.2.6",
"reqwest",
"serde",
"serde_json",
"sha256",
"tokio",
"toml",
"tracing",
"uuid",
]
[[package]]
name = "side-watcher"
version = "0.1.0"
dependencies = [
"async-trait",
"ezsockets",
"sha256",
"tokio",
"tracing",
"tracing-subscriber",
]
[[package]]
name = "signal-hook-registry"
version = "1.4.2"

View File

@@ -1,4 +1,4 @@
[workspace]
members = ["side-node", "side-watcher"]
members = ["crdt-node", "crdt-relayer"]
resolver = "2"

21
LICENSE Normal file
View File

@@ -0,0 +1,21 @@
MIT License
Copyright (c) 2024 Side Protocol
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

View File

@@ -1,27 +1,37 @@
# Side BFT-CRDT PoC
# BFT-CRDT PoC
This is a proof of concept implementation of a BFT-CRDT blockchain system.
This is a proof of concept implementation of a [BFT-CRDT](https://jzhao.xyz/posts/bft-json-crdt) blockchain-like system. It is willfully, wildly insecure as a blockchain right now. Think of it as an experiment which is strictly for fun and poking at ideas.
This code is based on the ideas of [Martin Kleppmann](https://martin.kleppmann.com/papers/bft-crdt-papoc22.pdf) and the ideas and code of [Jacky Zhao](https://jzhao.xyz/). Have a read, they are both excellent writers and have some of the most interesting computing ideas I've run across in quite a while.
It is not clear what this thing is for, yet. It's not a blockchain. It makes a kind of secure DAG. It uses BFT-CRDTs to make a Sybil-proof and secure information transmission system for messages, with eventual consistency guarantees.
The idea that it could be possible to set up a secure Sybil-proof system, negating the energy burn required for proof of work, the financially exclusionary proof of stake, or the meat space hassle of a proof of personhood ceremony, is too attractive to ignore. At least, if you're interested in cool P2P systems.
## Prerequisites
Install a recent version of Rust.
## Running in development
Run the watcher first:
```bash
cd side-watcher
cd crdt-relayer
cargo watch -x run
```
To init a Side node:
```bash
cd side-node
cd crdt-node
cargo run -- init node1
cargo run -- init node2
cargo run -- init node3
cargo run -- init node4
```
To start a node with a cargo watch for development purposes (from the side-node dir), open up a few terminals and run:
To start a node with a cargo watch for development purposes (from the `crdt-node` dir), open up a few terminals and run:
```bash
cargo watch -x "run -- run -- node1"
@@ -29,34 +39,23 @@ cargo watch -x "run -- run -- node2"
cargo watch -x "run -- run -- node3"
cargo watch -x "run -- run -- node4"
```
You can then type directly into each of the Crdt Node consoles. Messages will be relayed to each Crdt Node, and the transaction history will end up being the same on all nodes.
## Discussion
What we have here is a very simple system comprised of two key parts: the Side Node, and the Side Watcher.
What we have here is a very simple system comprised of two parts: the Crdt Node, and the Crdt Relayer.
### Side Node(s)
### Crdt Node(s)
The Side Nodes make up a system of BFT-CRDT-producing nodes that can make a blockchain. Currently they can reliably send transactions to each other in a secure way, such that all nodes they communicate with can tell whether received transactions are obeying the rules of the system.
The Crdt Nodes make up a system of BFT-CRDT-producing nodes that can make a sort of wildly insecure blockchain. Currently, they can reliably send transactions to each other in a secure way, such that all nodes they communicate with can tell whether received transactions are obeying the rules of the system.
Next dev tasks:
The Crdt Node does not download any chain state, and if one goes off-line it will miss transactions. This is expected at the moment and fairly easy to fix, with a bit of work.
[ ] enable Side Nodes to download current P2P chain state so that they start out with a consistent copy of transaction data
[ ] add smart contract execution engine (CosmWasm would be a good first choice)
[ ] enable Side Nodes to download contract code for a given contract
[ ] enable Side Nodes to download current contract state for a given contract
[ ] switch to full P2P messaging instead of websockets
[ ] take the Side Watcher out of the system by electing a Side Node as a leader, so that agreement about transaction inclusion can be reached for a given block.
### Crdt Relayer
### Side Watcher
The Crdt Relayer replicates transactions between nodes using a websocket. We aim to eliminate this component from the architecture, but for the moment it simplifies networking and consensus agreement while we experiment with higher-value concepts.
The Side Watcher is a simple relayer node that sits between the Side Chain (Cosmos) and the decentralized Side Nodes. At the moment, it simply relays transactions between nodes via a websocket. We aim to eliminate this component from the architecture, but for the moment it simplifies networking and consensus agreement while we experiment with higher-value concepts.
To fulfill the promises in the Lite Paper, the Side Watcher needs to:
[ ] make a block for the P2P when the Side Chain creates a block
[ ] submit P2P chain data to the Side Chain
Later, we will aim to remove the Side Watcher from the architecture, by (a) moving to pure P2P transactions between Side Nodes, and (b) doing leader election of a Side Node to reach agreement on the submitted block.
Later, we will aim to remove the Crdt Relayer from the architecture, by (a) moving to pure P2P transactions between Crdt Nodes, and (b) doing leader election of a Crdt Node to reach agreement on the submitted block.
## Bitcoin integration
@@ -75,3 +74,28 @@ You'll need to have funded the "dave" address prior to running the `btc` command
I was using this primarily as a way to experiment with constructing and broadcasting Bitcoin transactions, with the hope that it would be possible to move on to more advanced constructions (e.g. state channels). However, now that I look at all the options, it seems that multi-party state channels in Bitcoin are (probably) impossible to construct.
There is a second, unused Bitcoin client in place which uses Blockstream's Electrum server, but this didn't seem to be working properly with respect to Signet Bitcoin network during my testing, so I went with the esplora / Mutiny version instead.
## Possible uses
### DKG
It strikes me that there are many, many systems which rely on a trusted setup, and which might be able to use Distributed Key Generation (DKG) instead. SNARK systems for instance all have this problem. Could BFT-CRDTs help here?
It is not necessarily the case that e.g. signer participants and Cosmos validators are the same entities. Being able to quickly spin up a blockchain and use it to sign (potentially temporary or ephemeral) keyshare data might be pretty useful.
### Cross chain transfers
Might the ability to be part of multiple consensus groups at once provide new opportunities for cross-chain transfers?
## Next dev tasks:
- [ ] we don't need a relayer, the first crdt node can act as a leader until people decide they don't want to trust it any more
- [ ] the leader node can have a timer in it for block creation
- [ ] code up the ability to switch leaders (can be a human decision at first, later an (optional) automated choice)
- [ ] pick a commit and reveal scheme to remove MEV. One thing to investigate is [single-use seals](https://docs.rgb.info/distributed-computing-concepts/single-use-seals)
- [ ] enable Crdt Nodes should download current P2P chain/dag state so that they start - out with a consistent copy of transaction data, and also do catch-up after going off-line
- [ ] remove the proc macro code from bft-json-crdt, it's not really needed in this implementation
- [ ] add smart contract execution engine (CosmWasm would be a good first choice)
- [ ] enable Crdt Nodes to download contract code for a given contract
- [ ] enable Crdt Nodes to download current contract state for a given contract
- [ ] switch to full P2P messaging instead of websockets

View File

@@ -1,5 +1,5 @@
[package]
name = "side-node"
name = "crdt-node"
version = "0.1.0"
edition = "2021"

View File

@@ -6,6 +6,7 @@ use bft_json_crdt::{
use serde::{Deserialize, Serialize};
pub mod keys;
pub mod stdin;
pub mod websocket;
#[add_crdt_fields]

View File

@@ -1,6 +1,4 @@
use std::str::FromStr;
use bdk_wallet::bitcoin::{Address, Amount, Network};
use bdk_wallet::bitcoin::{Amount, Network};
use crate::bitcoin::clients;

View File

@@ -10,7 +10,6 @@ pub mod bitcoin;
pub(crate) mod cli;
pub(crate) mod init;
pub mod node;
pub(crate) mod stdin;
pub mod utils;
#[tokio::main]
@@ -49,7 +48,7 @@ async fn setup(name: &String) -> SideNode {
let (incoming_sender, incoming_receiver) = mpsc::channel::<SignedOp>(32);
let (stdin_sender, stdin_receiver) = std::sync::mpsc::channel();
task::spawn(async move {
stdin::input(stdin_sender);
bft_crdt::stdin::input(stdin_sender);
});
// Finally, create the node and return it

5
crdt-node/src/main.rs Normal file
View File

@@ -0,0 +1,5 @@
use crdt_node;
fn main() {
crdt_node::run();
}

View File

@@ -8,7 +8,7 @@ use crate::{bft_crdt::websocket::Client, bft_crdt::TransactionList, utils};
pub struct SideNode {
crdt: BaseCrdt<TransactionList>,
bft_crdt_keys: fastcrypto::ed25519::Ed25519KeyPair,
bitcoin_wallet: bdk::Wallet<MemoryDatabase>,
_bitcoin_wallet: bdk::Wallet<MemoryDatabase>, // currently not read anywhere
incoming_receiver: mpsc::Receiver<SignedOp>,
stdin_receiver: std::sync::mpsc::Receiver<String>,
handle: ezsockets::Client<Client>,
@@ -26,7 +26,7 @@ impl SideNode {
let node = Self {
crdt,
bft_crdt_keys,
bitcoin_wallet,
_bitcoin_wallet: bitcoin_wallet,
incoming_receiver,
stdin_receiver,
handle,

View File

@@ -1,5 +1,5 @@
[package]
name = "side-watcher"
name = "crdt-relayer"
version = "0.1.0"
edition = "2021"

View File

@@ -1,5 +0,0 @@
use side_node;
fn main() {
side_node::run();
}