1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
use crate::block::BlockType;
use crate::blockchain::Blockchain;
use crate::consensus::SaitoMessage;
use crate::mempool::Mempool;
use crate::network::Result;
use crate::transaction::Transaction;
use crate::wallet::Wallet;
use base58::ToBase58;
use std::sync::Arc;
use tokio::sync::{broadcast, RwLock};
use warp::reject::Reject;
use warp::reply::Response;
use warp::{Buf, Rejection, Reply};
use crate::peer::{handle_inbound_peer_connection, PeersDB};
#[derive(Debug)]
struct Invalid;
impl Reject for Invalid {}
#[derive(Debug)]
struct AlreadyExists;
impl Reject for AlreadyExists {}
struct Message {
msg: String,
}
impl warp::Reply for Message {
fn into_response(self) -> warp::reply::Response {
Response::new(format!("message: {}", self.msg).into())
}
}
pub async fn ws_upgrade_handler(
ws: warp::ws::Ws,
peer_db_lock: Arc<RwLock<PeersDB>>,
wallet_lock: Arc<RwLock<Wallet>>,
mempool_lock: Arc<RwLock<Mempool>>,
blockchain_lock: Arc<RwLock<Blockchain>>,
broadcast_channel_sender: broadcast::Sender<SaitoMessage>,
) -> std::result::Result<impl Reply, Rejection> {
Ok(ws.on_upgrade(move |socket| {
handle_inbound_peer_connection(
socket,
peer_db_lock,
wallet_lock,
mempool_lock,
blockchain_lock,
broadcast_channel_sender,
)
}))
}
pub async fn post_transaction_handler(
mut body: impl Buf,
mempool_lock: Arc<RwLock<Mempool>>,
blockchain_lock: Arc<RwLock<Blockchain>>,
) -> Result<impl Reply> {
let mut buffer = vec![];
while body.has_remaining() {
buffer.append(&mut body.chunk().to_vec());
let cnt = body.chunk().len();
body.advance(cnt);
}
let mut tx = Transaction::deserialize_from_net(buffer);
let blockchain = blockchain_lock.read().await;
tx.generate_metadata(tx.inputs[0].get_publickey());
if tx.validate(&blockchain.utxoset, &blockchain.staking) {
let response = std::str::from_utf8(&tx.get_signature().to_base58().as_bytes())
.unwrap()
.to_string();
let mut mempool = mempool_lock.write().await;
mempool.add_transaction(tx).await;
Ok(Message { msg: response })
} else {
Err(warp::reject::custom(Invalid))
}
}
pub async fn get_block_handler(
str_block_hash: String,
blockchain_lock: Arc<RwLock<Blockchain>>,
) -> Result<impl Reply> {
let mut block_hash = [0u8; 32];
hex::decode_to_slice(str_block_hash.clone(), &mut block_hash).expect("Failed to parse hash");
{
let blockchain = blockchain_lock.read().await;
let block = blockchain.get_block(&block_hash).await;
match block {
Some(block) => {
let block_bytes = block.serialize_for_net(BlockType::Full);
Ok(block_bytes)
}
None => Err(warp::reject()),
}
}
}