Skip to content

Commit

Permalink
Use mutable char to pass signature in ffi
Browse files Browse the repository at this point in the history
  • Loading branch information
Ma233 committed Oct 31, 2023
1 parent 19ad57b commit 8c16056
Show file tree
Hide file tree
Showing 4 changed files with 25 additions and 15 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/qaci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@ jobs:
python-version: "3.11"

- name: Smoke test
run: pip install wheel && pip install web3 cffi && python ffi/rings.py
run: pip install wheel && pip install web3 cffi && python examples/ffi/rings.py

rustfmt_and_clippy:
name: Check rustfmt style && run clippy
Expand Down
17 changes: 10 additions & 7 deletions ffi/rings.py → examples/ffi/rings.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
acc = w3.eth.account.create()

ffi = cffi.FFI()
c_header = open("./ffi/rings.h", "r").read()
c_header = open("./target/include/rings.h", "r").read()
c_header = re.sub(r"#define .*", "", c_header)
ffi.cdef(c_header)

Expand All @@ -22,22 +22,25 @@
extension = "so"


@ffi.callback("char*(*)(char *)")
def signer(msg):
@ffi.callback("void (*)(const char *, char *)")
def signer(msg, output):
c_input = ffi.string(msg)
decoded = encode_defunct(c_input)
sig = acc.sign_message(decoded)
ret = bytes(sig.signature)
return ffi.new("char[]", ret)
print("signature", sig.signature)
print("signature len", len(sig.signature))
ffi.memmove(output, sig.signature, len(sig.signature))
print("output", ffi.string(output))
return


@ffi.callback("void(*)(char *, char *)")
@ffi.callback("void(*)(const char *, const char *)")
def custom_msg_callback(msg):
print(msg)
return


@ffi.callback("void(*)(char *)")
@ffi.callback("void(*)(const char *)")
def builtin_msg_callback(msg):
print(msg)
return
Expand Down
4 changes: 2 additions & 2 deletions node/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,11 @@ fn gen_cbinding() {
.with_language(cbindgen::Language::C)
.with_no_includes()
.with_documentation(true)
.with_crate(crate_dir)
.with_crate(&crate_dir)
.generate()
{
Ok(g) => {
g.write_to_file("../ffi/rings.h");
g.write_to_file(crate_dir + "/../target/include/rings.h");
}
Err(e) => println!("Unable to generate bindings, {:?}", e),
};
Expand Down
17 changes: 12 additions & 5 deletions node/src/client/ffi.rs
Original file line number Diff line number Diff line change
Expand Up @@ -317,18 +317,25 @@ pub unsafe extern "C" fn new_client_with_callback(
stabilize_timeout: u32,
account: *const c_char,
account_type: *const c_char,
signer: extern "C" fn(*const c_char) -> *const c_char,
signer: extern "C" fn(*const c_char, *mut c_char) -> (),
callback_ptr: *const MessageCallbackInstanceFFI,
) -> ClientPtr {
fn wrapped_signer(
signer: extern "C" fn(*const c_char) -> *const c_char,
signer: extern "C" fn(*const c_char, *mut c_char) -> (),
) -> impl Fn(String) -> Vec<u8> {
move |data: String| -> Vec<u8> {
let c_data = CString::new(data).expect("Failed to convert String to CString");
let sig = signer(c_data.as_ptr());
let c_ret = c_char_to_bytes(sig).expect("Failed to convert c char to [u8]");

let mut sig = Vec::<u8>::with_capacity(65);
let sig_ptr = sig.as_mut_ptr() as *mut c_char;
signer(c_data.as_ptr(), sig_ptr);

let c_ret = c_char_to_bytes(sig_ptr).expect("Failed to convert c char to [u8]");
let c_ret_len = c_ret.len();
assert!(c_ret.len() >= 64, "sig length({c_ret_len} < 64) is invalid");
assert!(
c_ret.len() >= 64,
"sig length({c_ret_len} < 64) is invalid: {c_ret:?}"
);
c_ret
}
}
Expand Down

0 comments on commit 8c16056

Please sign in to comment.