1use std::{
2 borrow::{Borrow, Cow},
3 fmt::Display,
4 fs::File,
5 io::Read,
6 ops::Deref,
7 path::Path,
8};
9
10use blake3::{traits::digest::Digest, Hasher as Blake3};
11use serde::{Deserialize, Deserializer, Serialize};
12use serde_with::serde_as;
13
14use crate::generated::client_request::{
15 DelegateKey as FbsDelegateKey, InboundDelegateMsg as FbsInboundDelegateMsg,
16 InboundDelegateMsgType,
17};
18
19use crate::common_generated::common::SecretsId as FbsSecretsId;
20
21use crate::client_api::{TryFromFbs, WsApiError};
22use crate::prelude::{ContractInstanceId, WrappedState, CONTRACT_KEY_SIZE};
23use crate::{code_hash::CodeHash, prelude::Parameters};
24
25const DELEGATE_HASH_LENGTH: usize = 32;
26
27type Secret = Vec<u8>;
28
29#[derive(Clone, Debug, Serialize, Deserialize)]
30pub struct Delegate<'a> {
31 #[serde(borrow)]
32 parameters: Parameters<'a>,
33 #[serde(borrow)]
34 pub data: DelegateCode<'a>,
35 key: DelegateKey,
36}
37
38impl Delegate<'_> {
39 pub fn key(&self) -> &DelegateKey {
40 &self.key
41 }
42
43 pub fn code(&self) -> &DelegateCode<'_> {
44 &self.data
45 }
46
47 pub fn code_hash(&self) -> &CodeHash {
48 &self.data.code_hash
49 }
50
51 pub fn params(&self) -> &Parameters<'_> {
52 &self.parameters
53 }
54
55 pub fn into_owned(self) -> Delegate<'static> {
56 Delegate {
57 parameters: self.parameters.into_owned(),
58 data: self.data.into_owned(),
59 key: self.key,
60 }
61 }
62
63 pub fn size(&self) -> usize {
64 self.parameters.size() + self.data.size()
65 }
66
67 pub(crate) fn deserialize_delegate<'de, D>(deser: D) -> Result<Delegate<'static>, D::Error>
68 where
69 D: Deserializer<'de>,
70 {
71 let data: Delegate<'de> = Deserialize::deserialize(deser)?;
72 Ok(data.into_owned())
73 }
74}
75
76impl PartialEq for Delegate<'_> {
77 fn eq(&self, other: &Self) -> bool {
78 self.key == other.key
79 }
80}
81
82impl Eq for Delegate<'_> {}
83
84impl<'a> From<(&DelegateCode<'a>, &Parameters<'a>)> for Delegate<'a> {
85 fn from((data, parameters): (&DelegateCode<'a>, &Parameters<'a>)) -> Self {
86 Self {
87 key: DelegateKey::from_params_and_code(parameters, data),
88 parameters: parameters.clone(),
89 data: data.clone(),
90 }
91 }
92}
93
94#[derive(Debug, Serialize, Deserialize, Clone)]
96#[serde_as]
97pub struct DelegateCode<'a> {
98 #[serde_as(as = "serde_with::Bytes")]
99 #[serde(borrow)]
100 pub(crate) data: Cow<'a, [u8]>,
101 pub(crate) code_hash: CodeHash,
103}
104
105impl DelegateCode<'static> {
106 pub fn load_raw(path: &Path) -> Result<Self, std::io::Error> {
108 let contract_data = Self::load_bytes(path)?;
109 Ok(DelegateCode::from(contract_data))
110 }
111
112 pub(crate) fn load_bytes(path: &Path) -> Result<Vec<u8>, std::io::Error> {
113 let mut contract_file = File::open(path)?;
114 let mut contract_data = if let Ok(md) = contract_file.metadata() {
115 Vec::with_capacity(md.len() as usize)
116 } else {
117 Vec::new()
118 };
119 contract_file.read_to_end(&mut contract_data)?;
120 Ok(contract_data)
121 }
122}
123
124impl DelegateCode<'_> {
125 pub fn hash(&self) -> &CodeHash {
127 &self.code_hash
128 }
129
130 pub fn hash_str(&self) -> String {
132 Self::encode_hash(&self.code_hash.0)
133 }
134
135 pub fn data(&self) -> &[u8] {
137 &self.data
138 }
139
140 pub fn encode_hash(hash: &[u8; DELEGATE_HASH_LENGTH]) -> String {
142 bs58::encode(hash)
143 .with_alphabet(bs58::Alphabet::BITCOIN)
144 .into_string()
145 }
146
147 pub fn into_owned(self) -> DelegateCode<'static> {
148 DelegateCode {
149 code_hash: self.code_hash,
150 data: Cow::from(self.data.into_owned()),
151 }
152 }
153
154 pub fn size(&self) -> usize {
155 self.data.len()
156 }
157}
158
159impl PartialEq for DelegateCode<'_> {
160 fn eq(&self, other: &Self) -> bool {
161 self.code_hash == other.code_hash
162 }
163}
164
165impl Eq for DelegateCode<'_> {}
166
167impl AsRef<[u8]> for DelegateCode<'_> {
168 fn as_ref(&self) -> &[u8] {
169 self.data.borrow()
170 }
171}
172
173impl From<Vec<u8>> for DelegateCode<'static> {
174 fn from(data: Vec<u8>) -> Self {
175 let key = CodeHash::from_code(data.as_slice());
176 DelegateCode {
177 data: Cow::from(data),
178 code_hash: key,
179 }
180 }
181}
182
183impl<'a> From<&'a [u8]> for DelegateCode<'a> {
184 fn from(code: &'a [u8]) -> Self {
185 let key = CodeHash::from_code(code);
186 DelegateCode {
187 data: Cow::from(code),
188 code_hash: key,
189 }
190 }
191}
192
193#[serde_as]
194#[derive(Clone, PartialEq, Eq, Hash, Debug, Serialize, Deserialize)]
195pub struct DelegateKey {
196 #[serde_as(as = "[_; DELEGATE_HASH_LENGTH]")]
197 key: [u8; DELEGATE_HASH_LENGTH],
198 code_hash: CodeHash,
199}
200
201impl From<DelegateKey> for SecretsId {
202 fn from(key: DelegateKey) -> SecretsId {
203 SecretsId {
204 hash: key.key,
205 key: vec![],
206 }
207 }
208}
209
210impl DelegateKey {
211 pub const fn new(key: [u8; DELEGATE_HASH_LENGTH], code_hash: CodeHash) -> Self {
212 Self { key, code_hash }
213 }
214
215 fn from_params_and_code<'a>(
216 params: impl Borrow<Parameters<'a>>,
217 wasm_code: impl Borrow<DelegateCode<'a>>,
218 ) -> Self {
219 let code = wasm_code.borrow();
220 let key = generate_id(params.borrow(), code);
221 Self {
222 key,
223 code_hash: *code.hash(),
224 }
225 }
226
227 pub fn encode(&self) -> String {
228 bs58::encode(self.key)
229 .with_alphabet(bs58::Alphabet::BITCOIN)
230 .into_string()
231 }
232
233 pub fn code_hash(&self) -> &CodeHash {
234 &self.code_hash
235 }
236
237 pub fn bytes(&self) -> &[u8] {
238 self.key.as_ref()
239 }
240
241 pub fn from_params(
242 code_hash: impl Into<String>,
243 parameters: &Parameters,
244 ) -> Result<Self, bs58::decode::Error> {
245 let mut code_key = [0; DELEGATE_HASH_LENGTH];
246 bs58::decode(code_hash.into())
247 .with_alphabet(bs58::Alphabet::BITCOIN)
248 .onto(&mut code_key)?;
249 let mut hasher = Blake3::new();
250 hasher.update(code_key.as_slice());
251 hasher.update(parameters.as_ref());
252 let full_key_arr = hasher.finalize();
253
254 debug_assert_eq!(full_key_arr[..].len(), DELEGATE_HASH_LENGTH);
255 let mut key = [0; DELEGATE_HASH_LENGTH];
256 key.copy_from_slice(&full_key_arr);
257
258 Ok(Self {
259 key,
260 code_hash: CodeHash(code_key),
261 })
262 }
263}
264
265impl Deref for DelegateKey {
266 type Target = [u8; DELEGATE_HASH_LENGTH];
267
268 fn deref(&self) -> &Self::Target {
269 &self.key
270 }
271}
272
273impl Display for DelegateKey {
274 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
275 write!(f, "{}", self.encode())
276 }
277}
278
279impl<'a> TryFromFbs<&FbsDelegateKey<'a>> for DelegateKey {
280 fn try_decode_fbs(key: &FbsDelegateKey<'a>) -> Result<Self, WsApiError> {
281 let mut key_bytes = [0; DELEGATE_HASH_LENGTH];
282 key_bytes.copy_from_slice(key.key().bytes().iter().as_ref());
283 Ok(DelegateKey {
284 key: key_bytes,
285 code_hash: CodeHash::from_code(key.code_hash().bytes()),
286 })
287 }
288}
289
290#[derive(Debug, thiserror::Error, Serialize, Deserialize)]
292pub enum DelegateError {
293 #[error("de/serialization error: {0}")]
294 Deser(String),
295 #[error("{0}")]
296 Other(String),
297}
298
299fn generate_id<'a>(
300 parameters: &Parameters<'a>,
301 code_data: &DelegateCode<'a>,
302) -> [u8; DELEGATE_HASH_LENGTH] {
303 let contract_hash = code_data.hash();
304
305 let mut hasher = Blake3::new();
306 hasher.update(contract_hash.0.as_slice());
307 hasher.update(parameters.as_ref());
308 let full_key_arr = hasher.finalize();
309
310 debug_assert_eq!(full_key_arr[..].len(), DELEGATE_HASH_LENGTH);
311 let mut key = [0; DELEGATE_HASH_LENGTH];
312 key.copy_from_slice(&full_key_arr);
313 key
314}
315
316#[serde_as]
317#[derive(Clone, Serialize, Deserialize, Debug, PartialEq, Eq)]
318pub struct SecretsId {
319 #[serde_as(as = "serde_with::Bytes")]
320 key: Vec<u8>,
321 #[serde_as(as = "[_; 32]")]
322 hash: [u8; 32],
323}
324
325impl SecretsId {
326 pub fn new(key: Vec<u8>) -> Self {
327 let mut hasher = Blake3::new();
328 hasher.update(&key);
329 let hashed = hasher.finalize();
330 let mut hash = [0; 32];
331 hash.copy_from_slice(&hashed);
332 Self { key, hash }
333 }
334
335 pub fn encode(&self) -> String {
336 bs58::encode(self.hash)
337 .with_alphabet(bs58::Alphabet::BITCOIN)
338 .into_string()
339 }
340
341 pub fn hash(&self) -> &[u8; 32] {
342 &self.hash
343 }
344 pub fn key(&self) -> &[u8] {
345 self.key.as_slice()
346 }
347}
348
349impl Display for SecretsId {
350 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
351 write!(f, "{}", self.encode())
352 }
353}
354
355impl<'a> TryFromFbs<&FbsSecretsId<'a>> for SecretsId {
356 fn try_decode_fbs(key: &FbsSecretsId<'a>) -> Result<Self, WsApiError> {
357 let mut key_hash = [0; 32];
358 key_hash.copy_from_slice(key.hash().bytes().iter().as_ref());
359 Ok(SecretsId {
360 key: key.key().bytes().to_vec(),
361 hash: key_hash,
362 })
363 }
364}
365
366pub trait DelegateInterface {
411 fn process(
422 ctx: &mut crate::delegate_host::DelegateCtx,
423 parameters: Parameters<'static>,
424 attested: Option<&'static [u8]>,
425 message: InboundDelegateMsg,
426 ) -> Result<Vec<OutboundDelegateMsg>, DelegateError>;
427}
428
429#[serde_as]
430#[derive(Debug, Clone, Default, Serialize, Deserialize, PartialEq, Eq)]
431pub struct DelegateContext(#[serde_as(as = "serde_with::Bytes")] Vec<u8>);
432
433impl DelegateContext {
434 pub const MAX_SIZE: usize = 4096 * 10 * 10;
435
436 pub fn new(bytes: Vec<u8>) -> Self {
437 assert!(bytes.len() < Self::MAX_SIZE);
438 Self(bytes)
439 }
440
441 pub fn append(&mut self, bytes: &mut Vec<u8>) {
442 assert!(self.0.len() + bytes.len() < Self::MAX_SIZE);
443 self.0.append(bytes)
444 }
445
446 pub fn replace(&mut self, bytes: Vec<u8>) {
447 assert!(bytes.len() < Self::MAX_SIZE);
448 let _ = std::mem::replace(&mut self.0, bytes);
449 }
450}
451
452impl AsRef<[u8]> for DelegateContext {
453 fn as_ref(&self) -> &[u8] {
454 &self.0
455 }
456}
457
458#[derive(Serialize, Deserialize, Debug, Clone)]
459pub enum InboundDelegateMsg<'a> {
460 ApplicationMessage(ApplicationMessage),
461 GetSecretResponse(GetSecretResponse),
462 UserResponse(#[serde(borrow)] UserInputResponse<'a>),
463 GetSecretRequest(GetSecretRequest),
464 GetContractResponse(GetContractResponse),
465}
466
467impl InboundDelegateMsg<'_> {
468 pub fn into_owned(self) -> InboundDelegateMsg<'static> {
469 match self {
470 InboundDelegateMsg::ApplicationMessage(r) => InboundDelegateMsg::ApplicationMessage(r),
471 InboundDelegateMsg::GetSecretResponse(r) => InboundDelegateMsg::GetSecretResponse(r),
472 InboundDelegateMsg::UserResponse(r) => InboundDelegateMsg::UserResponse(r.into_owned()),
473 InboundDelegateMsg::GetSecretRequest(r) => InboundDelegateMsg::GetSecretRequest(r),
474 InboundDelegateMsg::GetContractResponse(r) => {
475 InboundDelegateMsg::GetContractResponse(r)
476 }
477 }
478 }
479
480 pub fn get_context(&self) -> Option<&DelegateContext> {
481 match self {
482 InboundDelegateMsg::ApplicationMessage(ApplicationMessage { context, .. }) => {
483 Some(context)
484 }
485 InboundDelegateMsg::GetSecretResponse(GetSecretResponse { context, .. }) => {
486 Some(context)
487 }
488 InboundDelegateMsg::GetContractResponse(GetContractResponse { context, .. }) => {
489 Some(context)
490 }
491 _ => None,
492 }
493 }
494
495 pub fn get_mut_context(&mut self) -> Option<&mut DelegateContext> {
496 match self {
497 InboundDelegateMsg::ApplicationMessage(ApplicationMessage { context, .. }) => {
498 Some(context)
499 }
500 InboundDelegateMsg::GetSecretResponse(GetSecretResponse { context, .. }) => {
501 Some(context)
502 }
503 InboundDelegateMsg::GetContractResponse(GetContractResponse { context, .. }) => {
504 Some(context)
505 }
506 _ => None,
507 }
508 }
509}
510
511impl From<GetSecretRequest> for InboundDelegateMsg<'_> {
512 fn from(value: GetSecretRequest) -> Self {
513 Self::GetSecretRequest(value)
514 }
515}
516
517impl From<ApplicationMessage> for InboundDelegateMsg<'_> {
518 fn from(value: ApplicationMessage) -> Self {
519 Self::ApplicationMessage(value)
520 }
521}
522
523impl<'a> TryFromFbs<&FbsInboundDelegateMsg<'a>> for InboundDelegateMsg<'a> {
524 fn try_decode_fbs(msg: &FbsInboundDelegateMsg<'a>) -> Result<Self, WsApiError> {
525 match msg.inbound_type() {
526 InboundDelegateMsgType::common_ApplicationMessage => {
527 let app_msg = msg.inbound_as_common_application_message().unwrap();
528 let mut instance_key_bytes = [0; CONTRACT_KEY_SIZE];
529 instance_key_bytes
530 .copy_from_slice(app_msg.app().data().bytes().to_vec().as_slice());
531 let app_msg = ApplicationMessage {
532 app: ContractInstanceId::new(instance_key_bytes),
533 payload: app_msg.payload().bytes().to_vec(),
534 context: DelegateContext::new(app_msg.context().bytes().to_vec()),
535 processed: app_msg.processed(),
536 };
537 Ok(InboundDelegateMsg::ApplicationMessage(app_msg))
538 }
539 InboundDelegateMsgType::common_GetSecretResponse => {
540 let get_secret = msg.inbound_as_common_get_secret_response().unwrap();
541 let get_secret = GetSecretResponse {
542 key: SecretsId::try_decode_fbs(&get_secret.key())?,
543 value: get_secret.value().map(|value| value.bytes().to_vec()),
544 context: DelegateContext::new(get_secret.delegate_context().bytes().to_vec()),
545 };
546 Ok(InboundDelegateMsg::GetSecretResponse(get_secret))
547 }
548 InboundDelegateMsgType::UserInputResponse => {
549 let user_response = msg.inbound_as_user_input_response().unwrap();
550 let user_response = UserInputResponse {
551 request_id: user_response.request_id(),
552 response: ClientResponse::new(user_response.response().data().bytes().to_vec()),
553 context: DelegateContext::new(
554 user_response.delegate_context().bytes().to_vec(),
555 ),
556 };
557 Ok(InboundDelegateMsg::UserResponse(user_response))
558 }
559 InboundDelegateMsgType::common_GetSecretRequest => {
560 let get_secret = msg.inbound_as_common_get_secret_request().unwrap();
561 let get_secret = GetSecretRequest {
562 key: SecretsId::try_decode_fbs(&get_secret.key())?,
563 context: DelegateContext::new(get_secret.delegate_context().bytes().to_vec()),
564 processed: get_secret.processed(),
565 };
566 Ok(InboundDelegateMsg::GetSecretRequest(get_secret))
567 }
568 _ => unreachable!("invalid inbound delegate message type"),
569 }
570 }
571}
572
573#[derive(Serialize, Deserialize, Debug, Clone)]
574pub struct GetSecretResponse {
575 pub key: SecretsId,
576 pub value: Option<Secret>,
577 pub context: DelegateContext,
578}
579
580#[non_exhaustive]
581#[derive(Serialize, Deserialize, Debug, Clone)]
582pub struct ApplicationMessage {
583 pub app: ContractInstanceId,
584 pub payload: Vec<u8>,
585 pub context: DelegateContext,
586 pub processed: bool,
587}
588
589impl ApplicationMessage {
590 pub fn new(app: ContractInstanceId, payload: Vec<u8>) -> Self {
591 Self {
592 app,
593 payload,
594 context: DelegateContext::default(),
595 processed: false,
596 }
597 }
598
599 pub fn with_context(mut self, context: DelegateContext) -> Self {
600 self.context = context;
601 self
602 }
603
604 pub fn processed(mut self, p: bool) -> Self {
605 self.processed = p;
606 self
607 }
608}
609
610#[derive(Serialize, Deserialize, Debug, Clone)]
611pub struct UserInputResponse<'a> {
612 pub request_id: u32,
613 #[serde(borrow)]
614 pub response: ClientResponse<'a>,
615 pub context: DelegateContext,
616}
617
618impl UserInputResponse<'_> {
619 pub fn into_owned(self) -> UserInputResponse<'static> {
620 UserInputResponse {
621 request_id: self.request_id,
622 response: self.response.into_owned(),
623 context: self.context,
624 }
625 }
626}
627
628#[derive(Serialize, Deserialize, Debug, Clone)]
629pub enum OutboundDelegateMsg {
630 ApplicationMessage(ApplicationMessage),
632 RequestUserInput(
633 #[serde(deserialize_with = "OutboundDelegateMsg::deser_user_input_req")]
634 UserInputRequest<'static>,
635 ),
636 ContextUpdated(DelegateContext),
638 GetSecretRequest(GetSecretRequest),
640 SetSecretRequest(SetSecretRequest),
641 GetContractRequest(GetContractRequest),
642 GetSecretResponse(GetSecretResponse),
643}
644
645impl From<GetSecretRequest> for OutboundDelegateMsg {
646 fn from(req: GetSecretRequest) -> Self {
647 Self::GetSecretRequest(req)
648 }
649}
650
651impl From<ApplicationMessage> for OutboundDelegateMsg {
652 fn from(req: ApplicationMessage) -> Self {
653 Self::ApplicationMessage(req)
654 }
655}
656
657impl From<GetContractRequest> for OutboundDelegateMsg {
658 fn from(req: GetContractRequest) -> Self {
659 Self::GetContractRequest(req)
660 }
661}
662
663impl OutboundDelegateMsg {
664 fn deser_user_input_req<'de, D>(deser: D) -> Result<UserInputRequest<'static>, D::Error>
665 where
666 D: serde::Deserializer<'de>,
667 {
668 let value = <UserInputRequest<'de> as Deserialize>::deserialize(deser)?;
669 Ok(value.into_owned())
670 }
671
672 pub fn processed(&self) -> bool {
673 match self {
674 OutboundDelegateMsg::ApplicationMessage(msg) => msg.processed,
675 OutboundDelegateMsg::GetSecretRequest(msg) => msg.processed,
676 OutboundDelegateMsg::GetContractRequest(msg) => msg.processed,
677 OutboundDelegateMsg::SetSecretRequest(_) => false,
678 OutboundDelegateMsg::RequestUserInput(_) => true,
679 OutboundDelegateMsg::ContextUpdated(_) => true,
680 OutboundDelegateMsg::GetSecretResponse(_) => true,
681 }
682 }
683
684 pub fn get_context(&self) -> Option<&DelegateContext> {
685 match self {
686 OutboundDelegateMsg::ApplicationMessage(ApplicationMessage { context, .. }) => {
687 Some(context)
688 }
689 OutboundDelegateMsg::GetSecretRequest(GetSecretRequest { context, .. }) => {
690 Some(context)
691 }
692 OutboundDelegateMsg::GetContractRequest(GetContractRequest { context, .. }) => {
693 Some(context)
694 }
695 _ => None,
696 }
697 }
698
699 pub fn get_mut_context(&mut self) -> Option<&mut DelegateContext> {
700 match self {
701 OutboundDelegateMsg::ApplicationMessage(ApplicationMessage { context, .. }) => {
702 Some(context)
703 }
704 OutboundDelegateMsg::GetSecretRequest(GetSecretRequest { context, .. }) => {
705 Some(context)
706 }
707 OutboundDelegateMsg::GetContractRequest(GetContractRequest { context, .. }) => {
708 Some(context)
709 }
710 _ => None,
711 }
712 }
713}
714
715#[derive(Serialize, Deserialize, Debug, Clone)]
716pub struct GetSecretRequest {
717 pub key: SecretsId,
718 pub context: DelegateContext,
719 pub processed: bool,
720}
721
722impl GetSecretRequest {
723 pub fn new(key: SecretsId) -> Self {
724 Self {
725 key,
726 context: Default::default(),
727 processed: false,
728 }
729 }
730}
731
732#[derive(Serialize, Deserialize, Debug, Clone)]
733pub struct SetSecretRequest {
734 pub key: SecretsId,
735 pub value: Option<Secret>,
737}
738
739#[derive(Serialize, Deserialize, Debug, Clone)]
741pub struct GetContractRequest {
742 pub contract_id: ContractInstanceId,
743 pub context: DelegateContext,
744 pub processed: bool,
745}
746
747impl GetContractRequest {
748 pub fn new(contract_id: ContractInstanceId) -> Self {
749 Self {
750 contract_id,
751 context: Default::default(),
752 processed: false,
753 }
754 }
755}
756
757#[derive(Serialize, Deserialize, Debug, Clone)]
759pub struct GetContractResponse {
760 pub contract_id: ContractInstanceId,
761 pub state: Option<WrappedState>,
763 pub context: DelegateContext,
764}
765
766#[serde_as]
767#[derive(Serialize, Deserialize, Debug, Clone)]
768pub struct NotificationMessage<'a>(
769 #[serde_as(as = "serde_with::Bytes")]
770 #[serde(borrow)]
771 Cow<'a, [u8]>,
772);
773
774impl TryFrom<&serde_json::Value> for NotificationMessage<'static> {
775 type Error = ();
776
777 fn try_from(json: &serde_json::Value) -> Result<NotificationMessage<'static>, ()> {
778 let bytes = serde_json::to_vec(json).unwrap();
780 Ok(Self(Cow::Owned(bytes)))
781 }
782}
783
784impl NotificationMessage<'_> {
785 pub fn into_owned(self) -> NotificationMessage<'static> {
786 NotificationMessage(self.0.into_owned().into())
787 }
788 pub fn bytes(&self) -> &[u8] {
789 self.0.as_ref()
790 }
791}
792
793#[serde_as]
794#[derive(Serialize, Deserialize, Debug, Clone)]
795pub struct ClientResponse<'a>(
796 #[serde_as(as = "serde_with::Bytes")]
797 #[serde(borrow)]
798 Cow<'a, [u8]>,
799);
800
801impl Deref for ClientResponse<'_> {
802 type Target = [u8];
803
804 fn deref(&self) -> &Self::Target {
805 &self.0
806 }
807}
808
809impl ClientResponse<'_> {
810 pub fn new(response: Vec<u8>) -> Self {
811 Self(response.into())
812 }
813 pub fn into_owned(self) -> ClientResponse<'static> {
814 ClientResponse(self.0.into_owned().into())
815 }
816 pub fn bytes(&self) -> &[u8] {
817 self.0.as_ref()
818 }
819}
820
821#[derive(Serialize, Deserialize, Debug, Clone)]
822pub struct UserInputRequest<'a> {
823 pub request_id: u32,
824 #[serde(borrow)]
825 pub message: NotificationMessage<'a>,
827 pub responses: Vec<ClientResponse<'a>>,
829}
830
831impl UserInputRequest<'_> {
832 pub fn into_owned(self) -> UserInputRequest<'static> {
833 UserInputRequest {
834 request_id: self.request_id,
835 message: self.message.into_owned(),
836 responses: self.responses.into_iter().map(|r| r.into_owned()).collect(),
837 }
838 }
839}
840
841#[doc(hidden)]
842pub(crate) mod wasm_interface {
843 use super::*;
846 use crate::memory::WasmLinearMem;
847
848 #[repr(C)]
849 #[derive(Debug, Clone, Copy)]
850 pub struct DelegateInterfaceResult {
851 ptr: i64,
852 size: u32,
853 }
854
855 impl DelegateInterfaceResult {
856 pub unsafe fn from_raw(ptr: i64, mem: &WasmLinearMem) -> Self {
857 let result = Box::leak(Box::from_raw(crate::memory::buf::compute_ptr(
858 ptr as *mut Self,
859 mem,
860 )));
861 #[cfg(feature = "trace")]
862 {
863 tracing::trace!(
864 "got FFI result @ {ptr} ({:p}) -> {result:?}",
865 ptr as *mut Self
866 );
867 }
868 *result
869 }
870
871 #[cfg(feature = "contract")]
872 pub fn into_raw(self) -> i64 {
873 #[cfg(feature = "trace")]
874 {
875 tracing::trace!("returning FFI -> {self:?}");
876 }
877 let ptr = Box::into_raw(Box::new(self));
878 #[cfg(feature = "trace")]
879 {
880 tracing::trace!("FFI result ptr: {ptr:p} ({}i64)", ptr as i64);
881 }
882 ptr as _
883 }
884
885 pub unsafe fn unwrap(
886 self,
887 mem: WasmLinearMem,
888 ) -> Result<Vec<OutboundDelegateMsg>, DelegateError> {
889 let ptr = crate::memory::buf::compute_ptr(self.ptr as *mut u8, &mem);
890 let serialized = std::slice::from_raw_parts(ptr as *const u8, self.size as _);
891 let value: Result<Vec<OutboundDelegateMsg>, DelegateError> =
892 bincode::deserialize(serialized)
893 .map_err(|e| DelegateError::Other(format!("{e}")))?;
894 #[cfg(feature = "trace")]
895 {
896 tracing::trace!(
897 "got result through FFI; addr: {:p} ({}i64, mapped: {ptr:p})
898 serialized: {serialized:?}
899 value: {value:?}",
900 self.ptr as *mut u8,
901 self.ptr
902 );
903 }
904 value
905 }
906 }
907
908 impl From<Result<Vec<OutboundDelegateMsg>, DelegateError>> for DelegateInterfaceResult {
909 fn from(value: Result<Vec<OutboundDelegateMsg>, DelegateError>) -> Self {
910 let serialized = bincode::serialize(&value).unwrap();
911 let size = serialized.len() as _;
912 let ptr = serialized.as_ptr();
913 #[cfg(feature = "trace")]
914 {
915 tracing::trace!(
916 "sending result through FFI; addr: {ptr:p} ({}),\n serialized: {serialized:?}\n value: {value:?}",
917 ptr as i64
918 );
919 }
920 std::mem::forget(serialized);
921 Self {
922 ptr: ptr as i64,
923 size,
924 }
925 }
926 }
927}