Skip to content

Commit

Permalink
final version
Browse files Browse the repository at this point in the history
  • Loading branch information
huiminliu09 committed Mar 27, 2022
1 parent 9a7ca47 commit db9eb47
Show file tree
Hide file tree
Showing 22 changed files with 1,652 additions and 548 deletions.
821 changes: 333 additions & 488 deletions Cargo.lock

Large diffs are not rendered by default.

3 changes: 2 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ authors = []
edition = "2018"

[dependencies]
ring = "0.16"
ring = "0.16.19"
bincode = "1.2"
serde = { version = "1.0", features = ["derive"] }
hex = "0.4"
Expand All @@ -20,6 +20,7 @@ url = "2.1"
crossbeam = "0.7"
rand = "0.6"
hex-literal = "0.2"
chrono = "0.4.0"
clap = { version = "2.33", features = ["wrap_help"]}

[features]
Expand Down
12 changes: 6 additions & 6 deletions MidtermProject1/README.md
Original file line number Diff line number Diff line change
@@ -1,22 +1,22 @@
# Midterm Project, Part 1

Due 11 PM, October 14, 2021
Due 11 PM, October 12, 2021

You may form a team of 2 with another student in this class for this and subsequent parts of this midterm project. You do not have to form a team. If you do at any point, you must work as a team through the end of Part 6. A team of two should submit a single solution. Consider to use Piazza to look for a teammate. A group set 'miners' has been created on Canvas. If you have a teammate, the two of you should be able to form a group on Canvas.
You may form a team of 2 with another student in this class for this and subsequent parts of this midterm project. You do not have to form a team. If you do at any point, you must work as a team through the end of Part 6. A team of two should submit a single solution in the following manner: One submits the entire solution that includes both names; the other submits only the name of the other teammate (both must make a submission by the deadline). Consider to use Piazza to look for a teammate.

Through this midterm project, you are going to build a simplified Bitcoin client. The goal of the client is not to run in Bitcoin mainnet or any public testnet. Instead, the goal is to run it inside your team and let you have fun with it. You have plenty of freedom of designing and implementing this project.

The midterm project should be based on your code of warmup 2. You are free to discuss warmup 2 or merge codes of teammates after it is due.
The midterm project should be based on your code of warmup 2. You are free to discuss warmup 2 or merge codes of teammates after it is due.

This is the first part of midterm project. You are going to finish the **Block** struct and the **Blockchain** struct.

## Repository management and submission

1. We suggest you to continue to work on your repo of warmup 2. Team members should work on one same repo.
2. Students can run tests (by command `cargo test`) provided in the code to check the validity of their implementation. However, passing these tests doesn't guarantee getting full grades.
2. Students can run tests (by command `cargo test`) provided in the code to check the validity of their implementation. However, passing these tests doesn't guarantee getting full grades.
3. After finishing this part, before submitting your code, please remove your tests if you write any. Please leave `mod tests` at its original code, and this is for TAs to conveniently do the grading.
4. After step 3, please push to your github repo, and click `Code`->`Download ZIP` on github to download a zip file.
5. Rename it to your netids as `netid1-netid2.zip` if teamed, else `netid.zip`. Upload the zip file on Canvas. Please check your file size and it should be less than 1MB or 2MB. One submission for one team is enough.
5. Rename it to your netids as `netid1-netid2.zip`. Upload the zip file on Canvas. Please check your file size and it should be less than 1MB or 2MB. One submission for one team is enough.
6. TAs will put additional tests (private) on the submission and run them to award marks.

