Check in before surgery

This commit is contained in:
John Newby 2019-08-05 12:25:53 +02:00
parent bf2d30d064
commit 74e20f3a9d
5 changed files with 93 additions and 3 deletions

View File

@ -8,9 +8,11 @@ edition = "2018"
[dependencies] [dependencies]
c_vec = "1.3.3" c_vec = "1.3.3"
ethcore-builtin = { path = "../parity-ethereum/ethcore/builtin" }
lazy_static = "1.3.0"
libc = "0.2.60" libc = "0.2.60"
parity-bytes = "0.1.0" parity-bytes = "0.1.0"
ethcore-builtin = { path = "../parity-ethereum/ethcore/builtin" } rustler = "0.20.0"
[lib] [lib]
crate-type = ["cdylib"] crate-type = ["cdylib"]

View File

@ -2,7 +2,7 @@ DEBUG ?= 0
ifeq ($(DEBUG), 1) ifeq ($(DEBUG), 1)
CFLAGS =-DDEBUG=1 CFLAGS =-DDEBUG=1
else else
CFLAGS=-DNDEBUG CFLAGS=-DNDEBUG -Ofast
endif endif
CC = gcc CC = gcc
@ -15,7 +15,7 @@ INCLUDEPATH = -Iinclude
all: test erl_ecrecover all: test erl_ecrecover
test: src/test.c src/base64.c target/debug/libecrecover.so test: src/test.c src/base64.c target/release/libecrecover.so
$(CC) -o $@ $^ $(INCLUDEPATH) $(CFLAGS) $(LDPATH) $(CC) -o $@ $^ $(INCLUDEPATH) $(CFLAGS) $(LDPATH)
./test ./test

View File

@ -1,6 +1,11 @@
-module(ecrecover). -module(ecrecover).
-export([start/1, stop/0, init/1]). -export([start/1, stop/0, init/1]).
-export([ecrecover/1]). -export([ecrecover/1]).
-export([time_taken_to_execute/1]).
time_taken_to_execute(F) -> Start = os:timestamp(),
F(),
io:format("total time taken ~f seconds~n", [timer:now_diff(os:timestamp(), Start) / 1000000]).
start(ExtPrg) -> start(ExtPrg) ->
spawn(?MODULE, init, [ExtPrg]). spawn(?MODULE, init, [ExtPrg]).

View File

@ -1,18 +1,72 @@
extern crate c_vec; extern crate c_vec;
extern crate ethcore_builtin; extern crate ethcore_builtin;
#[macro_use]
extern crate lazy_static;
extern crate libc; extern crate libc;
extern crate parity_bytes; extern crate parity_bytes;
#[macro_use]
extern crate rustler;
use std::ffi::*; use std::ffi::*;
use ethcore_builtin::EcRecover; use ethcore_builtin::EcRecover;
use crate::ethcore_builtin::Implementation; use crate::ethcore_builtin::Implementation;
use c_vec::{CVec}; use c_vec::{CVec};
use parity_bytes::BytesRef; use parity_bytes::BytesRef;
use rustler::*;
use std::ptr::copy_nonoverlapping; use std::ptr::copy_nonoverlapping;
const INPUT_LENGTH: usize = 512; const INPUT_LENGTH: usize = 512;
const OUTPUT_LENGTH: usize = 32; const OUTPUT_LENGTH: usize = 32;
mod atoms {
rustler_atoms! {
atom ok;
}
}
rustler_export_nifs!(
"nifecrecover",
[
("ecrecover", 2, nif_ecrecover),
],
Some(on_load)
);
struct EcrecoverResource { }
#[no_mangle]
fn on_load(env: Env, _load_info: Term) -> bool {
println!("on_load");
rustler::resource_struct_init!(EcrecoverResource, env);
true
}
pub fn nif_ecrecover<'a>(env: Env<'a>, args: &[Term<'a>]) -> Result<Term<'a>, Error> {
let input: String = args[0].decode()?;
let mut output: String = args[1].decode()?;
let mut byte_ref = Vec::new();
let ecrecover = EcRecover { };
let result = match ecrecover.execute(input.as_bytes(),
&mut BytesRef::Flexible(&mut byte_ref)) {
Ok(x) => x,
Err(e) => return Err(rustler::Error::Atom("ecrecover failed")),
};
match String::from_utf8(byte_ref) {
Ok(x) => {
output.push_str(&x);
Ok((atoms::ok(), true).encode(env))
},
Err(x) => Err(rustler::Error::Atom("Invalid UTF-8")),
}
}
/**
* C interface to the ethereum ecrecover implementation. Returns 1 on success,
* 0 on failure (in which case there are no guarantees as to what is in output.
*
* Memory allocated by caller, expected to be an array of bytes, as above-- 512 in,
* 32 out.
*/
#[no_mangle] #[no_mangle]
pub unsafe extern "C" fn ecrecover(input: *const libc::c_uchar, output: *mut libc::c_uchar) -> i16 { pub unsafe extern "C" fn ecrecover(input: *const libc::c_uchar, output: *mut libc::c_uchar) -> i16 {
let ecrecover = EcRecover { }; let ecrecover = EcRecover { };
@ -27,6 +81,8 @@ pub unsafe extern "C" fn ecrecover(input: *const libc::c_uchar, output: *mut lib
return 1; return 1;
} }
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
#[test] #[test]

27
src/nifecrecover.erl Normal file
View File

@ -0,0 +1,27 @@
-module(nifecrecover).
%% API
-export([ecrecover/2]).
%% Native library support
-export([load/0]).
-on_load(load/0).
ecrecover(_Input, _Output) ->
not_loaded(?LINE).
load() ->
ok = erlang:load_nif("/home/newby/projects/ethereum/ecrecover/target/debug/libecrecover", 0).
not_loaded(Line) ->
erlang:nif_error({error, {not_loaded, [{module, ?MODULE}, {line, Line}]}}).
priv()->
case code:priv_dir(?MODULE) of
{error, _} ->
EbinDir = filename:dirname(code:which(?MODULE)),
AppPath = filename:dirname(EbinDir),
filename:join(AppPath, "priv");
Path ->
Path
end.