NIF goodness!

This commit is contained in:
John Newby 2019-08-05 15:05:14 +02:00
parent 74e20f3a9d
commit e6e6b94b5b
3 changed files with 45 additions and 19 deletions

View File

@ -7,6 +7,7 @@ edition = "2018"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies] [dependencies]
base64 = "0.10.1"
c_vec = "1.3.3" c_vec = "1.3.3"
ethcore-builtin = { path = "../parity-ethereum/ethcore/builtin" } ethcore-builtin = { path = "../parity-ethereum/ethcore/builtin" }
lazy_static = "1.3.0" lazy_static = "1.3.0"

View File

@ -13,6 +13,8 @@ use crate::ethcore_builtin::Implementation;
use c_vec::{CVec}; use c_vec::{CVec};
use parity_bytes::BytesRef; use parity_bytes::BytesRef;
use rustler::*; use rustler::*;
use rustler::types::atom::ok;
use std::io::Write;
use std::ptr::copy_nonoverlapping; use std::ptr::copy_nonoverlapping;
const INPUT_LENGTH: usize = 512; const INPUT_LENGTH: usize = 512;
@ -27,37 +29,27 @@ mod atoms {
rustler_export_nifs!( rustler_export_nifs!(
"nifecrecover", "nifecrecover",
[ [
("ecrecover", 2, nif_ecrecover), ("ecrecover", 1, nif_ecrecover),
], ],
Some(on_load) Some(on_load)
); );
struct EcrecoverResource { }
#[no_mangle] #[no_mangle]
fn on_load(env: Env, _load_info: Term) -> bool { fn on_load(env: Env, _load_info: Term) -> bool {
println!("on_load");
rustler::resource_struct_init!(EcrecoverResource, env);
true true
} }
pub fn nif_ecrecover<'a>(env: Env<'a>, args: &[Term<'a>]) -> Result<Term<'a>, Error> { pub fn nif_ecrecover<'a>(env: Env<'a>, args: &[Term<'a>]) -> NifResult<Term<'a>> {
let input: String = args[0].decode()?; let input: Binary = args[0].decode()?;
let mut output: String = args[1].decode()?;
let mut byte_ref = Vec::new(); let mut byte_ref = Vec::new();
let ecrecover = EcRecover { }; let ecrecover = EcRecover { };
let result = match ecrecover.execute(input.as_bytes(), let result = match ecrecover.execute(input.as_slice(),
&mut BytesRef::Flexible(&mut byte_ref)) { &mut BytesRef::Flexible(&mut byte_ref)) {
Ok(x) => x, Ok(_) => (),
Err(e) => return Err(rustler::Error::Atom("ecrecover failed")), Err(e) => return Err(rustler::Error::Atom("ecrecover failed")),
}; };
match String::from_utf8(byte_ref) { Ok(byte_ref.as_slice().encode(env))
Ok(x) => {
output.push_str(&x);
Ok((atoms::ok(), true).encode(env))
},
Err(x) => Err(rustler::Error::Atom("Invalid UTF-8")),
}
} }
/** /**

View File

@ -1,17 +1,29 @@
-module(nifecrecover). -module(nifecrecover).
%% API %% API
-export([ecrecover/2]). -export([ecrecover/1,
ecrecover_hex/1,
bin_to_hexstr/1,
hexstr_to_bin/1,
time_taken_to_execute/1
]).
%% Native library support %% Native library support
-export([load/0]). -export([load/0]).
-on_load(load/0). -on_load(load/0).
ecrecover(_Input, _Output) -> ecrecover(_Input) ->
not_loaded(?LINE). not_loaded(?LINE).
ecrecover_hex(Input) ->
Decoded = hexstr_to_bin(Input),
{ok, PubKey} = ecrecover(Decoded),
Encoded = bin_to_hexstr(PubKey),
Encoded.
load() -> load() ->
ok = erlang:load_nif("/home/newby/projects/ethereum/ecrecover/target/debug/libecrecover", 0). ok = erlang:load_nif("/home/newby/projects/ethereum/ecrecover/target/release/libecrecover", 0).
not_loaded(Line) -> not_loaded(Line) ->
erlang:nif_error({error, {not_loaded, [{module, ?MODULE}, {line, Line}]}}). erlang:nif_error({error, {not_loaded, [{module, ?MODULE}, {line, Line}]}}).
@ -25,3 +37,24 @@ priv()->
Path -> Path ->
Path Path
end. end.
%%
time_taken_to_execute(F) -> Start = os:timestamp(),
F(),
io:format("total time taken ~f seconds~n", [timer:now_diff(os:timestamp(), Start) / 1000000]).
%%
bin_to_hexstr(Bin) ->
lists:flatten([io_lib:format("~2.16.0B", [X]) ||
X <- binary_to_list(Bin)]).
hexstr_to_bin(S) ->
hexstr_to_bin(S, []).
hexstr_to_bin([], Acc) ->
list_to_binary(lists:reverse(Acc));
hexstr_to_bin([X,Y|T], Acc) ->
{ok, [V], []} = io_lib:fread("~16u", [X,Y]),
hexstr_to_bin(T, [V | Acc]);
hexstr_to_bin([X|T], Acc) ->
{ok, [V], []} = io_lib:fread("~16u", lists:flatten([X,"0"])),
hexstr_to_bin(T, [V | Acc]).