## Code provided
Expand Down Expand Up @@ -84,4 +84,4 @@ We will *NOT* call insert function with invalid blocks. Specifically, we will no
3. We don't involve proof-of-work check or mining, but we need to prepare for them. So we require fields nonce and difficulty inside a block. You can start to think about how to mine or check blocks.
4. Blockchain struct will be used in multiple places in the future. For example, when you implement a miner, you insert a mined block into blockchain; when you want to mine on the longest chain, you need to get the tip as the block's parent; when you receive a block from p2p network, you insert it.
5. (Same as in warmup 2.) A tricky part about transaction and signature is how you put them together. One possible way is to create another struct called SignedTransaction. The other way is to declare a field in transaction called signature, which will be empty if there is no signature. Feel free to design your own way. Obviously, a block should carry transactions *with* signature in order to verify it. (We don’t require you to finish this in this part.)
6. We don't require you to put a coin base transaction inside blocks in this part.
6. We don't require you to put a coin base transaction inside blocks in this part.
12 changes: 6 additions & 6 deletions MidtermProject2/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ In this part of midterm project, you are going to implement the **mining** modul

## Repository management and submission

1. We suggest you to continue to work on your repo of midterm project.
1. We suggest you to continue to work on your repo of midterm project.
2. Submit a report in pdf on Canvas. Please don't submit code. One submission for one team is enough.

## Code provided
Expand All @@ -17,7 +17,7 @@ The following files are related to this assignment.

To see how the code in these files works, you can run `cargo run -- -vv` and you will see these logs in the terminal
> Miner initialized into paused mode
>
>
> API server listening at 127.0.0.1:7000
This means the miner is not started yet, however, you can use API to start it. In a browser (or *curl* command), go to
Expand Down Expand Up @@ -76,20 +76,20 @@ If it is satisfied, the block is successfully generated. Congratulations! Just i

After you finish the programming, you will have a program that can mine blocks. The experiment section requires you to run the program with different threshold/difficulty and measure the mining rate.

First, you need to set a difficulty. Since we use static difficulty, it's sufficient to set that of the genesis block. (Recall that the genesis block is created when calling *Blockchain::new()*.) Please run experiments with **at least 3 different difficulty values**.
First, you need to set a difficulty. Since we use static difficulty, it's sufficient to set that of the genesis block. (Recall that the genesis block is created when calling *Blockchain::new()*.) Please run experiments with **at least 3 different difficulty values**.

Then, start the program **in release version** by running
```
cargo run --release -- -vv
```
and call API via browser or curl command:
and call API via browser or curl command:
```
http://127.0.0.1:7000/miner/start?lambda=0
```

After some time, stop miner (or the program), count the number of blocks and calculate the mining rate (block per second). Please run experiments such that the mining rate is not too large or too low. 0.01 to 1000 blocks per second is a reasonable range. (If too low, you have to wait for too long. If too high, you may run out of memory.)

You also need to write the function to get the number of blocks if you don't have one. You can do it in your way. It can be in *src/blockchain.rs*, *src/miner.rs*, and/or *src/api/mod.rs*, etc.
You also need to write the function to get the number of blocks if you don't have one. You can do it in your way. It can be in *src/blockchain.rs*, *src/miner.rs*, and/or *src/api/mod.rs*, etc.

## Report

Expand All @@ -108,4 +108,4 @@ In the last paragraph, please use one sentence to describe how you divide your w
## Advance notice
1. Miner also needs memory pool (and UTXO state perhaps). We will cover them in the future.
2. We will cover network module in the next part. In that part, the miner just needs to follow the protocol when a block is mined. E.g., broadcast the block's hash.
3. You can also see whether your blockchain/longest chain is working after many blocks are mined. Is the longest chain growing? Is the miner generating incorrect blocks such as orphan blocks?
3. You can also see whether your blockchain/longest chain is working after many blocks are mined. Is the longest chain growing? Is the miner generating incorrect blocks such as orphan blocks?
6 changes: 3 additions & 3 deletions MidtermProject3/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ In this part of midterm project, you are going to implement the **network** modu

## Repository management and submission

1. We suggest you to continue to work on your repo of midterm project.
1. We suggest you to continue to work on your repo of midterm project.
2. Submit a report in pdf on Canvas. Please don't submit code. One submission for one team is enough.

## Code provided
Expand Down Expand Up @@ -78,7 +78,7 @@ Note: remember to start the program **in release version**, which runs much fast

