Skip to content

Commit

Permalink
jni: Fragment class
Browse files Browse the repository at this point in the history
  • Loading branch information
ecioppettini committed May 13, 2021
1 parent 7f7db24 commit 31e11ea
Show file tree
Hide file tree
Showing 3 changed files with 157 additions and 9 deletions.
54 changes: 49 additions & 5 deletions bindings/wallet-jni/java/WalletTest.java
@@ -1,10 +1,11 @@
import com.iohk.jormungandrwallet.Wallet;
import com.iohk.jormungandrwallet.Settings;
import com.iohk.jormungandrwallet.Conversion;
import com.iohk.jormungandrwallet.Fragment;
import com.iohk.jormungandrwallet.Proposal;
import com.iohk.jormungandrwallet.PendingTransactions;
import com.iohk.jormungandrwallet.SymmetricCipher;
import com.iohk.jormungandrwallet.Settings;
import com.iohk.jormungandrwallet.Fragment;

import java.util.Properties;
import java.util.Enumeration;
Expand Down Expand Up @@ -74,8 +75,8 @@ public void extractSettings() throws IOException {
public void buildSettings() throws IOException {
final byte[] blockId = hexStringToByteArray("182764b45bae25cc466143de8107618b37f0d28fe3daa0a0d39fd0ab5a2061e1");
final Settings.Discrimination discrimination = Settings.Discrimination.TEST;
final Settings.LinearFees expectedFees = new Settings.LinearFees(1, 2, 3, new Settings.PerCertificateFee(4, 5, 6),
new Settings.PerVoteCertificateFee(7, 8));
final Settings.LinearFees expectedFees = new Settings.LinearFees(1, 2, 3,
new Settings.PerCertificateFee(4, 5, 6), new Settings.PerVoteCertificateFee(7, 8));

Settings.PerCertificateFee test = new Settings.PerCertificateFee(4, 5, 6);

Expand All @@ -96,8 +97,10 @@ public void buildSettings() throws IOException {
assertEquals(fees.perCertificateFee.certificateOwnerStakeDelegation,
expectedFees.perCertificateFee.certificateOwnerStakeDelegation);

assertEquals(fees.perVoteCertificateFee.certificateVotePlan, expectedFees.perVoteCertificateFee.certificateVotePlan);
assertEquals(fees.perVoteCertificateFee.certificateVoteCast, expectedFees.perVoteCertificateFee.certificateVoteCast);
assertEquals(fees.perVoteCertificateFee.certificateVotePlan,
expectedFees.perVoteCertificateFee.certificateVotePlan);
assertEquals(fees.perVoteCertificateFee.certificateVoteCast,
expectedFees.perVoteCertificateFee.certificateVoteCast);

final Settings.Discrimination foundDiscrimination = Settings.discrimination(settingsPtr);

Expand Down Expand Up @@ -301,6 +304,47 @@ public void confirmVoteCast() throws IOException {
}
}

@Test
public void fragmentId() throws IOException {
final long walletPtr = Wallet.recover(
"neck bulb teach illegal soul cry monitor claw amount boring provide village rival draft stone");

final byte[] block0 = Files.readAllBytes(Paths.get("../../../test-vectors/block0"));

final long settingsPtr = Wallet.initialFunds(walletPtr, block0);

final byte[] id = new byte[Proposal.ID_SIZE];
final long proposalPtr = Proposal.withPublicPayload(id, 0, 3);

Wallet.setState(walletPtr, 10000000, 0);

try {
final byte[] transaction = Wallet.voteCast(walletPtr, settingsPtr, proposalPtr, 1);

final long fragment = Fragment.fromBytes(transaction);
final byte[] fragmentId = Fragment.id(fragment);
Fragment.delete(fragment);

final long pending = Wallet.pendingTransactions(walletPtr);

final int sizeBefore = PendingTransactions.len(pending);

final byte[] expectedFragmentId = PendingTransactions.get(pending, 0);

for (int i = 0; i < fragmentId.length; i++) {
assertEquals(fragmentId[i], expectedFragmentId[i]);
}

PendingTransactions.delete(pending);
} catch (final Exception e) {
Proposal.delete(proposalPtr);
Settings.delete(settingsPtr);
Wallet.delete(walletPtr);
System.out.println(e.getMessage());
throw e;
}
}

@Test
public void privateVoteCast() throws IOException {
final long walletPtr = Wallet.recover(
Expand Down
13 changes: 13 additions & 0 deletions bindings/wallet-jni/java/com/iohk/jormungandrwallet/Fragment.java
@@ -0,0 +1,13 @@
package com.iohk.jormungandrwallet;

public class Fragment {
static {
System.loadLibrary("wallet_jni");
}

public native static long fromBytes(byte[] buffer);

public native static byte[] id(long fragmentPtr);

public native static void delete (long fragmentPtr);
}
99 changes: 95 additions & 4 deletions bindings/wallet-jni/src/lib.rs
Expand Up @@ -3,11 +3,14 @@ use jni::sys::{jbyte, jbyteArray, jint, jlong};
use jni::JNIEnv;
use std::convert::TryInto;
use std::ptr::{null, null_mut};
use wallet_core::c::settings::{
settings_block0_hash, settings_discrimination, settings_fees, settings_new, Discrimination,
LinearFee, PerCertificateFee, PerVoteCertificateFee,
};
use wallet_core::c::*;
use wallet_core::c::{
fragment::{fragment_from_raw, fragment_id},
settings::{
settings_block0_hash, settings_discrimination, settings_fees, settings_new, Discrimination,
LinearFee, PerCertificateFee, PerVoteCertificateFee,
},
};

///
/// # Safety
Expand Down Expand Up @@ -1027,3 +1030,91 @@ pub extern "system" fn Java_com_iohk_jormungandrwallet_SymmetricCipher_decrypt(
}
}
}

///
/// # Safety
///
/// This function dereference raw pointers. Even though
/// the function checks if the pointers are null. Mind not to put random values
/// in or you may see unexpected behaviors
///
#[no_mangle]
pub unsafe extern "system" fn Java_com_iohk_jormungandrwallet_Fragment_fromBytes(
env: JNIEnv,
_: JClass,
buffer: jbyteArray,
) -> jlong {
let len = env
.get_array_length(buffer)
.expect("Couldn't get block0 array length") as usize;

let mut bytes = vec![0i8; len as usize];

env.get_byte_array_region(buffer, 0, &mut bytes).unwrap();

let mut ptr: FragmentPtr = null_mut();

let result = fragment_from_raw(
bytes.as_ptr().cast::<u8>(),
len,
&mut ptr as *mut FragmentPtr,
);

if let Some(error) = result.error() {
let _ = env.throw(error.to_string());
}

ptr as jlong
}

///
/// # Safety
///
/// This function dereference raw pointers. Even though
/// the function checks if the pointers are null. Mind not to put random values
/// in or you may see unexpected behaviors
///
#[no_mangle]
pub unsafe extern "system" fn Java_com_iohk_jormungandrwallet_Fragment_id(
env: JNIEnv,
_: JClass,
fragment: jlong,
) -> jbyteArray {
let mut id = [0u8; FRAGMENT_ID_LENGTH];

let result = fragment_id(fragment as FragmentPtr, id.as_mut_ptr());

let array = env
.new_byte_array(id.len() as jint)
.expect("Failed to create new byte array");

match result.error() {
None => {
let slice = std::slice::from_raw_parts(id.as_ptr() as *const jbyte, id.len());

env.set_byte_array_region(array, 0, slice)
.expect("Couldn't copy array to jvm");
}
Some(error) => {
let _ = env.throw(error.to_string());
}
};

array
}

///
/// # Safety
///
/// This function dereference raw pointers. Even though
/// the function checks if the pointers are null. Mind not to put random values
/// in or you may see unexpected behaviors
///
#[no_mangle]
pub unsafe extern "system" fn Java_com_iohk_jormungandrwallet_Fragment_delete(
_env: JNIEnv,
_: JClass,
fragment: jlong,
) {
let _ = fragment::fragment_delete(fragment as FragmentPtr);
}

0 comments on commit 31e11ea

Please sign in to comment.