1#![no_std]
10#![deny(missing_docs)]
11#![deny(rustdoc::broken_intra_doc_links)]
12#![deny(clippy::pedantic)]
13#![allow(clippy::module_name_repetitions)]
14#![deny(unused_crate_dependencies)]
15#![deny(unused_extern_crates)]
16
17extern crate alloc;
18
19use alloc::format;
20use alloc::string::String;
21use alloc::vec::Vec;
22
23use dusk_core::signatures::bls::PublicKey as BlsPublicKey;
24use dusk_core::stake::{
25 Reward, SlashEvent, Stake, StakeConfig, StakeData, StakeEvent, StakeKeys,
26 Withdraw, WithdrawToContract,
27};
28use dusk_core::transfer::ReceiveFromContract;
29use dusk_data_driver::{
30 json_to_rkyv, rkyv_to_json, rkyv_to_json_u64, ConvertibleContract, Error,
31 JsonValue,
32};
33
34#[derive(Default)]
36pub struct ContractDriver;
37
38const STAKE_SCHEMA: &str = r#"{"name":"StakeContract","imports":[],"functions":[{"name":"stake","doc":"","input":"Stake","output":"()","custom":false},{"name":"unstake","doc":"","input":"Withdraw","output":"()","custom":false},{"name":"withdraw","doc":"","input":"Withdraw","output":"()","custom":false},{"name":"stake_from_contract","doc":"","input":"ReceiveFromContract","output":"()","custom":false},{"name":"unstake_from_contract","doc":"","input":"WithdrawToContract","output":"()","custom":false},{"name":"withdraw_from_contract","doc":"","input":"WithdrawToContract","output":"()","custom":false},{"name":"get_stake","doc":"","input":"BlsPublicKey","output":"Option<StakeData>","custom":false},{"name":"get_stake_keys","doc":"","input":"BlsPublicKey","output":"Option<StakeKeys>","custom":false},{"name":"burnt_amount","doc":"","input":"()","output":"u64","custom":false},{"name":"get_version","doc":"","input":"()","output":"u64","custom":false},{"name":"get_config","doc":"","input":"()","output":"StakeConfig","custom":false},{"name":"stakes","doc":"","input":"()","output":"(StakeKeys,StakeData)","custom":false},{"name":"prev_state_changes","doc":"","input":"()","output":"(BlsPublicKey,Option<StakeData>)","custom":false}],"events":[{"topic":"stake","data":"StakeEvent"},{"topic":"unstake","data":"StakeEvent"},{"topic":"withdraw","data":"StakeEvent"},{"topic":"reward","data":"Vec<Reward>"},{"topic":"slash","data":"SlashEvent"},{"topic":"hard_slash","data":"SlashEvent"}]}"#;
39
40impl ConvertibleContract for ContractDriver {
41 fn encode_input_fn(
42 &self,
43 fn_name: &str,
44 json: &str,
45 ) -> Result<Vec<u8>, Error> {
46 match fn_name {
47 "stake" => json_to_rkyv::<Stake>(json),
49 "unstake" | "withdraw" => json_to_rkyv::<Withdraw>(json),
50 "stake_from_contract" => json_to_rkyv::<ReceiveFromContract>(json),
51 "unstake_from_contract" | "withdraw_from_contract" => {
52 json_to_rkyv::<WithdrawToContract>(json)
53 }
54 "get_stake" | "get_stake_keys" => {
56 json_to_rkyv::<BlsPublicKey>(json)
57 }
58 "burnt_amount" | "get_version" | "get_config" | "stakes"
59 | "prev_state_changes" => json_to_rkyv::<()>("null"),
60
61 name => Err(Error::Unsupported(format!("fn_name {name}"))),
63 }
64 }
65
66 fn decode_input_fn(
67 &self,
68 fn_name: &str,
69 rkyv: &[u8],
70 ) -> Result<JsonValue, Error> {
71 match fn_name {
72 "stake" => rkyv_to_json::<Stake>(rkyv),
74 "unstake" | "withdraw" => rkyv_to_json::<Withdraw>(rkyv),
75 "stake_from_contract" => rkyv_to_json::<ReceiveFromContract>(rkyv),
76 "unstake_from_contract" | "withdraw_from_contract" => {
77 rkyv_to_json::<WithdrawToContract>(rkyv)
78 }
79 "get_stake" | "get_stake_keys" => {
81 rkyv_to_json::<BlsPublicKey>(rkyv)
82 }
83 "burnt_amount" | "get_version" | "get_config" | "stakes"
84 | "prev_state_changes" => rkyv_to_json::<()>(rkyv),
85
86 name => Err(Error::Unsupported(format!("fn_name {name}"))),
88 }
89 }
90
91 fn decode_output_fn(
92 &self,
93 fn_name: &str,
94 rkyv: &[u8],
95 ) -> Result<JsonValue, Error> {
96 match fn_name {
97 "stake"
99 | "unstake"
100 | "withdraw"
101 | "stake_from_contract"
102 | "unstake_from_contract"
103 | "withdraw_from_contract" => Ok(JsonValue::Null),
104 "get_stake" => rkyv_to_json::<Option<StakeData>>(rkyv),
106 "get_stake_keys" => rkyv_to_json::<Option<StakeKeys>>(rkyv),
107 "burnt_amount" | "get_version" => rkyv_to_json_u64(rkyv),
108 "get_config" => rkyv_to_json::<StakeConfig>(rkyv),
109
110 "stakes" => rkyv_to_json::<(StakeKeys, StakeData)>(rkyv),
111 "prev_state_changes" => {
112 rkyv_to_json::<(BlsPublicKey, Option<StakeData>)>(rkyv)
113 }
114
115 name => Err(Error::Unsupported(format!("fn_name {name}"))),
117 }
118 }
119
120 fn decode_event(
121 &self,
122 event_name: &str,
123 rkyv: &[u8],
124 ) -> Result<JsonValue, Error> {
125 match event_name {
126 "stake" | "unstake" | "withdraw" => {
127 rkyv_to_json::<StakeEvent>(rkyv)
128 }
129 "reward" => rkyv_to_json::<Vec<Reward>>(rkyv),
130 "slash" | "hard_slash" => rkyv_to_json::<SlashEvent>(rkyv),
131 event => Err(Error::Unsupported(format!("event {event}"))),
132 }
133 }
134
135 fn get_schema(&self) -> String {
136 STAKE_SCHEMA.into()
137 }
138}
139
140#[cfg(all(target_family = "wasm", feature = "ffi"))]
141dusk_data_driver::generate_wasm_entrypoint!(ContractDriver);