## Report

Please submit a report in pdf. Please use double spacing between paragraphs and use 11 pt font size. Also please keep it within one page.
Please submit a report in pdf. Please use double spacing between paragraphs and use 16 pt font size. Also please keep it within one page.

Firstly, the report should have both teammate's name and netid. Then you need to write the following paragraphs.

Expand All @@ -98,4 +98,4 @@ In the last paragraph, please use one sentence to describe how you divide your w
## Advance notice
1. When a block is received, it should be validated/checked first. We will cover this in the future.
2. Communication of transactions will be covered in the next part.
2. The buffer is optional in this part, and will be covered in the next part.
2. The buffer is optional in this part, and will be covered in the next part.
4 changes: 2 additions & 2 deletions MidtermProject4/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ In this part of the midterm project, we will be combine last 3 week's work to ma

## Repository management and submission

1. We suggest you to continue to work on your repo of midterm project.
1. We suggest you to continue to work on your repo of midterm project.
2. Submit a report in pdf on Canvas. Please don't submit code. One submission for one team is enough.

## Code provided
Expand Down Expand Up @@ -79,4 +79,4 @@ In the last paragraph, please use one sentence to describe how you divide your w

## Advance notice
1. In the next part, you are going to make the data meaningful, i.e., expressive for cryptocurrency operations.
2. In this project, we don't consider handling spamming attacks. Orphan buffer may be spammed by blocks from an adversary (not a big issue with real PoW), but we don't require you to solve this problem.
2. In this project, we don't consider handling spamming attacks. Orphan buffer may be spammed by blocks from an adversary (not a big issue with real PoW), but we don't require you to solve this problem.
8 changes: 4 additions & 4 deletions MidtermProject5/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ This part of the Midterm project will deal with including transactions in the co

## Repository management and submission

1. We suggest you to continue to work on your repo of midterm project.
1. We suggest you to continue to work on your repo of midterm project.
2. No submission required.

## Code provided
Expand All @@ -23,7 +23,7 @@ Add the following new messages:

### Transaction format

You are free to choose any format for transaction structure. We recommend using a transaction structure that is either compatable with the UTXO model in Bitcoin or the account based model in Ethereum.
You are free to choose any format for transaction structure. We recommend using a transaction structure that is either compatable with the UTXO model in Bitcoin or the account based model in Ethereum.

