-
Notifications
You must be signed in to change notification settings - Fork 690
/
Copy pathrpc_user.rs
113 lines (92 loc) · 3.73 KB
/
rpc_user.rs
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
use std::convert::TryInto;
use std::sync::{Arc, RwLock};
use actix::System;
use borsh::BorshSerialize;
use near_client::StatusResponse;
use near_crypto::{PublicKey, Signer};
use near_jsonrpc::client::{new_client, JsonRpcClient};
use near_primitives::hash::CryptoHash;
use near_primitives::receipt::Receipt;
use near_primitives::serialize::{to_base, to_base64};
use near_primitives::transaction::SignedTransaction;
use near_primitives::types::AccountId;
use near_primitives::views::{
AccessKeyView, AccountView, BlockView, ExecutionOutcomeView, FinalExecutionOutcomeView,
QueryResponse, ViewStateResult,
};
use crate::user::User;
use near_jsonrpc_client::BlockId;
pub struct RpcUser {
signer: Arc<dyn Signer>,
client: RwLock<JsonRpcClient>,
}
impl RpcUser {
pub fn new(addr: &str, signer: Arc<dyn Signer>) -> RpcUser {
RpcUser { client: RwLock::new(new_client(&format!("http://{}", addr))), signer }
}
pub fn get_status(&self) -> Option<StatusResponse> {
System::new("actix").block_on(self.client.write().unwrap().status()).ok()
}
pub fn query(&self, path: String, data: &[u8]) -> Result<QueryResponse, String> {
System::new("actix").block_on(self.client.write().unwrap().query(path, to_base(data)))
}
}
impl User for RpcUser {
fn view_account(&self, account_id: &AccountId) -> Result<AccountView, String> {
self.query(format!("account/{}", account_id), &[])?.try_into()
}
fn view_state(&self, account_id: &AccountId, prefix: &[u8]) -> Result<ViewStateResult, String> {
self.query(format!("contract/{}", account_id), prefix)?.try_into()
}
fn add_transaction(&self, transaction: SignedTransaction) -> Result<(), String> {
let bytes = transaction.try_to_vec().unwrap();
let _ = System::new("actix")
.block_on(self.client.write().unwrap().broadcast_tx_async(to_base64(&bytes)))?;
Ok(())
}
fn commit_transaction(
&self,
transaction: SignedTransaction,
) -> Result<FinalExecutionOutcomeView, String> {
let bytes = transaction.try_to_vec().unwrap();
System::new("actix")
.block_on(self.client.write().unwrap().broadcast_tx_commit(to_base64(&bytes)))
}
fn add_receipt(&self, _receipt: Receipt) -> Result<(), String> {
// TDDO: figure out if rpc will support this
unimplemented!()
}
fn get_best_block_index(&self) -> Option<u64> {
self.get_status().map(|status| status.sync_info.latest_block_height)
}
fn get_best_block_hash(&self) -> Option<CryptoHash> {
self.get_status().map(|status| status.sync_info.latest_block_hash.into())
}
fn get_block(&self, index: u64) -> Option<BlockView> {
System::new("actix")
.block_on(self.client.write().unwrap().block(BlockId::Height(index)))
.ok()
}
fn get_transaction_result(&self, hash: &CryptoHash) -> ExecutionOutcomeView {
System::new("actix").block_on(self.client.write().unwrap().tx_details(hash.into())).unwrap()
}
fn get_transaction_final_result(&self, hash: &CryptoHash) -> FinalExecutionOutcomeView {
System::new("actix").block_on(self.client.write().unwrap().tx(hash.into())).unwrap()
}
fn get_state_root(&self) -> CryptoHash {
self.get_status().map(|status| status.sync_info.latest_state_root).unwrap()
}
fn get_access_key(
&self,
account_id: &AccountId,
public_key: &PublicKey,
) -> Result<Option<AccessKeyView>, String> {
self.query(format!("access_key/{}/{}", account_id, public_key), &[])?.try_into()
}
fn signer(&self) -> Arc<dyn Signer> {
self.signer.clone()
}
fn set_signer(&mut self, signer: Arc<dyn Signer>) {
self.signer = signer;
}
}