@@ -6451,8 +6451,8 @@ fn link_contract_call_fn(linker: &mut Linker<ClarityWasmContext>) -> Result<(),
64516451 "clarity" ,
64526452 "contract_call" ,
64536453 |mut caller : Caller < ' _ , ClarityWasmContext > ,
6454- trait_name_offset : i32 ,
6455- trait_name_length : i32 ,
6454+ trait_id_offset : i32 ,
6455+ trait_id_length : i32 ,
64566456 contract_offset : i32 ,
64576457 contract_length : i32 ,
64586458 function_offset : i32 ,
@@ -6499,7 +6499,7 @@ fn link_contract_call_fn(linker: &mut Linker<ClarityWasmContext>) -> Result<(),
64996499 ) ?;
65006500
65016501 // Retrieve the contract context for the contract we're calling
6502- let contract = caller
6502+ let mut contract = caller
65036503 . data_mut ( )
65046504 . global_context
65056505 . database
@@ -6568,30 +6568,34 @@ fn link_contract_call_fn(linker: &mut Linker<ClarityWasmContext>) -> Result<(),
65686568 } ?;
65696569
65706570 // 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 {
65726572 // 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 ) ?
65746577 } else {
65756578 // 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+ } ;
65826591 contract
65836592 . contract_context
65846593 . defined_traits
6585- . get ( trait_name . as_str ( ) )
6594+ . get ( trait_id . name . as_str ( ) )
65866595 . and_then ( |trait_functions| trait_functions. get ( function_name. as_str ( ) ) )
65876596 . 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+ } ;
65956599
65966600 write_to_wasm (
65976601 & mut caller,
@@ -7376,6 +7380,43 @@ fn link_debug_msg<T>(linker: &mut Linker<T>) -> Result<(), Error> {
73767380 } )
73777381}
73787382
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+
73797420#[ cfg( test) ]
73807421mod tests {
73817422 use wasmtime:: * ;
0 commit comments