Skip to main content

dusk_stake_contract_dd/
lib.rs

1// This Source Code Form is subject to the terms of the Mozilla Public
2// License, v. 2.0. If a copy of the MPL was not distributed with this
3// file, You can obtain one at http://mozilla.org/MPL/2.0/.
4//
5// Copyright (c) DUSK NETWORK. All rights reserved.
6
7//! This crate provides a data driver implementation for dusk stake contract.
8
9#![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/// The contract driver for encoding and decoding transactions.
35#[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            // Transactions
48            "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            // Queries (TBD)
55            "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            // Unsupported
62            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            // Transactions
73            "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            // Queries (TBD)
80            "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            // Unsupported
87            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            // Transactions
98            "stake"
99            | "unstake"
100            | "withdraw"
101            | "stake_from_contract"
102            | "unstake_from_contract"
103            | "withdraw_from_contract" => Ok(JsonValue::Null),
104            // Queries (TBD)
105            "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            // Unsupported
116            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);