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
115
#![allow(dead_code)]
use crate::{blockchain::TransactionContext, contractapi::contractmanager::*};
use protobuf::{parse_from_bytes, Message};
use std::cell::RefCell;
use std::str;
extern crate wapc_guest as guest;
use guest::prelude::*;
use wapc_guest::console_log;
use fabric_ledger_protos::contract_messages::*;
use log::{debug, trace};
pub fn handle_wapc(operation: &str, msg: &[u8]) -> CallResult {
log(">> handle_wapc");
match operation {
"InvokeTransaction" => handle_tx_invoke(msg),
"GetMetadata" => todo!("GetMetadata"),
"RegisterPeer" => todo!("RegisterPeer"),
_ => Err("Unknown operation being called".into()),
}
}
#[inline(never)]
pub fn log(s: &str) {
console_log(s);
}
pub fn runtime_host_call(service: String, cmd: String, data: Vec<u8>) -> Result<Vec<u8>> {
trace!(
"Making host call {}::{}::len={}::",
service,
cmd,
data.len()
);
match host_call("wapc", &service[..], &cmd[..], &data) {
Ok(v) => Ok(v),
Err(e) => {
debug!("{:?}", e);
Err(e)
}
}
}
fn handle_tx_invoke(msg: &[u8]) -> CallResult {
trace!("handler_tx_invoke>>");
let invoke_request = parse_from_bytes::<InvokeTransactionRequest>(&msg).unwrap();
let fn_name = invoke_request.get_transaction_name();
let args = invoke_request.get_args();
let transient_args = invoke_request.get_transient_args();
let request_ctx = invoke_request.get_context();
set_context(TransactionContext::new(request_ctx));
let ctx = get_context();
trace!(
"making the routing call tx::{} fn::{}",
request_ctx.get_transaction_id(),
fn_name
);
let mut response_msg = InvokeTransactionResponse::new();
let ret = match ContractManager::route(&ctx, fn_name.to_string(), args, transient_args) {
Ok(r) => {
let buffer = match r.buffer {
Some(r) => r,
None => Vec::new(),
};
response_msg.set_payload(buffer)
}
Err(e) => response_msg.set_payload(e.to_string().into_bytes()),
};
let buffer: Vec<u8> = response_msg.write_to_bytes()?;
trace!("handler_tx_invoke<<");
Ok(buffer)
}
thread_local! {
pub static CONTEXT: RefCell<TransactionContext>
= RefCell::new( Default::default() );
}
fn set_context(name: TransactionContext) {
CONTEXT.with(|ctx| *ctx.borrow_mut() = name);
}
pub fn get_context() -> TransactionContext {
CONTEXT.with(|ctx| ctx.borrow().clone())
}