Skip to content

Commit

Permalink
fix int128 borsh encoding. add int256.
Browse files Browse the repository at this point in the history
  • Loading branch information
jpe7s committed Sep 22, 2024
1 parent 2940a39 commit d71a576
Show file tree
Hide file tree
Showing 3 changed files with 83 additions and 15 deletions.
59 changes: 57 additions & 2 deletions core/src/main/java/software/sava/core/encoding/ByteUtil.java
Original file line number Diff line number Diff line change
Expand Up @@ -78,14 +78,69 @@ public static long getInt64LE(final byte[] b, final int off) {
return (long) LONG_LE.get(b, off);
}

private static int putIntLE(final byte[] data, final int offset,
final BigInteger val,
final int byteSize) {
final byte[] be = val.abs().toByteArray();
for (int i = 0, o = offset + (be.length - 1); i < be.length; ++i, --o) {
data[o] = be[i];
}
if (val.signum() < 0) {
data[offset + (byteSize - 1)] |= (byte) 0b1000_0000;
}
return byteSize;
}

private static BigInteger getUIntLE(final byte[] data, final int offset, final int byteSize) {
final byte[] be = new byte[byteSize];
for (int i = 0, o = offset + (byteSize - 1); i < be.length; ++i, --o) {
be[i] = data[o];
}
return new BigInteger(be);
}

private static BigInteger getIntLE(final byte[] data, final int offset, final int byteSize) {
int o = offset + (byteSize - 1);
final boolean signed = (data[o] & 0b1000_0000) == 0b1000_0000;
final byte[] be = new byte[byteSize];
byte b = (byte) (data[o--] & 0b0111_1111);
boolean zero = b == 0;
be[0] = b;
for (int i = 1; i < be.length; ++i, --o) {
b = data[o];
be[i] = b;
if (zero) {
zero = b == 0;
}
}
return new BigInteger(signed ? -1 : zero ? 0 : 1, be);
}

public static int putInt128LE(final byte[] data, final int offset, final BigInteger val) {
throw new UnsupportedOperationException("TODO: convert 2's compliment encoding to regular LE byte encoding.");
return putIntLE(data, offset, val, 16);
}

public static BigInteger getUInt128LE(final byte[] data, final int offset) {
return getUIntLE(data, offset, 16);
}

public static BigInteger getInt128LE(final byte[] data, final int offset) {
throw new UnsupportedOperationException("TODO: convert 2's compliment encoding to regular LE byte encoding.");
return getIntLE(data, offset, 16);
}

public static int putInt256LE(final byte[] data, final int offset, final BigInteger val) {
return putIntLE(data, offset, val, 32);
}

public static BigInteger getUInt256LE(final byte[] data, final int offset) {
return getUIntLE(data, offset, 32);
}

public static BigInteger getInt256LE(final byte[] data, final int offset) {
return getIntLE(data, offset, 32);
}


public static int indexOf(final byte[] data, final int start, final int end,
final byte[] sub, final int subStart, final int subEnd) {
final int len = subEnd - subStart;
Expand Down
2 changes: 0 additions & 2 deletions core/src/test/java/software/sava/core/borsh/BorshTests.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
package software.sava.core.borsh;

import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import software.sava.core.accounts.PublicKey;
import software.sava.core.accounts.sysvar.Clock;
Expand Down Expand Up @@ -492,7 +491,6 @@ void multiDimensionalLongs() {
}
}

@Disabled
@Test
void multiDimensionalBigIntegers() {
final int dataTypeByteLength = 128 / Byte.SIZE;
Expand Down
37 changes: 26 additions & 11 deletions core/src/test/java/software/sava/core/ecnoding/ByteUtilTests.java
Original file line number Diff line number Diff line change
@@ -1,21 +1,36 @@
package software.sava.core.ecnoding;

import org.junit.jupiter.api.Test;
import software.sava.core.encoding.ByteUtil;

import java.math.BigInteger;
import java.util.Arrays;

import static org.junit.jupiter.api.Assertions.assertEquals;

final class ByteUtilTests {

private void testInt128(final BigInteger expected) {
byte[] write = new byte[16];
ByteUtil.putInt128LE(write, 0, expected);
var read = ByteUtil.getInt128LE(write, 0);
assertEquals(expected, read);

if (expected.signum() < 0) {
final var abs = expected.negate();
Arrays.fill(write, (byte) 0);
ByteUtil.putInt128LE(write, 0, abs);
read = ByteUtil.getUInt128LE(write, 0);
assertEquals(abs, read);
}
}

@Test
void test128BitIntegers() {
// var expected = new BigInteger("-155155494242896723051467122773477245");
// byte[] write = new byte[16];
// ByteUtil.putInt128LE(write, 0, expected);
// var read = ByteUtil.getInt128LE(write, 0);
// assertEquals(expected, read);
//
// expected = new BigInteger("-25912721450736272609715131753556298938");
// write = new byte[16];
// ByteUtil.putInt128LE(write, 0, expected);
// read = ByteUtil.getInt128LE(write, 0);
// assertEquals(expected, read);
var expected = new BigInteger("-155155494242896723051467122773477245");
testInt128(expected);

expected = new BigInteger("-25912721450736272609715131753556298938");
testInt128(expected);
}
}

0 comments on commit d71a576

Please sign in to comment.