- UTXO model transaction: input contains the hash of previous transaction and the index; output contains a recipient address and a value. It can support multiple inputs/outputs in a transaction. You can refer to [Bitcoin](https://en.bitcoin.it/wiki/Transaction) transaction but don't need to adopt its complex scripting language.
- Account based model transaction: it should contain a recipient address, a value, and a account-nonce. It only supports single sender and single receiver. This should be simpler to implement than UTXO model.
Expand All @@ -41,7 +41,7 @@ When receiving and processing a new transaction in *src/network/worker.rs*, plea

#### Transaction signature check

Check if the transaction is signed correctly by the public key(s).
Check if the transaction is signed correctly by the public key(s).

(Not necessary at this stage.) In UTXO model, also check the public key(s) matches the owner(s)'s address of these inputs. In account based model, check if the public key matches the owner's address of the withdrawing account.

Expand Down Expand Up @@ -79,4 +79,4 @@ Make sure the code is working properly with transactions with valid signatures.
## Advance notice
1. In the next part, we will need to add state validity to the transaction which corresponds to the double spend checks.
2. We will do ICO in the next part.
3. We will have a demo for this project after next part.
3. We will have a demo for this project after next part.
8 changes: 4 additions & 4 deletions MidtermProject6/README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Midterm Project, Part 6

This is the last part of midterm project, and you are going to finish the Bitcoin client. You need to maintain a state for the ledger that the blockchain creates and add all the necessary checks related to it.
This is the last part of midterm project, and you are going to finish the Bitcoin client. You need to maintain a state for the ledger that the blockchain creates and add all the necessary checks related to it.

** Due 11 PM, December 2, 2021. Submit a report on Canvas. One submission for one team is enough. Remember to include both author names if you are a team of two. **

Expand All @@ -20,7 +20,7 @@ In last part, you include transactions into blocks. However, in order to prevent

### State

Ledger state, or **State**, is a collection of all the required information to check transactions.
Ledger state, or **State**, is a collection of all the required information to check transactions.

- In UTXO model, **State** should contain all the unspent transaction outputs. The format of an unspent transaction output may contain *(transaction hash, output index, value, recipient)*. Output index refers to the index in transactions (remember transactions are multi-output.) Recipient refers to the recipient address of that output, and is used as the owner of that unspent transaction output.
- In account based model, **State** should contain all the accounts' information. It may contain *(account address, account nonce, balance)*.
Expand Down Expand Up @@ -84,11 +84,11 @@ For each of the following bullet your video convincingly demonstrates, you recei
3. the growth of the blockchain on each node, and that all nodes agree to each other (e.g., showing the hash and height of the tip, and the total count of the blocks);
4. the evolution of the ledger state on each node, and that all nodes agree to each other (e.g., showing the balances of certain accounts if your implementation is account based);
5. occasional invalid transactions are properly rejected and do not crash the program (i.e. the generators should take a small chance to generate invalid transactions).

If your bitcoin client is not fully completed, you can still get partial credits by showing how the individual parts work, for example:

6. traces of the generator generating random UTXO or account-based transactions, signing them, adding them to the mempool, and broadcasting their hashes;
7. traces of the network exchanging messages;
8. traces of all sorts of validations when receiving a new block/transaction;
9. traces of one process working alone (instead of three processes working in harmony);
and so on.
and so on.
37 changes: 37 additions & 0 deletions src/api/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ use serde::Serialize;
use crate::miner::Handle as MinerHandle;
use crate::network::server::Handle as NetworkServerHandle;
use crate::network::message::Message;
use crate::generator::Generator;

use log::info;
use std::collections::HashMap;
Expand All @@ -14,6 +15,7 @@ use url::Url;
pub struct Server {
handle: HTTPServer,
miner: MinerHandle,
generator: Generator,
network: NetworkServerHandle,
}

Expand All @@ -40,18 +42,21 @@ impl Server {
pub fn start(
addr: std::net::SocketAddr,
miner: &MinerHandle,
generator: &Generator,
network: &NetworkServerHandle,
) {
let handle = HTTPServer::http(&addr).unwrap();
let server = Self {
handle,
miner: miner.clone(),
generator: generator.clone(),
network: network.clone(),
};
thread::spawn(move || {
for req in server.handle.incoming_requests() {
let miner = server.miner.clone();
let network = server.network.clone();
let generator = server.generator.clone();
thread::spawn(move || {
// a valid url requires a base
let base_url = Url::parse(&format!("http://{}/", &addr)).unwrap();
Expand Down Expand Up @@ -87,10 +92,42 @@ impl Server {
miner.start(lambda);
respond_result!(req, true, "ok");
}
"/miner/end" => {
miner.exit();
respond_result!(req, true, "ok");
}
"/network/ping" => {
network.broadcast(Message::Ping(String::from("Test ping")));
respond_result!(req, true, "ok");
}
"/trans/start" => {
let params = url.query_pairs();
let params: HashMap<_, _> = params.into_owned().collect();
let lambda = match params.get("lambda") {
Some(v) => v,
None => {
respond_result!(req, false, "missing lambda");
return;
}
};
let lambda = match lambda.parse::<u64>() {
Ok(v) => v,
Err(e) => {
respond_result!(
req,
false,
format!("error parsing lambda: {}", e)
);
return;
}
};
generator.start(lambda);
respond_result!(req, true, "ok");
}
"/trans/end" => {
generator.exit();
respond_result!(req, true, "ok");
}
_ => {
let content_type =
"Content-Type: application/json".parse::<Header>().unwrap();
Expand Down
Loading

0 comments on commit db9eb47

Please sign in to comment.