mirror of
https://github.com/Qortal/qortal.git
synced 2025-04-22 19:07:51 +00:00
Revert "Add Qortal AT FunctionCodes for getting account level / blocks minted + tests"
This reverts commit eb9b94b9c6cb7f969cd0a759535be8e117a7359c.
This commit is contained in:
parent
1b42c5edb1
commit
59025b8f47
@ -205,12 +205,6 @@ public class Account {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Returns account's blockMinted (0+) or null if account not found in repository. */
|
|
||||||
public Integer getBlocksMinted() throws DataException {
|
|
||||||
return this.repository.getAccountRepository().getMintedBlockCount(this.address);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/** Returns whether account can build reward-shares.
|
/** Returns whether account can build reward-shares.
|
||||||
* <p>
|
* <p>
|
||||||
* To be able to create reward-shares, the account needs to pass at least one of these tests:<br>
|
* To be able to create reward-shares, the account needs to pass at least one of these tests:<br>
|
||||||
|
@ -551,7 +551,7 @@ public class QortalATAPI extends API {
|
|||||||
* <p>
|
* <p>
|
||||||
* Otherwise, assume B is a public key.
|
* Otherwise, assume B is a public key.
|
||||||
*/
|
*/
|
||||||
/*package*/ Account getAccountFromB(MachineState state) {
|
private Account getAccountFromB(MachineState state) {
|
||||||
byte[] bBytes = this.getB(state);
|
byte[] bBytes = this.getB(state);
|
||||||
|
|
||||||
if ((bBytes[0] == Crypto.ADDRESS_VERSION || bBytes[0] == Crypto.AT_ADDRESS_VERSION)
|
if ((bBytes[0] == Crypto.ADDRESS_VERSION || bBytes[0] == Crypto.AT_ADDRESS_VERSION)
|
||||||
|
@ -10,11 +10,9 @@ import org.ciyam.at.ExecutionException;
|
|||||||
import org.ciyam.at.FunctionData;
|
import org.ciyam.at.FunctionData;
|
||||||
import org.ciyam.at.IllegalFunctionCodeException;
|
import org.ciyam.at.IllegalFunctionCodeException;
|
||||||
import org.ciyam.at.MachineState;
|
import org.ciyam.at.MachineState;
|
||||||
import org.qortal.account.Account;
|
|
||||||
import org.qortal.crosschain.Bitcoin;
|
import org.qortal.crosschain.Bitcoin;
|
||||||
import org.qortal.crypto.Crypto;
|
import org.qortal.crypto.Crypto;
|
||||||
import org.qortal.data.transaction.TransactionData;
|
import org.qortal.data.transaction.TransactionData;
|
||||||
import org.qortal.repository.DataException;
|
|
||||||
import org.qortal.settings.Settings;
|
import org.qortal.settings.Settings;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -162,68 +160,6 @@ public enum QortalFunctionCode {
|
|||||||
protected void postCheckExecute(FunctionData functionData, MachineState state, short rawFunctionCode) throws ExecutionException {
|
protected void postCheckExecute(FunctionData functionData, MachineState state, short rawFunctionCode) throws ExecutionException {
|
||||||
convertAddressInB(Crypto.ADDRESS_VERSION, state);
|
convertAddressInB(Crypto.ADDRESS_VERSION, state);
|
||||||
}
|
}
|
||||||
},
|
|
||||||
/**
|
|
||||||
* Returns account level of account in B.<br>
|
|
||||||
* <tt>0x0520</tt><br>
|
|
||||||
* B should contain either Qortal address or public key,<br>
|
|
||||||
* e.g. as a result of calling function {@link org.ciyam.at.FunctionCode#PUT_ADDRESS_FROM_TX_IN_A_INTO_B}</code>.
|
|
||||||
* <p></p>
|
|
||||||
* Returns account level, or -1 if account unknown.
|
|
||||||
* <p></p>
|
|
||||||
* @see QortalATAPI#getAccountFromB(MachineState)
|
|
||||||
*/
|
|
||||||
GET_ACCOUNT_LEVEL_FROM_ACCOUNT_IN_B(0x0520, 0, true) {
|
|
||||||
@Override
|
|
||||||
protected void postCheckExecute(FunctionData functionData, MachineState state, short rawFunctionCode) throws ExecutionException {
|
|
||||||
QortalATAPI api = (QortalATAPI) state.getAPI();
|
|
||||||
Account account = api.getAccountFromB(state);
|
|
||||||
|
|
||||||
Integer accountLevel = null;
|
|
||||||
|
|
||||||
if (account != null) {
|
|
||||||
try {
|
|
||||||
accountLevel = account.getLevel();
|
|
||||||
} catch (DataException e) {
|
|
||||||
throw new RuntimeException("AT API unable to fetch account level?", e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
functionData.returnValue = accountLevel != null
|
|
||||||
? accountLevel.longValue()
|
|
||||||
: -1;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
/**
|
|
||||||
* Returns account's minted block count of account in B.<br>
|
|
||||||
* <tt>0x0521</tt><br>
|
|
||||||
* B should contain either Qortal address or public key,<br>
|
|
||||||
* e.g. as a result of calling function {@link org.ciyam.at.FunctionCode#PUT_ADDRESS_FROM_TX_IN_A_INTO_B}</code>.
|
|
||||||
* <p></p>
|
|
||||||
* Returns account level, or -1 if account unknown.
|
|
||||||
* <p></p>
|
|
||||||
* @see QortalATAPI#getAccountFromB(MachineState)
|
|
||||||
*/
|
|
||||||
GET_BLOCKS_MINTED_FROM_ACCOUNT_IN_B(0x0521, 0, true) {
|
|
||||||
@Override
|
|
||||||
protected void postCheckExecute(FunctionData functionData, MachineState state, short rawFunctionCode) throws ExecutionException {
|
|
||||||
QortalATAPI api = (QortalATAPI) state.getAPI();
|
|
||||||
Account account = api.getAccountFromB(state);
|
|
||||||
|
|
||||||
Integer blocksMinted = null;
|
|
||||||
|
|
||||||
if (account != null) {
|
|
||||||
try {
|
|
||||||
blocksMinted = account.getBlocksMinted();
|
|
||||||
} catch (DataException e) {
|
|
||||||
throw new RuntimeException("AT API unable to fetch account's minted block count?", e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
functionData.returnValue = blocksMinted != null
|
|
||||||
? blocksMinted.longValue()
|
|
||||||
: -1;
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
public final short value;
|
public final short value;
|
||||||
|
@ -76,9 +76,6 @@ public interface AccountRepository {
|
|||||||
*/
|
*/
|
||||||
public void setBlocksMintedAdjustment(AccountData accountData) throws DataException;
|
public void setBlocksMintedAdjustment(AccountData accountData) throws DataException;
|
||||||
|
|
||||||
/** Returns account's minted block count or null if account not found. */
|
|
||||||
public Integer getMintedBlockCount(String address) throws DataException;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Saves account's minted block count and public key if present, in repository.
|
* Saves account's minted block count and public key if present, in repository.
|
||||||
* <p>
|
* <p>
|
||||||
|
@ -241,20 +241,6 @@ public class HSQLDBAccountRepository implements AccountRepository {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public Integer getMintedBlockCount(String address) throws DataException {
|
|
||||||
String sql = "SELECT blocks_minted FROM Accounts WHERE account = ?";
|
|
||||||
|
|
||||||
try (ResultSet resultSet = this.repository.checkedExecute(sql, address)) {
|
|
||||||
if (resultSet == null)
|
|
||||||
return null;
|
|
||||||
|
|
||||||
return resultSet.getInt(1);
|
|
||||||
} catch (SQLException e) {
|
|
||||||
throw new DataException("Unable to fetch account's minted block count from repository", e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setMintedBlockCount(AccountData accountData) throws DataException {
|
public void setMintedBlockCount(AccountData accountData) throws DataException {
|
||||||
HSQLDBSaver saveHelper = new HSQLDBSaver("Accounts");
|
HSQLDBSaver saveHelper = new HSQLDBSaver("Accounts");
|
||||||
|
@ -1,186 +0,0 @@
|
|||||||
package org.qortal.test.at.qortalfunctioncodes;
|
|
||||||
|
|
||||||
import com.google.common.primitives.Bytes;
|
|
||||||
import org.ciyam.at.CompilationException;
|
|
||||||
import org.ciyam.at.FunctionCode;
|
|
||||||
import org.ciyam.at.MachineState;
|
|
||||||
import org.ciyam.at.OpCode;
|
|
||||||
import org.junit.After;
|
|
||||||
import org.junit.Before;
|
|
||||||
import org.junit.Test;
|
|
||||||
import org.qortal.account.Account;
|
|
||||||
import org.qortal.account.PrivateKeyAccount;
|
|
||||||
import org.qortal.at.QortalFunctionCode;
|
|
||||||
import org.qortal.data.at.ATStateData;
|
|
||||||
import org.qortal.repository.DataException;
|
|
||||||
import org.qortal.repository.Repository;
|
|
||||||
import org.qortal.repository.RepositoryManager;
|
|
||||||
import org.qortal.test.common.AtUtils;
|
|
||||||
import org.qortal.test.common.BlockUtils;
|
|
||||||
import org.qortal.test.common.Common;
|
|
||||||
import org.qortal.test.common.TestAccount;
|
|
||||||
import org.qortal.transaction.DeployAtTransaction;
|
|
||||||
import org.qortal.utils.Base58;
|
|
||||||
import org.qortal.utils.BitTwiddling;
|
|
||||||
|
|
||||||
import java.nio.ByteBuffer;
|
|
||||||
import java.util.Random;
|
|
||||||
|
|
||||||
import static org.junit.Assert.assertEquals;
|
|
||||||
import static org.junit.Assert.assertNull;
|
|
||||||
|
|
||||||
public class GetAccountBlocksMintedTests extends Common {
|
|
||||||
|
|
||||||
private static final Random RANDOM = new Random();
|
|
||||||
private static final long fundingAmount = 1_00000000L;
|
|
||||||
|
|
||||||
private Repository repository = null;
|
|
||||||
private byte[] creationBytes = null;
|
|
||||||
private PrivateKeyAccount deployer;
|
|
||||||
private DeployAtTransaction deployAtTransaction;
|
|
||||||
private String atAddress;
|
|
||||||
|
|
||||||
@Before
|
|
||||||
public void before() throws DataException {
|
|
||||||
Common.useDefaultSettings();
|
|
||||||
|
|
||||||
this.repository = RepositoryManager.getRepository();
|
|
||||||
this.deployer = Common.getTestAccount(repository, "alice");
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@After
|
|
||||||
public void after() throws DataException {
|
|
||||||
if (this.repository != null)
|
|
||||||
this.repository.close();
|
|
||||||
|
|
||||||
this.repository = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testGetAccountBlocksMintedFromAddress() throws DataException {
|
|
||||||
Account alice = Common.getTestAccount(repository, "alice");
|
|
||||||
byte[] accountBytes = Bytes.ensureCapacity(Base58.decode(alice.getAddress()), 32, 0);
|
|
||||||
|
|
||||||
this.creationBytes = buildGetAccountBlocksMintedAT(accountBytes);
|
|
||||||
|
|
||||||
this.deployAtTransaction = AtUtils.doDeployAT(repository, deployer, creationBytes, fundingAmount);
|
|
||||||
this.atAddress = deployAtTransaction.getATAccount().getAddress();
|
|
||||||
|
|
||||||
// Mint a block to allow AT to run - Alice's blocksMinted is incremented AFTER block is processed / AT is run
|
|
||||||
Integer expectedBlocksMinted = alice.getBlocksMinted();
|
|
||||||
BlockUtils.mintBlock(repository);
|
|
||||||
|
|
||||||
Integer extractedBlocksMinted = extractBlocksMinted(repository, atAddress);
|
|
||||||
assertEquals(expectedBlocksMinted, extractedBlocksMinted);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testGetAccountBlocksMintedFromPublicKey() throws DataException {
|
|
||||||
TestAccount alice = Common.getTestAccount(repository, "alice");
|
|
||||||
byte[] accountBytes = alice.getPublicKey();
|
|
||||||
|
|
||||||
this.creationBytes = buildGetAccountBlocksMintedAT(accountBytes);
|
|
||||||
|
|
||||||
this.deployAtTransaction = AtUtils.doDeployAT(repository, deployer, creationBytes, fundingAmount);
|
|
||||||
this.atAddress = deployAtTransaction.getATAccount().getAddress();
|
|
||||||
|
|
||||||
// Mint a block to allow AT to run - Alice's blocksMinted is incremented AFTER block is processed / AT is run
|
|
||||||
Integer expectedBlocksMinted = alice.getBlocksMinted();
|
|
||||||
BlockUtils.mintBlock(repository);
|
|
||||||
|
|
||||||
Integer extractedBlocksMinted = extractBlocksMinted(repository, atAddress);
|
|
||||||
assertEquals(expectedBlocksMinted, extractedBlocksMinted);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testGetUnknownAccountBlocksMinted() throws DataException {
|
|
||||||
byte[] accountBytes = new byte[32];
|
|
||||||
RANDOM.nextBytes(accountBytes);
|
|
||||||
|
|
||||||
this.creationBytes = buildGetAccountBlocksMintedAT(accountBytes);
|
|
||||||
|
|
||||||
this.deployAtTransaction = AtUtils.doDeployAT(repository, deployer, creationBytes, fundingAmount);
|
|
||||||
this.atAddress = deployAtTransaction.getATAccount().getAddress();
|
|
||||||
|
|
||||||
// Mint a block to allow AT to run - Alice's blocksMinted is incremented AFTER block is processed / AT is run
|
|
||||||
BlockUtils.mintBlock(repository);
|
|
||||||
|
|
||||||
Integer extractedBlocksMinted = extractBlocksMinted(repository, atAddress);
|
|
||||||
assertNull(extractedBlocksMinted);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static byte[] buildGetAccountBlocksMintedAT(byte[] accountBytes) {
|
|
||||||
// Labels for data segment addresses
|
|
||||||
int addrCounter = 0;
|
|
||||||
|
|
||||||
// Beginning of data segment for easy extraction
|
|
||||||
final int addrBlocksMinted = addrCounter++;
|
|
||||||
|
|
||||||
// accountBytes
|
|
||||||
final int addrAccountBytes = addrCounter;
|
|
||||||
addrCounter += 4;
|
|
||||||
|
|
||||||
// Pointer to accountBytes so we can load them into B
|
|
||||||
final int addrAccountBytesPointer = addrCounter++;
|
|
||||||
|
|
||||||
// Data segment
|
|
||||||
ByteBuffer dataByteBuffer = ByteBuffer.allocate(addrCounter * MachineState.VALUE_SIZE);
|
|
||||||
|
|
||||||
// Write accountBytes
|
|
||||||
dataByteBuffer.position(addrAccountBytes * MachineState.VALUE_SIZE);
|
|
||||||
dataByteBuffer.put(accountBytes);
|
|
||||||
|
|
||||||
// Store pointer to addrAccountbytes at addrAccountBytesPointer
|
|
||||||
assertEquals(addrAccountBytesPointer * MachineState.VALUE_SIZE, dataByteBuffer.position());
|
|
||||||
dataByteBuffer.putLong(addrAccountBytes);
|
|
||||||
|
|
||||||
ByteBuffer codeByteBuffer = ByteBuffer.allocate(512);
|
|
||||||
|
|
||||||
// Two-pass version
|
|
||||||
for (int pass = 0; pass < 2; ++pass) {
|
|
||||||
codeByteBuffer.clear();
|
|
||||||
|
|
||||||
try {
|
|
||||||
/* Initialization */
|
|
||||||
|
|
||||||
// Copy accountBytes from data segment into B, starting at addrAccountBytes (as pointed to by addrAccountBytesPointer)
|
|
||||||
codeByteBuffer.put(OpCode.EXT_FUN_DAT.compile(FunctionCode.SET_B_IND, addrAccountBytesPointer));
|
|
||||||
|
|
||||||
// Get account's blocks minted count and save into addrBlocksMinted
|
|
||||||
codeByteBuffer.put(OpCode.EXT_FUN_RET.compile(QortalFunctionCode.GET_BLOCKS_MINTED_FROM_ACCOUNT_IN_B.value, addrBlocksMinted));
|
|
||||||
|
|
||||||
// We're done
|
|
||||||
codeByteBuffer.put(OpCode.FIN_IMD.compile());
|
|
||||||
} catch (CompilationException e) {
|
|
||||||
throw new IllegalStateException("Unable to compile AT?", e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
codeByteBuffer.flip();
|
|
||||||
|
|
||||||
byte[] codeBytes = new byte[codeByteBuffer.limit()];
|
|
||||||
codeByteBuffer.get(codeBytes);
|
|
||||||
|
|
||||||
final short ciyamAtVersion = 2;
|
|
||||||
final short numCallStackPages = 0;
|
|
||||||
final short numUserStackPages = 0;
|
|
||||||
final long minActivationAmount = 0L;
|
|
||||||
|
|
||||||
return MachineState.toCreationBytes(ciyamAtVersion, codeBytes, dataByteBuffer.array(), numCallStackPages, numUserStackPages, minActivationAmount);
|
|
||||||
}
|
|
||||||
|
|
||||||
private Integer extractBlocksMinted(Repository repository, String atAddress) throws DataException {
|
|
||||||
// Check AT result
|
|
||||||
ATStateData atStateData = repository.getATRepository().getLatestATState(atAddress);
|
|
||||||
byte[] stateData = atStateData.getStateData();
|
|
||||||
|
|
||||||
byte[] dataBytes = MachineState.extractDataBytes(stateData);
|
|
||||||
|
|
||||||
Long blocksMintedValue = BitTwiddling.longFromBEBytes(dataBytes, 0);
|
|
||||||
if (blocksMintedValue == -1)
|
|
||||||
return null;
|
|
||||||
|
|
||||||
return blocksMintedValue.intValue();
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,184 +0,0 @@
|
|||||||
package org.qortal.test.at.qortalfunctioncodes;
|
|
||||||
|
|
||||||
import com.google.common.primitives.Bytes;
|
|
||||||
import org.ciyam.at.CompilationException;
|
|
||||||
import org.ciyam.at.FunctionCode;
|
|
||||||
import org.ciyam.at.MachineState;
|
|
||||||
import org.ciyam.at.OpCode;
|
|
||||||
import org.junit.After;
|
|
||||||
import org.junit.Before;
|
|
||||||
import org.junit.Test;
|
|
||||||
import org.qortal.account.Account;
|
|
||||||
import org.qortal.account.PrivateKeyAccount;
|
|
||||||
import org.qortal.at.QortalFunctionCode;
|
|
||||||
import org.qortal.data.at.ATStateData;
|
|
||||||
import org.qortal.repository.DataException;
|
|
||||||
import org.qortal.repository.Repository;
|
|
||||||
import org.qortal.repository.RepositoryManager;
|
|
||||||
import org.qortal.test.common.AtUtils;
|
|
||||||
import org.qortal.test.common.BlockUtils;
|
|
||||||
import org.qortal.test.common.Common;
|
|
||||||
import org.qortal.test.common.TestAccount;
|
|
||||||
import org.qortal.transaction.DeployAtTransaction;
|
|
||||||
import org.qortal.utils.Base58;
|
|
||||||
import org.qortal.utils.BitTwiddling;
|
|
||||||
|
|
||||||
import java.nio.ByteBuffer;
|
|
||||||
import java.util.Random;
|
|
||||||
|
|
||||||
import static org.junit.Assert.assertEquals;
|
|
||||||
import static org.junit.Assert.assertNull;
|
|
||||||
|
|
||||||
public class GetAccountLevelTests extends Common {
|
|
||||||
|
|
||||||
private static final Random RANDOM = new Random();
|
|
||||||
private static final long fundingAmount = 1_00000000L;
|
|
||||||
|
|
||||||
private Repository repository = null;
|
|
||||||
private byte[] creationBytes = null;
|
|
||||||
private PrivateKeyAccount deployer;
|
|
||||||
private DeployAtTransaction deployAtTransaction;
|
|
||||||
private String atAddress;
|
|
||||||
|
|
||||||
@Before
|
|
||||||
public void before() throws DataException {
|
|
||||||
Common.useDefaultSettings();
|
|
||||||
|
|
||||||
this.repository = RepositoryManager.getRepository();
|
|
||||||
this.deployer = Common.getTestAccount(repository, "alice");
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@After
|
|
||||||
public void after() throws DataException {
|
|
||||||
if (this.repository != null)
|
|
||||||
this.repository.close();
|
|
||||||
|
|
||||||
this.repository = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testGetAccountLevelFromAddress() throws DataException {
|
|
||||||
Account dilbert = Common.getTestAccount(repository, "dilbert");
|
|
||||||
byte[] accountBytes = Bytes.ensureCapacity(Base58.decode(dilbert.getAddress()), 32, 0);
|
|
||||||
|
|
||||||
this.creationBytes = buildGetAccountLevelAT(accountBytes);
|
|
||||||
|
|
||||||
this.deployAtTransaction = AtUtils.doDeployAT(repository, deployer, creationBytes, fundingAmount);
|
|
||||||
this.atAddress = deployAtTransaction.getATAccount().getAddress();
|
|
||||||
|
|
||||||
// Mint a block to allow AT to run
|
|
||||||
BlockUtils.mintBlock(repository);
|
|
||||||
|
|
||||||
Integer extractedAccountLevel = extractAccountLevel(repository, atAddress);
|
|
||||||
assertEquals(dilbert.getLevel(), extractedAccountLevel);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testGetAccountLevelFromPublicKey() throws DataException {
|
|
||||||
TestAccount dilbert = Common.getTestAccount(repository, "dilbert");
|
|
||||||
byte[] accountBytes = dilbert.getPublicKey();
|
|
||||||
|
|
||||||
this.creationBytes = buildGetAccountLevelAT(accountBytes);
|
|
||||||
|
|
||||||
this.deployAtTransaction = AtUtils.doDeployAT(repository, deployer, creationBytes, fundingAmount);
|
|
||||||
this.atAddress = deployAtTransaction.getATAccount().getAddress();
|
|
||||||
|
|
||||||
// Mint a block to allow AT to run
|
|
||||||
BlockUtils.mintBlock(repository);
|
|
||||||
|
|
||||||
Integer extractedAccountLevel = extractAccountLevel(repository, atAddress);
|
|
||||||
assertEquals(dilbert.getLevel(), extractedAccountLevel);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testGetUnknownAccountLevel() throws DataException {
|
|
||||||
byte[] accountBytes = new byte[32];
|
|
||||||
RANDOM.nextBytes(accountBytes);
|
|
||||||
|
|
||||||
this.creationBytes = buildGetAccountLevelAT(accountBytes);
|
|
||||||
|
|
||||||
this.deployAtTransaction = AtUtils.doDeployAT(repository, deployer, creationBytes, fundingAmount);
|
|
||||||
this.atAddress = deployAtTransaction.getATAccount().getAddress();
|
|
||||||
|
|
||||||
// Mint a block to allow AT to run
|
|
||||||
BlockUtils.mintBlock(repository);
|
|
||||||
|
|
||||||
Integer extractedAccountLevel = extractAccountLevel(repository, atAddress);
|
|
||||||
assertNull(extractedAccountLevel);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static byte[] buildGetAccountLevelAT(byte[] accountBytes) {
|
|
||||||
// Labels for data segment addresses
|
|
||||||
int addrCounter = 0;
|
|
||||||
|
|
||||||
// Beginning of data segment for easy extraction
|
|
||||||
final int addrAccountLevel = addrCounter++;
|
|
||||||
|
|
||||||
// accountBytes
|
|
||||||
final int addrAccountBytes = addrCounter;
|
|
||||||
addrCounter += 4;
|
|
||||||
|
|
||||||
// Pointer to accountBytes so we can load them into B
|
|
||||||
final int addrAccountBytesPointer = addrCounter++;
|
|
||||||
|
|
||||||
// Data segment
|
|
||||||
ByteBuffer dataByteBuffer = ByteBuffer.allocate(addrCounter * MachineState.VALUE_SIZE);
|
|
||||||
|
|
||||||
// Write accountBytes
|
|
||||||
dataByteBuffer.position(addrAccountBytes * MachineState.VALUE_SIZE);
|
|
||||||
dataByteBuffer.put(accountBytes);
|
|
||||||
|
|
||||||
// Store pointer to addrAccountbytes at addrAccountBytesPointer
|
|
||||||
assertEquals(addrAccountBytesPointer * MachineState.VALUE_SIZE, dataByteBuffer.position());
|
|
||||||
dataByteBuffer.putLong(addrAccountBytes);
|
|
||||||
|
|
||||||
ByteBuffer codeByteBuffer = ByteBuffer.allocate(512);
|
|
||||||
|
|
||||||
// Two-pass version
|
|
||||||
for (int pass = 0; pass < 2; ++pass) {
|
|
||||||
codeByteBuffer.clear();
|
|
||||||
|
|
||||||
try {
|
|
||||||
/* Initialization */
|
|
||||||
|
|
||||||
// Copy accountBytes from data segment into B, starting at addrAccountBytes (as pointed to by addrAccountBytesPointer)
|
|
||||||
codeByteBuffer.put(OpCode.EXT_FUN_DAT.compile(FunctionCode.SET_B_IND, addrAccountBytesPointer));
|
|
||||||
|
|
||||||
// Get account level and save into addrAccountLevel
|
|
||||||
codeByteBuffer.put(OpCode.EXT_FUN_RET.compile(QortalFunctionCode.GET_ACCOUNT_LEVEL_FROM_ACCOUNT_IN_B.value, addrAccountLevel));
|
|
||||||
|
|
||||||
// We're done
|
|
||||||
codeByteBuffer.put(OpCode.FIN_IMD.compile());
|
|
||||||
} catch (CompilationException e) {
|
|
||||||
throw new IllegalStateException("Unable to compile AT?", e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
codeByteBuffer.flip();
|
|
||||||
|
|
||||||
byte[] codeBytes = new byte[codeByteBuffer.limit()];
|
|
||||||
codeByteBuffer.get(codeBytes);
|
|
||||||
|
|
||||||
final short ciyamAtVersion = 2;
|
|
||||||
final short numCallStackPages = 0;
|
|
||||||
final short numUserStackPages = 0;
|
|
||||||
final long minActivationAmount = 0L;
|
|
||||||
|
|
||||||
return MachineState.toCreationBytes(ciyamAtVersion, codeBytes, dataByteBuffer.array(), numCallStackPages, numUserStackPages, minActivationAmount);
|
|
||||||
}
|
|
||||||
|
|
||||||
private Integer extractAccountLevel(Repository repository, String atAddress) throws DataException {
|
|
||||||
// Check AT result
|
|
||||||
ATStateData atStateData = repository.getATRepository().getLatestATState(atAddress);
|
|
||||||
byte[] stateData = atStateData.getStateData();
|
|
||||||
|
|
||||||
byte[] dataBytes = MachineState.extractDataBytes(stateData);
|
|
||||||
|
|
||||||
Long accountLevelValue = BitTwiddling.longFromBEBytes(dataBytes, 0);
|
|
||||||
if (accountLevelValue == -1)
|
|
||||||
return null;
|
|
||||||
|
|
||||||
return accountLevelValue.intValue();
|
|
||||||
}
|
|
||||||
}
|
|
Loading…
x
Reference in New Issue
Block a user