@@ -6451,8 +6451,8 @@ fn link_contract_call_fn(linker: &mut Linker<ClarityWasmContext>) -> Result<(),
6451
6451
"clarity" ,
6452
6452
"contract_call" ,
6453
6453
|mut caller : Caller < ' _ , ClarityWasmContext > ,
6454
- trait_name_offset : i32 ,
6455
- trait_name_length : i32 ,
6454
+ trait_id_offset : i32 ,
6455
+ trait_id_length : i32 ,
6456
6456
contract_offset : i32 ,
6457
6457
contract_length : i32 ,
6458
6458
function_offset : i32 ,
@@ -6499,7 +6499,7 @@ fn link_contract_call_fn(linker: &mut Linker<ClarityWasmContext>) -> Result<(),
6499
6499
) ?;
6500
6500
6501
6501
// Retrieve the contract context for the contract we're calling
6502
- let contract = caller
6502
+ let mut contract = caller
6503
6503
. data_mut ( )
6504
6504
. global_context
6505
6505
. database
@@ -6568,30 +6568,34 @@ fn link_contract_call_fn(linker: &mut Linker<ClarityWasmContext>) -> Result<(),
6568
6568
} ?;
6569
6569
6570
6570
// Write the result to the return buffer
6571
- let return_ty = if trait_name_length == 0 {
6571
+ let return_ty = if trait_id_length == 0 {
6572
6572
// This is a direct call
6573
- function. get_return_type ( ) . as_ref ( )
6573
+ function
6574
+ . get_return_type ( )
6575
+ . as_ref ( )
6576
+ . ok_or ( CheckErrors :: DefineFunctionBadSignature ) ?
6574
6577
} else {
6575
6578
// This is a dynamic call
6576
- let trait_name = read_identifier_from_wasm (
6577
- memory,
6578
- & mut caller,
6579
- trait_name_offset,
6580
- trait_name_length,
6581
- ) ?;
6579
+ let trait_id =
6580
+ read_bytes_from_wasm ( memory, & mut caller, trait_id_offset, trait_id_length)
6581
+ . and_then ( |bs| trait_identifier_from_bytes ( & bs) ) ?;
6582
+ contract = if & trait_id. contract_identifier == contract_id {
6583
+ contract
6584
+ } else {
6585
+ caller
6586
+ . data_mut ( )
6587
+ . global_context
6588
+ . database
6589
+ . get_contract ( & trait_id. contract_identifier ) ?
6590
+ } ;
6582
6591
contract
6583
6592
. contract_context
6584
6593
. defined_traits
6585
- . get ( trait_name . as_str ( ) )
6594
+ . get ( trait_id . name . as_str ( ) )
6586
6595
. and_then ( |trait_functions| trait_functions. get ( function_name. as_str ( ) ) )
6587
6596
. map ( |f_ty| & f_ty. returns )
6588
- }
6589
- . ok_or ( CheckErrors :: DefineFunctionBadSignature ) ?;
6590
-
6591
- let memory = caller
6592
- . get_export ( "memory" )
6593
- . and_then ( |export| export. into_memory ( ) )
6594
- . ok_or ( Error :: Wasm ( WasmError :: MemoryNotFound ) ) ?;
6597
+ . ok_or ( CheckErrors :: DefineFunctionBadSignature ) ?
6598
+ } ;
6595
6599
6596
6600
write_to_wasm (
6597
6601
& mut caller,
@@ -7376,6 +7380,43 @@ fn link_debug_msg<T>(linker: &mut Linker<T>) -> Result<(), Error> {
7376
7380
} )
7377
7381
}
7378
7382
7383
+ /// Tries to deserialize bytes into a [TraitIdentifier]. The bytes should have the following format:
7384
+ /// issuer principal as 21 bytes + contract name length as byte + contract name as bytes + trait name length as byte + trait name as bytes
7385
+ ///
7386
+ /// This is a duplication of the function defined in clarity-wasm due to the duplication issue.
7387
+ pub fn trait_identifier_from_bytes ( bytes : & [ u8 ] ) -> Result < TraitIdentifier , Error > {
7388
+ let not_enough_bytes = || {
7389
+ Error :: Wasm ( WasmError :: Expect (
7390
+ "Not enough bytes for a trait deserialization" . to_owned ( ) ,
7391
+ ) )
7392
+ } ;
7393
+
7394
+ // deserilize issuer
7395
+ let ( version, bytes) = bytes. split_first ( ) . ok_or_else ( not_enough_bytes) ?;
7396
+ let ( issuer_bytes, bytes) = bytes. split_at_checked ( 20 ) . ok_or_else ( not_enough_bytes) ?;
7397
+ let issuer = StandardPrincipalData :: new ( * version, issuer_bytes. try_into ( ) . unwrap ( ) ) ?;
7398
+
7399
+ // deserialize contract name
7400
+ let ( contract_name_len, bytes) = bytes. split_first ( ) . ok_or_else ( not_enough_bytes) ?;
7401
+ let ( contract_name_bytes, bytes) = bytes
7402
+ . split_at_checked ( * contract_name_len as usize )
7403
+ . ok_or_else ( not_enough_bytes) ?;
7404
+ let contract_name: ContractName = String :: from_utf8 ( contract_name_bytes. to_owned ( ) )
7405
+ . map_err ( |err| Error :: Wasm ( WasmError :: UnableToReadIdentifier ( err) ) ) ?
7406
+ . try_into ( ) ?;
7407
+
7408
+ // deserialize trait name
7409
+ let ( trait_name_len, bytes) = bytes. split_first ( ) . ok_or_else ( not_enough_bytes) ?;
7410
+ if bytes. len ( ) != * trait_name_len as usize {
7411
+ return Err ( not_enough_bytes ( ) ) ;
7412
+ }
7413
+ let trait_name: ClarityName = String :: from_utf8 ( bytes. to_owned ( ) )
7414
+ . map_err ( |err| Error :: Wasm ( WasmError :: UnableToReadIdentifier ( err) ) ) ?
7415
+ . try_into ( ) ?;
7416
+
7417
+ Ok ( TraitIdentifier :: new ( issuer, contract_name, trait_name) )
7418
+ }
7419
+
7379
7420
#[ cfg( test) ]
7380
7421
mod tests {
7381
7422
use wasmtime:: * ;
0 commit comments