Skip to content

Commit

Permalink
Improve behaviour of integer <-> blob conversions. Fixes #432
Browse files Browse the repository at this point in the history
  • Loading branch information
mikera committed Dec 15, 2023
1 parent d6e0218 commit da47075
Show file tree
Hide file tree
Showing 26 changed files with 93 additions and 130 deletions.
2 changes: 1 addition & 1 deletion convex-cli/src/main/java/convex/cli/AccountCreate.java
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ public void run() {
convex = mainParent.connectAsPeer(0);

Address address = convex.createAccountSync(keyPair.getAccountKey());
output.addField("Address", address.toExactLong());
output.addField("Address", address.longValue());
if (isFund) {
convex.transferSync(address, Constants.ACCOUNT_FUND_AMOUNT);
convex = mainParent.connectToSessionPeer(hostname, port, address, keyPair);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ public void run() {
Convex convex = null;
Address address = Address.create(addressNumber);
convex = mainParent.connectToSessionPeer(hostname, port, address, null);
String queryCommand = String.format("(account #%d)", address.toExactLong());
String queryCommand = String.format("(account #%d)", address.longValue());
ACell message = Reader.read(queryCommand);
Result result;
try {
Expand Down
2 changes: 1 addition & 1 deletion convex-cli/src/main/java/convex/cli/PeerCreate.java
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,7 @@ public void run() {
RecordOutput output=new RecordOutput();

output.addField("Public Peer Key", keyPair.getAccountKey().toString());
output.addField("Address", address.toExactLong());
output.addField("Address", address.longValue());
output.addField("Balance", currentBalance);
output.addField("Inital stake amount", stakeAmount);
// System.out.println("You can now start this peer by executing the following line:\n");
Expand Down
6 changes: 3 additions & 3 deletions convex-core/src/main/java/convex/core/State.java
Original file line number Diff line number Diff line change
Expand Up @@ -382,7 +382,7 @@ public State applyScheduledTransactions() {
if (sched.isEmpty()) break;
MapEntry<ABlob, AVector<ACell>> me = sched.entryAt(0);
ABlob key = me.getKey();
long time = key.toExactLong();
long time = key.longValue();
if (time > timestamp.longValue()) break; // exit if we are still in the future
AVector<ACell> trans = me.getValue();
long numScheduled = trans.count(); // number scheduled at this schedule timestamp
Expand Down Expand Up @@ -610,7 +610,7 @@ public State withAccounts(AVector<AccountStatus> newAccounts) {
* @throws IndexOutOfBoundsException if Address represents an illegal account position
*/
public State putAccount(Address address, AccountStatus accountStatus) {
long ix=address.toExactLong();
long ix=address.longValue();
long n=accounts.count();
if (ix>n) {
throw new IndexOutOfBoundsException("Trying to add an account beyond accounts array at position: "+ix);
Expand All @@ -634,7 +634,7 @@ public State putAccount(Address address, AccountStatus accountStatus) {
* @return The AccountStatus for the given account, or null.
*/
public AccountStatus getAccount(Address target) {
long ix=target.toExactLong();
long ix=target.longValue();
if ((ix<0)||(ix>=accounts.count())) return null;
return accounts.get(ix);
}
Expand Down
31 changes: 4 additions & 27 deletions convex-core/src/main/java/convex/core/data/AArrayBlob.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@

import convex.core.crypto.Hashing;
import convex.core.exceptions.InvalidDataException;
import convex.core.util.Errors;
import convex.core.util.Utils;

/**
Expand Down Expand Up @@ -178,7 +177,7 @@ public long longAt(long i) {
throw new IndexOutOfBoundsException("Index: " + i);
}

long val=Utils.readLong(store, offset+ix);
long val=Utils.readLong(store, offset+ix,8);
return val;
}

Expand Down Expand Up @@ -328,35 +327,13 @@ public void validateCell() throws InvalidDataException {
}
}

@Override
public long toExactLong() {
if (length != 8) throw new IllegalStateException(Errors.wrongLength(8, length));
return Utils.readLong(store, offset);
}

@Override
public long longValue() {
if (length==0) return 0;
if (length >= 8) {
return Utils.readLong(store, offset + length - 8);
return Utils.readLong(store, offset + length - 8,8);
} else {
long result = 0l;
int ix = offset;
if ((length & 4) != 0) {
result += 0xffffffffL & Utils.readInt(store, ix);
ix += 4;
}
if ((length & 2) != 0) {
result = (result << 16) + (0xFFFF & Utils.readShort(store, ix));
ix += 2;
}
if ((length & 1) != 0) {
result = (result << 8) + (0xFF & store[ix]);
ix += 1;
}
// Sign extend
//int shift=64-(length*8);
//return (result<<shift)>>shift;
return result;
return Utils.readLong(store,offset,length);
}
}

Expand Down
8 changes: 0 additions & 8 deletions convex-core/src/main/java/convex/core/data/ABlob.java
Original file line number Diff line number Diff line change
Expand Up @@ -343,14 +343,6 @@ public final int hashCode() {
return Long.hashCode(longValue());
}

/**
* Gets the long value of this Blob if the length is exactly 8 bytes, otherwise
* throws an Exception
*
* @return The long value represented by the Blob
*/
public abstract long toExactLong();

/**
* Returns true if this object is a regular blob (i.e. not a special blob type like Address)
* @return True if a regular blob
Expand Down
9 changes: 2 additions & 7 deletions convex-core/src/main/java/convex/core/data/ALongBlob.java
Original file line number Diff line number Diff line change
Expand Up @@ -111,16 +111,11 @@ public long hexMatchLength(ABlob b, long start, long length) {
public final long longValue() {
return value;
}

@Override
public long toExactLong() {
return value;
}

@Override
public int compareTo(ABlob b) {
if (b.count()==LENGTH) {
return compareTo(b.toExactLong());
return compareTo(b.longValue());
} else {
return -b.compareTo(this);
}
Expand All @@ -133,7 +128,7 @@ protected int compareTo(long bvalue) {
@Override
public final boolean equalsBytes(ABlob b) {
if (b.count()!=LENGTH) return false;
return value==b.toExactLong();
return value==b.longValue();
}

@Override
Expand Down
11 changes: 3 additions & 8 deletions convex-core/src/main/java/convex/core/data/Address.java
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ public static Address create(long number) {
*/
public static Address create(ABlob b) {
if (b.count()!=BYTE_LENGTH) return null;
return create(b.toExactLong());
return create(b.longValue());
}

@Override
Expand Down Expand Up @@ -94,7 +94,7 @@ public static Address fromHex(String hexString) {
Blob b=Blob.fromHex(hexString);
if (b==null) return null;
if (b.length!=BYTE_LENGTH) return null;
return create(b.toExactLong());
return create(b.longValue());
}

/**
Expand Down Expand Up @@ -219,12 +219,7 @@ protected void updateDigest(MessageDigest digest) {

@Override
public boolean equalsBytes(byte[] bytes, int byteOffset) {
return value==Utils.readLong(bytes, byteOffset);
}

@Override
public long toExactLong() {
return value;
return value==Utils.readLong(bytes, byteOffset,8);
}

public static final int MAX_ENCODING_LENGTH = 1+Format.MAX_VLC_COUNT_LENGTH;
Expand Down
7 changes: 0 additions & 7 deletions convex-core/src/main/java/convex/core/data/BlobTree.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@

import convex.core.exceptions.BadFormatException;
import convex.core.exceptions.InvalidDataException;
import convex.core.util.Errors;
import convex.core.util.Utils;

/**
Expand Down Expand Up @@ -524,12 +523,6 @@ public long hexMatchLength(ABlob b, long start, long length) {
}
return length;
}

@Override
public long toExactLong() {
if (count != 8) throw new IllegalStateException(Errors.wrongLength(8, count));
return getChunk(0).toExactLong();
}

@Override
public long longValue() {
Expand Down
13 changes: 4 additions & 9 deletions convex-core/src/main/java/convex/core/data/LongBlob.java
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,8 @@ private LongBlob(long value) {

public static LongBlob create(String string) {
byte[] bs = Utils.hexToBytes(string);
if (bs.length != LENGTH) throw new IllegalArgumentException("Long blob requires a length 8 hex string");
return new LongBlob(Utils.readLong(bs, 0));
int bl=bs.length;
return new LongBlob(Utils.readLong(bs, Math.max(0, bl-8),Math.min(8, bl)));
}

public static LongBlob create(long value) {
Expand Down Expand Up @@ -75,7 +75,7 @@ public boolean equals(ABlob a) {
// Note Blob is the only other plausible representation of a LongBlob
// AccountKey, Hash etc. excluded because of length
Blob b=(Blob)a;
return ((b.count()==LENGTH)&& (b.toExactLong()== value));
return ((b.count()==LENGTH)&& (b.longValue()== value));
}
return false;
}
Expand All @@ -98,11 +98,6 @@ public int estimatedEncodingSize() {
return (int) (2 + LENGTH);
}

@Override
public long toExactLong() {
return value;
}

@Override
public long hexMatchLength(ABlob b, long start, long length) {
if (b == this) return length;
Expand All @@ -120,7 +115,7 @@ public byte getTag() {

@Override
public boolean equalsBytes(byte[] bytes, int byteOffset) {
return value==Utils.readLong(bytes, byteOffset);
return value==Utils.readLong(bytes, byteOffset,8);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -165,7 +165,7 @@ public static CVMDouble read(double value) throws BadFormatException {

public static CVMDouble read(byte tag, Blob blob, int offset) throws BadFormatException {
if (blob.count()<offset+1+8) throw new BadFormatException("Insufficient blob bytes to read Double");
long bits=Utils.readLong(blob.getInternalArray(), blob.getInternalOffset()+offset+1);
long bits=Utils.readLong(blob.getInternalArray(), blob.getInternalOffset()+offset+1,8);
double d=Double.longBitsToDouble(bits);
CVMDouble result= read(d);
result.attachEncoding(blob.slice(offset,offset+1+8));
Expand Down
11 changes: 8 additions & 3 deletions convex-core/src/main/java/convex/core/data/prim/CVMLong.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import java.math.BigInteger;

import convex.core.data.ABlob;
import convex.core.data.ACell;
import convex.core.data.AString;
import convex.core.data.Blob;
Expand Down Expand Up @@ -443,9 +444,13 @@ public AInteger toCanonical() {
}

@Override
public LongBlob toBlob() {
// TODO: do we want minimal length?
return LongBlob.create(value);
public ABlob toBlob() {
long n=byteLength();
ABlob result= LongBlob.create(value);
if (n<8) {
result=result.slice(8-n);
}
return result;
}


Expand Down
14 changes: 7 additions & 7 deletions convex-core/src/main/java/convex/core/init/Init.java
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@ public static State createBaseState(List<AccountKey> genesisKeys) {
accts = s.getAccounts();

// Set up initial user accounts
assert(accts.count() == GENESIS_ADDRESS.toExactLong());
assert(accts.count() == GENESIS_ADDRESS.longValue());
{
long userFunds = (long)(supply*0.8); // 80% to user accounts
supply -= userFunds;
Expand All @@ -128,7 +128,7 @@ public static State createBaseState(List<AccountKey> genesisKeys) {
// One Peer account for each specified key (including initial genesis user)
for (int i = 0; i < keyCount; i++) {
Address address = Address.create(accts.count());
assert(address.toExactLong() == accts.count());
assert(address.longValue() == accts.count());
AccountKey key = genesisKeys.get(i);
long userBalance = userFunds / (keyCount-i);
accts = addAccount(accts, address, key, userBalance);
Expand Down Expand Up @@ -250,11 +250,11 @@ private static State addStandardLibraries(State s) {
}

public static Address calcPeerAddress(int userCount, int index) {
return Address.create(GENESIS_ADDRESS.toExactLong() + userCount + index);
return Address.create(GENESIS_ADDRESS.longValue() + userCount + index);
}

public static Address calcUserAddress(int index) {
return Address.create(GENESIS_ADDRESS.toExactLong() + index);
return Address.create(GENESIS_ADDRESS.longValue() + index);
}

// A CVX file contains forms which must be wrapped in a `(do ...)` and deployed as an actor.
Expand Down Expand Up @@ -337,14 +337,14 @@ private static BlobMap<AccountKey, PeerStatus> addPeer(BlobMap<AccountKey, PeerS
}

private static AVector<AccountStatus> addGovernanceAccount(AVector<AccountStatus> accts, Address a, long balance) {
if (accts.count() != a.toExactLong()) throw new Error("Incorrect initialisation address: " + a);
if (accts.count() != a.longValue()) throw new Error("Incorrect initialisation address: " + a);
AccountStatus as = AccountStatus.createGovernance(balance);
accts = accts.conj(as);
return accts;
}

private static AVector<AccountStatus> addCoreLibrary(AVector<AccountStatus> accts, Address a) {
if (accts.count() != a.toExactLong()) throw new Error("Incorrect core library address: " + a);
if (accts.count() != a.longValue()) throw new Error("Incorrect core library address: " + a);

AccountStatus as = AccountStatus.createActor();
as=as.withEnvironment(Core.ENVIRONMENT);
Expand All @@ -355,7 +355,7 @@ private static AVector<AccountStatus> addCoreLibrary(AVector<AccountStatus> acct

private static AVector<AccountStatus> addAccount(AVector<AccountStatus> accts, Address a, AccountKey key,
long balance) {
if (accts.count() != a.toExactLong()) throw new Error("Incorrect account address: " + a);
if (accts.count() != a.longValue()) throw new Error("Incorrect account address: " + a);
AccountStatus as = AccountStatus.create(0L, balance, key);
as = as.withMemory(Constants.INITIAL_ACCOUNT_ALLOWANCE);
accts = accts.conj(as);
Expand Down
10 changes: 5 additions & 5 deletions convex-core/src/main/java/convex/core/lang/Context.java
Original file line number Diff line number Diff line change
Expand Up @@ -1478,7 +1478,7 @@ public Context transfer(Address target, long amount) {
AVector<AccountStatus> accounts=getState().getAccounts();

Address source=getAddress();
long sourceIndex=source.toExactLong();
long sourceIndex=source.longValue();
AccountStatus sourceAccount=accounts.get(sourceIndex);

long currentBalance=sourceAccount.getBalance();
Expand All @@ -1491,7 +1491,7 @@ public Context transfer(Address target, long amount) {
accounts=accounts.assoc(sourceIndex, newSourceAccount);

// new target account (note: could be source account, so we get from latest accounts)
long targetIndex=target.toExactLong();
long targetIndex=target.longValue();
if (targetIndex>=accounts.count()) {
return this.withError(ErrorCodes.NOBODY,"Target account for transfer "+target+" does not exist");
}
Expand Down Expand Up @@ -1538,7 +1538,7 @@ public Context transferMemoryAllowance(Address target, CVMLong amountToSend) {
AVector<AccountStatus> accounts=getState().getAccounts();

Address source=getAddress();
long sourceIndex=source.toExactLong();
long sourceIndex=source.longValue();
AccountStatus sourceAccount=accounts.get(sourceIndex);

long currentBalance=sourceAccount.getMemory();
Expand All @@ -1551,7 +1551,7 @@ public Context transferMemoryAllowance(Address target, CVMLong amountToSend) {
accounts=accounts.assoc(sourceIndex, newSourceAccount);

// new target account (note: could be source account, so we get from latest accounts)
long targetIndex=target.toExactLong();
long targetIndex=target.longValue();
if (targetIndex>=accounts.count()) {
return withError(ErrorCodes.NOBODY,"Cannot transfer memory allowance to non-existent account: "+target);
}
Expand Down Expand Up @@ -1579,7 +1579,7 @@ public Context setMemory(long allowance) {
if (allowance>Constants.MAX_SUPPLY) return withError(ErrorCodes.ARGUMENT,"Can't transfer an allowance amount beyond maximum limit");

Address source=getAddress();
long sourceIndex=source.toExactLong();
long sourceIndex=source.longValue();
AccountStatus sourceAccount=accounts.get(sourceIndex);

long current=sourceAccount.getMemory();
Expand Down
2 changes: 1 addition & 1 deletion convex-core/src/main/java/convex/core/lang/RT.java
Original file line number Diff line number Diff line change
Expand Up @@ -1680,7 +1680,7 @@ public static <T> T json(ACell o) {
if (o instanceof CVMChar)
return (T) ((CVMChar) o).toString();
if (o instanceof Address)
return (T) (Long)((Address) o).toExactLong();
return (T) (Long)((Address) o).longValue();
if (o instanceof AMap) {
AMap<?,?> m= (AMap<?,?>)o;
return (T)jsonMap(m);
Expand Down
Loading

0 comments on commit da47075

Please sign in to comment.