forked from Qortal/qortal
Repository work
Rolled BlockTransactionRepository into BlockRepository. Added AccountRepository for general account info and account balances. BlockTransformer now takes Block as param instead of BlockData as it needs Block's transactions.
This commit is contained in:
parent
d45c33fe90
commit
37d9bcbb53
38
src/data/account/AccountBalanceData.java
Normal file
38
src/data/account/AccountBalanceData.java
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
package data.account;
|
||||||
|
|
||||||
|
import java.math.BigDecimal;
|
||||||
|
|
||||||
|
public class AccountBalanceData {
|
||||||
|
|
||||||
|
// Properties
|
||||||
|
protected String address;
|
||||||
|
protected long assetId;
|
||||||
|
protected BigDecimal balance;
|
||||||
|
|
||||||
|
// Constructors
|
||||||
|
|
||||||
|
public AccountBalanceData(String address, long assetId, BigDecimal balance) {
|
||||||
|
this.address = address;
|
||||||
|
this.assetId = assetId;
|
||||||
|
this.balance = balance;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Getters/Setters
|
||||||
|
|
||||||
|
public String getAddress() {
|
||||||
|
return this.address;
|
||||||
|
}
|
||||||
|
|
||||||
|
public long getAssetId() {
|
||||||
|
return this.assetId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public BigDecimal getBalance() {
|
||||||
|
return this.balance;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setBalance(BigDecimal balance) {
|
||||||
|
this.balance = balance;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -8,11 +8,13 @@ public class AccountData {
|
|||||||
|
|
||||||
// Constructors
|
// Constructors
|
||||||
|
|
||||||
protected AccountData() {
|
public AccountData(String address, byte[] reference) {
|
||||||
|
this.address = address;
|
||||||
|
this.reference = reference;
|
||||||
}
|
}
|
||||||
|
|
||||||
public AccountData(String address) {
|
public AccountData(String address) {
|
||||||
this.address = address;
|
this(address, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Getters/Setters
|
// Getters/Setters
|
||||||
|
@ -1,35 +1,31 @@
|
|||||||
package qora.account;
|
package qora.account;
|
||||||
|
|
||||||
import java.math.BigDecimal;
|
import java.math.BigDecimal;
|
||||||
import java.sql.ResultSet;
|
|
||||||
import java.sql.SQLException;
|
|
||||||
|
|
||||||
import database.DB;
|
import data.account.AccountBalanceData;
|
||||||
import repository.hsqldb.HSQLDBSaver;
|
import data.account.AccountData;
|
||||||
|
import repository.DataException;
|
||||||
|
import repository.Repository;
|
||||||
|
|
||||||
public class Account {
|
public class Account {
|
||||||
|
|
||||||
public static final int ADDRESS_LENGTH = 25;
|
public static final int ADDRESS_LENGTH = 25;
|
||||||
|
|
||||||
protected String address;
|
protected Repository repository;
|
||||||
|
protected AccountData accountData;
|
||||||
|
|
||||||
protected Account() {
|
protected Account() {
|
||||||
}
|
}
|
||||||
|
|
||||||
public Account(String address) {
|
public Account(Repository repository, String address) throws DataException {
|
||||||
this.address = address;
|
this.repository = repository;
|
||||||
|
this.accountData = this.repository.getAccountRepository().getAccount(address);
|
||||||
|
if (this.accountData == null)
|
||||||
|
this.accountData = new AccountData(address);
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getAddress() {
|
public String getAddress() {
|
||||||
return this.address;
|
return this.accountData.getAddress();
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean equals(Object b) {
|
|
||||||
if (!(b instanceof Account))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
return this.getAddress().equals(((Account) b).getAddress());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Balance manipulations - assetId is 0 for QORA
|
// Balance manipulations - assetId is 0 for QORA
|
||||||
@ -39,22 +35,21 @@ public class Account {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public BigDecimal getConfirmedBalance(long assetId) throws SQLException {
|
public BigDecimal getConfirmedBalance(long assetId) throws DataException {
|
||||||
ResultSet resultSet = DB.checkedExecute("SELECT balance FROM AccountBalances WHERE account = ? and asset_id = ?", this.getAddress(), assetId);
|
AccountBalanceData accountBalanceData = this.repository.getAccountRepository().getBalance(this.accountData.getAddress(), assetId);
|
||||||
if (resultSet == null)
|
if (accountBalanceData == null)
|
||||||
return BigDecimal.ZERO.setScale(8);
|
return BigDecimal.ZERO.setScale(8);
|
||||||
|
|
||||||
return resultSet.getBigDecimal(1);
|
return accountBalanceData.getBalance();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setConfirmedBalance(long assetId, BigDecimal balance) throws SQLException {
|
public void setConfirmedBalance(long assetId, BigDecimal balance) throws DataException {
|
||||||
HSQLDBSaver saveHelper = new HSQLDBSaver("AccountBalances");
|
AccountBalanceData accountBalanceData = new AccountBalanceData(this.accountData.getAddress(), assetId, balance);
|
||||||
saveHelper.bind("account", this.getAddress()).bind("asset_id", assetId).bind("balance", balance);
|
this.repository.getAccountRepository().save(accountBalanceData);
|
||||||
saveHelper.execute();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void deleteBalance(long assetId) throws SQLException {
|
public void deleteBalance(long assetId) throws DataException {
|
||||||
DB.checkedExecute("DELETE FROM AccountBalances WHERE account = ? and asset_id = ?", this.getAddress(), assetId);
|
this.repository.getAccountRepository().delete(this.accountData.getAddress(), assetId);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Reference manipulations
|
// Reference manipulations
|
||||||
@ -63,14 +58,14 @@ public class Account {
|
|||||||
* Fetch last reference for account.
|
* Fetch last reference for account.
|
||||||
*
|
*
|
||||||
* @return byte[] reference, or null if no reference or account not found.
|
* @return byte[] reference, or null if no reference or account not found.
|
||||||
* @throws SQLException
|
* @throws DataException
|
||||||
*/
|
*/
|
||||||
public byte[] getLastReference() throws SQLException {
|
public byte[] getLastReference() throws DataException {
|
||||||
ResultSet resultSet = DB.checkedExecute("SELECT reference FROM Accounts WHERE account = ?", this.getAddress());
|
AccountData accountData = this.repository.getAccountRepository().getAccount(this.accountData.getAddress());
|
||||||
if (resultSet == null)
|
if (accountData == null)
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
return DB.getResultSetBytes(resultSet.getBinaryStream(1));
|
return accountData.getReference();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -78,12 +73,10 @@ public class Account {
|
|||||||
*
|
*
|
||||||
* @param reference
|
* @param reference
|
||||||
* -- null allowed
|
* -- null allowed
|
||||||
* @throws SQLException
|
* @throws DataException
|
||||||
*/
|
*/
|
||||||
public void setLastReference(byte[] reference) throws SQLException {
|
public void setLastReference(byte[] reference) throws DataException {
|
||||||
HSQLDBSaver saveHelper = new HSQLDBSaver("Accounts");
|
this.repository.getAccountRepository().save(accountData);
|
||||||
saveHelper.bind("account", this.getAddress()).bind("reference", reference);
|
|
||||||
saveHelper.execute();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -231,7 +231,7 @@ public class Block {
|
|||||||
|
|
||||||
// Check there is space in block
|
// Check there is space in block
|
||||||
try {
|
try {
|
||||||
if (BlockTransformer.getDataLength(this.blockData) + TransactionTransformer.getDataLength(transactionData) > MAX_BLOCK_BYTES)
|
if (BlockTransformer.getDataLength(this) + TransactionTransformer.getDataLength(transactionData) > MAX_BLOCK_BYTES)
|
||||||
return false;
|
return false;
|
||||||
} catch (TransformationException e) {
|
} catch (TransformationException e) {
|
||||||
return false;
|
return false;
|
||||||
@ -436,7 +436,7 @@ public class Block {
|
|||||||
|
|
||||||
// Link transaction to this block
|
// Link transaction to this block
|
||||||
BlockTransactionData blockTransactionData = new BlockTransactionData(this.getSignature(), sequence, transaction.getTransactionData().getSignature());
|
BlockTransactionData blockTransactionData = new BlockTransactionData(this.getSignature(), sequence, transaction.getTransactionData().getSignature());
|
||||||
this.repository.getBlockTransactionRepository().save(blockTransactionData);
|
this.repository.getBlockRepository().save(blockTransactionData);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -20,7 +20,7 @@ import qora.assets.Order;
|
|||||||
import repository.hsqldb.HSQLDBSaver;
|
import repository.hsqldb.HSQLDBSaver;
|
||||||
import transform.TransformationException;
|
import transform.TransformationException;
|
||||||
|
|
||||||
public class CreateOrderTransaction extends TransactionHandler {
|
public class CreateOrderTransaction extends Transaction {
|
||||||
|
|
||||||
// Properties
|
// Properties
|
||||||
private Order order;
|
private Order order;
|
||||||
|
22
src/repository/AccountRepository.java
Normal file
22
src/repository/AccountRepository.java
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
package repository;
|
||||||
|
|
||||||
|
import data.account.AccountBalanceData;
|
||||||
|
import data.account.AccountData;
|
||||||
|
|
||||||
|
public interface AccountRepository {
|
||||||
|
|
||||||
|
// General account
|
||||||
|
|
||||||
|
public AccountData getAccount(String address) throws DataException;
|
||||||
|
|
||||||
|
public void save(AccountData accountData) throws DataException;
|
||||||
|
|
||||||
|
// Account balances
|
||||||
|
|
||||||
|
public AccountBalanceData getBalance(String address, long assetId) throws DataException;
|
||||||
|
|
||||||
|
public void save(AccountBalanceData accountBalanceData) throws DataException;
|
||||||
|
|
||||||
|
public void delete(String address, long assetId) throws DataException;
|
||||||
|
|
||||||
|
}
|
@ -3,6 +3,7 @@ package repository;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import data.block.BlockData;
|
import data.block.BlockData;
|
||||||
|
import data.block.BlockTransactionData;
|
||||||
import data.transaction.TransactionData;
|
import data.transaction.TransactionData;
|
||||||
|
|
||||||
public interface BlockRepository {
|
public interface BlockRepository {
|
||||||
@ -17,4 +18,6 @@ public interface BlockRepository {
|
|||||||
|
|
||||||
public void save(BlockData blockData) throws DataException;
|
public void save(BlockData blockData) throws DataException;
|
||||||
|
|
||||||
|
public void save(BlockTransactionData blockTransactionData) throws DataException;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1,9 +0,0 @@
|
|||||||
package repository;
|
|
||||||
|
|
||||||
import data.block.BlockTransactionData;
|
|
||||||
|
|
||||||
public interface BlockTransactionRepository {
|
|
||||||
|
|
||||||
public void save(BlockTransactionData blockTransactionData) throws DataException;
|
|
||||||
|
|
||||||
}
|
|
@ -4,10 +4,10 @@ public class DataException extends Exception {
|
|||||||
|
|
||||||
private static final long serialVersionUID = -3963965667288257605L;
|
private static final long serialVersionUID = -3963965667288257605L;
|
||||||
|
|
||||||
public DataException() {}
|
public DataException() {
|
||||||
|
}
|
||||||
|
|
||||||
public DataException(String message)
|
public DataException(String message) {
|
||||||
{
|
|
||||||
super(message);
|
super(message);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2,9 +2,9 @@ package repository;
|
|||||||
|
|
||||||
public interface Repository {
|
public interface Repository {
|
||||||
|
|
||||||
public BlockRepository getBlockRepository();
|
public AccountRepository getAccountRepository();
|
||||||
|
|
||||||
public BlockTransactionRepository getBlockTransactionRepository();
|
public BlockRepository getBlockRepository();
|
||||||
|
|
||||||
public TransactionRepository getTransactionRepository();
|
public TransactionRepository getTransactionRepository();
|
||||||
|
|
||||||
|
77
src/repository/hsqldb/HSQLDBAccountRepository.java
Normal file
77
src/repository/hsqldb/HSQLDBAccountRepository.java
Normal file
@ -0,0 +1,77 @@
|
|||||||
|
package repository.hsqldb;
|
||||||
|
|
||||||
|
import java.math.BigDecimal;
|
||||||
|
import java.sql.ResultSet;
|
||||||
|
import java.sql.SQLException;
|
||||||
|
|
||||||
|
import data.account.AccountBalanceData;
|
||||||
|
import data.account.AccountData;
|
||||||
|
import repository.AccountRepository;
|
||||||
|
import repository.DataException;
|
||||||
|
|
||||||
|
public class HSQLDBAccountRepository implements AccountRepository {
|
||||||
|
|
||||||
|
protected HSQLDBRepository repository;
|
||||||
|
|
||||||
|
public HSQLDBAccountRepository(HSQLDBRepository repository) {
|
||||||
|
this.repository = repository;
|
||||||
|
}
|
||||||
|
|
||||||
|
public AccountData getAccount(String address) throws DataException {
|
||||||
|
try {
|
||||||
|
ResultSet resultSet = this.repository.checkedExecute("SELECT reference FROM Accounts WHERE account = ?", address);
|
||||||
|
if (resultSet == null)
|
||||||
|
return null;
|
||||||
|
|
||||||
|
return new AccountData(address, this.repository.getResultSetBytes(resultSet.getBinaryStream(1)));
|
||||||
|
} catch (SQLException e) {
|
||||||
|
throw new DataException("Unable to fetch account info from repository", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void save(AccountData accountData) throws DataException {
|
||||||
|
HSQLDBSaver saveHelper = new HSQLDBSaver("Accounts");
|
||||||
|
saveHelper.bind("account", accountData.getAddress()).bind("reference", accountData.getReference());
|
||||||
|
|
||||||
|
try {
|
||||||
|
saveHelper.execute(this.repository.connection);
|
||||||
|
} catch (SQLException e) {
|
||||||
|
throw new DataException("Unable to save account info into repository", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public AccountBalanceData getBalance(String address, long assetId) throws DataException {
|
||||||
|
try {
|
||||||
|
ResultSet resultSet = this.repository.checkedExecute("SELECT balance FROM AccountBalances WHERE account = ? and asset_id = ?", address, assetId);
|
||||||
|
if (resultSet == null)
|
||||||
|
return null;
|
||||||
|
|
||||||
|
BigDecimal balance = resultSet.getBigDecimal(1).setScale(8);
|
||||||
|
|
||||||
|
return new AccountBalanceData(address, assetId, balance);
|
||||||
|
} catch (SQLException e) {
|
||||||
|
throw new DataException("Unable to fetch account balance from repository", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void save(AccountBalanceData accountBalanceData) throws DataException {
|
||||||
|
HSQLDBSaver saveHelper = new HSQLDBSaver("AccountBalances");
|
||||||
|
saveHelper.bind("account", accountBalanceData.getAddress()).bind("asset_id", accountBalanceData.getAssetId()).bind("balance",
|
||||||
|
accountBalanceData.getBalance());
|
||||||
|
|
||||||
|
try {
|
||||||
|
saveHelper.execute(this.repository.connection);
|
||||||
|
} catch (SQLException e) {
|
||||||
|
throw new DataException("Unable to save account balance into repository", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void delete(String address, long assetId) throws DataException {
|
||||||
|
try {
|
||||||
|
this.repository.checkedExecute("DELETE FROM AccountBalances WHERE account = ? and asset_id = ?", address, assetId);
|
||||||
|
} catch (SQLException e) {
|
||||||
|
throw new DataException("Unable to delete account balance from repository", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -8,6 +8,7 @@ import java.util.ArrayList;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import data.block.BlockData;
|
import data.block.BlockData;
|
||||||
|
import data.block.BlockTransactionData;
|
||||||
import data.transaction.TransactionData;
|
import data.transaction.TransactionData;
|
||||||
import repository.BlockRepository;
|
import repository.BlockRepository;
|
||||||
import repository.DataException;
|
import repository.DataException;
|
||||||
@ -115,4 +116,16 @@ public class HSQLDBBlockRepository implements BlockRepository {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void save(BlockTransactionData blockTransactionData) throws DataException {
|
||||||
|
HSQLDBSaver saveHelper = new HSQLDBSaver("BlockTransactions");
|
||||||
|
saveHelper.bind("block_signature", blockTransactionData.getBlockSignature()).bind("sequence", blockTransactionData.getSequence())
|
||||||
|
.bind("transaction_signature", blockTransactionData.getTransactionSignature());
|
||||||
|
|
||||||
|
try {
|
||||||
|
saveHelper.execute(this.repository.connection);
|
||||||
|
} catch (SQLException e) {
|
||||||
|
throw new DataException("Unable to save BlockTransaction into repository", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1,29 +0,0 @@
|
|||||||
package repository.hsqldb;
|
|
||||||
|
|
||||||
import java.sql.SQLException;
|
|
||||||
|
|
||||||
import data.block.BlockTransactionData;
|
|
||||||
import repository.BlockTransactionRepository;
|
|
||||||
import repository.DataException;
|
|
||||||
|
|
||||||
public class HSQLDBBlockTransactionRepository implements BlockTransactionRepository {
|
|
||||||
|
|
||||||
protected HSQLDBRepository repository;
|
|
||||||
|
|
||||||
public HSQLDBBlockTransactionRepository(HSQLDBRepository repository) {
|
|
||||||
this.repository = repository;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void save(BlockTransactionData blockTransactionData) throws DataException {
|
|
||||||
HSQLDBSaver saveHelper = new HSQLDBSaver("BlockTransactions");
|
|
||||||
saveHelper.bind("block_signature", blockTransactionData.getBlockSignature()).bind("sequence", blockTransactionData.getSequence())
|
|
||||||
.bind("transaction_signature", blockTransactionData.getTransactionSignature());
|
|
||||||
|
|
||||||
try {
|
|
||||||
saveHelper.execute(this.repository.connection);
|
|
||||||
} catch (SQLException e) {
|
|
||||||
throw new DataException("Unable to save BlockTransaction into repository", e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -8,8 +8,8 @@ import java.sql.PreparedStatement;
|
|||||||
import java.sql.ResultSet;
|
import java.sql.ResultSet;
|
||||||
import java.sql.SQLException;
|
import java.sql.SQLException;
|
||||||
|
|
||||||
|
import repository.AccountRepository;
|
||||||
import repository.BlockRepository;
|
import repository.BlockRepository;
|
||||||
import repository.BlockTransactionRepository;
|
|
||||||
import repository.DataException;
|
import repository.DataException;
|
||||||
import repository.Repository;
|
import repository.Repository;
|
||||||
import repository.TransactionRepository;
|
import repository.TransactionRepository;
|
||||||
@ -24,13 +24,13 @@ public class HSQLDBRepository implements Repository {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public BlockRepository getBlockRepository() {
|
public AccountRepository getAccountRepository() {
|
||||||
return new HSQLDBBlockRepository(this);
|
return new HSQLDBAccountRepository(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public BlockTransactionRepository getBlockTransactionRepository() {
|
public BlockRepository getBlockRepository() {
|
||||||
return new HSQLDBBlockTransactionRepository(this);
|
return new HSQLDBBlockRepository(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -1,14 +1,22 @@
|
|||||||
package transform;
|
package transform;
|
||||||
|
|
||||||
@SuppressWarnings("serial")
|
|
||||||
public class TransformationException extends Exception {
|
public class TransformationException extends Exception {
|
||||||
|
|
||||||
|
private static final long serialVersionUID = 1132363278761469714L;
|
||||||
|
|
||||||
|
public TransformationException() {
|
||||||
|
}
|
||||||
|
|
||||||
public TransformationException(String message) {
|
public TransformationException(String message) {
|
||||||
super(message);
|
super(message);
|
||||||
}
|
}
|
||||||
|
|
||||||
public TransformationException(Exception e) {
|
public TransformationException(String message, Throwable cause) {
|
||||||
super(e);
|
super(message, cause);
|
||||||
|
}
|
||||||
|
|
||||||
|
public TransformationException(Throwable cause) {
|
||||||
|
super(cause);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -19,13 +19,17 @@ import com.google.common.primitives.Longs;
|
|||||||
import data.block.BlockData;
|
import data.block.BlockData;
|
||||||
import data.transaction.TransactionData;
|
import data.transaction.TransactionData;
|
||||||
import qora.account.PublicKeyAccount;
|
import qora.account.PublicKeyAccount;
|
||||||
|
import qora.assets.Order;
|
||||||
|
import qora.assets.Trade;
|
||||||
import qora.block.Block;
|
import qora.block.Block;
|
||||||
|
import qora.transaction.CreateOrderTransaction;
|
||||||
import qora.transaction.Transaction;
|
import qora.transaction.Transaction;
|
||||||
import repository.DataException;
|
import repository.DataException;
|
||||||
import transform.TransformationException;
|
import transform.TransformationException;
|
||||||
import transform.Transformer;
|
import transform.Transformer;
|
||||||
import transform.transaction.TransactionTransformer;
|
import transform.transaction.TransactionTransformer;
|
||||||
import utils.Base58;
|
import utils.Base58;
|
||||||
|
import utils.Pair;
|
||||||
import utils.Serialization;
|
import utils.Serialization;
|
||||||
|
|
||||||
public class BlockTransformer extends Transformer {
|
public class BlockTransformer extends Transformer {
|
||||||
@ -48,7 +52,14 @@ public class BlockTransformer extends Transformer {
|
|||||||
protected static final int AT_FEES_LENGTH = LONG_LENGTH;
|
protected static final int AT_FEES_LENGTH = LONG_LENGTH;
|
||||||
protected static final int AT_LENGTH = AT_FEES_LENGTH + AT_BYTES_LENGTH;
|
protected static final int AT_LENGTH = AT_FEES_LENGTH + AT_BYTES_LENGTH;
|
||||||
|
|
||||||
public static BlockData fromBytes(byte[] bytes) throws TransformationException {
|
/**
|
||||||
|
* Extract block data and transaction data from serialized bytes.
|
||||||
|
*
|
||||||
|
* @param bytes
|
||||||
|
* @return BlockData and a List of transactions.
|
||||||
|
* @throws TransformationException
|
||||||
|
*/
|
||||||
|
public static Pair<BlockData, List<TransactionData>> fromBytes(byte[] bytes) throws TransformationException {
|
||||||
if (bytes == null)
|
if (bytes == null)
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
@ -91,8 +102,9 @@ public class BlockTransformer extends Transformer {
|
|||||||
|
|
||||||
int transactionCount = byteBuffer.getInt();
|
int transactionCount = byteBuffer.getInt();
|
||||||
|
|
||||||
// Parse transactions now, compared to deferred parsing in Gen1, so we can throw ParseException if need be
|
// Parse transactions now, compared to deferred parsing in Gen1, so we can throw ParseException if need be.
|
||||||
List<TransactionData> transactions = new ArrayList<TransactionData>();
|
List<TransactionData> transactions = new ArrayList<TransactionData>();
|
||||||
|
BigDecimal totalFees = BigDecimal.ZERO.setScale(8);
|
||||||
for (int t = 0; t < transactionCount; ++t) {
|
for (int t = 0; t < transactionCount; ++t) {
|
||||||
if (byteBuffer.remaining() < TRANSACTION_SIZE_LENGTH)
|
if (byteBuffer.remaining() < TRANSACTION_SIZE_LENGTH)
|
||||||
throw new TransformationException("Byte data too short for Block Transaction length");
|
throw new TransformationException("Byte data too short for Block Transaction length");
|
||||||
@ -106,41 +118,50 @@ public class BlockTransformer extends Transformer {
|
|||||||
byte[] transactionBytes = new byte[transactionLength];
|
byte[] transactionBytes = new byte[transactionLength];
|
||||||
byteBuffer.get(transactionBytes);
|
byteBuffer.get(transactionBytes);
|
||||||
|
|
||||||
TransactionData transaction = TransactionTransformer.fromBytes(transactionBytes);
|
TransactionData transactionData = TransactionTransformer.fromBytes(transactionBytes);
|
||||||
transactions.add(transaction);
|
transactions.add(transactionData);
|
||||||
|
|
||||||
|
totalFees.add(transactionData.getFee());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (byteBuffer.hasRemaining())
|
if (byteBuffer.hasRemaining())
|
||||||
throw new TransformationException("Excess byte data found after parsing Block");
|
throw new TransformationException("Excess byte data found after parsing Block");
|
||||||
|
|
||||||
// XXX Can't return a simple BlockData object because it doesn't support holding the transactions
|
// XXX we don't know height!
|
||||||
// return new BlockData(version, reference, timestamp, generatingBalance, generatorPublicKey, generatorSignature, transactionsSignature, atBytes, atFees, transactions);
|
int height = 0;
|
||||||
return null;
|
BlockData blockData = new BlockData(version, reference, transactionCount, totalFees, transactionsSignature, height, timestamp, generatingBalance, generatorPublicKey, generatorSignature,
|
||||||
|
atBytes, atFees);
|
||||||
|
|
||||||
|
return new Pair<BlockData, List<TransactionData>>(blockData, transactions);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static int getDataLength(BlockData blockData) throws TransformationException {
|
public static int getDataLength(Block block) throws TransformationException {
|
||||||
// TODO
|
BlockData blockData = block.getBlockData();
|
||||||
int blockLength = BASE_LENGTH;
|
int blockLength = BASE_LENGTH;
|
||||||
|
|
||||||
if (blockData.getVersion() >= 2 && blockData.getAtBytes() != null)
|
if (blockData.getVersion() >= 2 && blockData.getAtBytes() != null)
|
||||||
blockLength += AT_FEES_LENGTH + AT_BYTES_LENGTH + blockData.getAtBytes().length;
|
blockLength += AT_FEES_LENGTH + AT_BYTES_LENGTH + blockData.getAtBytes().length;
|
||||||
|
|
||||||
/*
|
try {
|
||||||
* XXX Where do the transactions come from? A param? Do we pass a Block instead of BlockData?
|
|
||||||
// Short cut for no transactions
|
// Short cut for no transactions
|
||||||
if (block.getTransactions() == null || block.getTransactions().isEmpty())
|
List<Transaction> transactions = block.getTransactions();
|
||||||
|
if (transactions == null || transactions.isEmpty())
|
||||||
return blockLength;
|
return blockLength;
|
||||||
|
|
||||||
for (TransactionData transaction : this.transactions)
|
for (Transaction transaction : transactions)
|
||||||
blockLength += TRANSACTION_SIZE_LENGTH + transaction.getDataLength();
|
blockLength += TRANSACTION_SIZE_LENGTH + TransactionTransformer.getDataLength(transaction.getTransactionData());
|
||||||
*/
|
} catch (DataException e) {
|
||||||
|
throw new TransformationException("Unable to determine serialized block length", e);
|
||||||
|
}
|
||||||
|
|
||||||
return blockLength;
|
return blockLength;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static byte[] toBytes(BlockData blockData) throws TransformationException {
|
public static byte[] toBytes(Block block) throws TransformationException {
|
||||||
|
BlockData blockData = block.getBlockData();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
ByteArrayOutputStream bytes = new ByteArrayOutputStream(getDataLength(blockData));
|
ByteArrayOutputStream bytes = new ByteArrayOutputStream(getDataLength(block));
|
||||||
|
|
||||||
bytes.write(Ints.toByteArray(blockData.getVersion()));
|
bytes.write(Ints.toByteArray(blockData.getVersion()));
|
||||||
bytes.write(Longs.toByteArray(blockData.getTimestamp()));
|
bytes.write(Longs.toByteArray(blockData.getTimestamp()));
|
||||||
@ -168,22 +189,22 @@ public class BlockTransformer extends Transformer {
|
|||||||
// Transactions
|
// Transactions
|
||||||
bytes.write(Ints.toByteArray(blockData.getTransactionCount()));
|
bytes.write(Ints.toByteArray(blockData.getTransactionCount()));
|
||||||
|
|
||||||
/*
|
for (Transaction transaction : block.getTransactions()) {
|
||||||
* XXX Where do the transactions come from? A param? Do we pass a Block instead of BlockData?
|
TransactionData transactionData = transaction.getTransactionData();
|
||||||
for (TransactionData transaction : blockData.getTransactions()) {
|
bytes.write(Ints.toByteArray(TransactionTransformer.getDataLength(transactionData)));
|
||||||
bytes.write(Ints.toByteArray(transaction.getDataLength()));
|
bytes.write(TransactionTransformer.toBytes(transactionData));
|
||||||
bytes.write(transaction.toBytes());
|
|
||||||
}
|
}
|
||||||
*/
|
|
||||||
|
|
||||||
return bytes.toByteArray();
|
return bytes.toByteArray();
|
||||||
} catch (IOException e) {
|
} catch (IOException | DataException e) {
|
||||||
throw new RuntimeException(e);
|
throw new TransformationException("Unable to serialize block", e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
public static JSONObject toJSON(BlockData blockData) throws TransformationException {
|
public static JSONObject toJSON(Block block) throws TransformationException {
|
||||||
|
BlockData blockData = block.getBlockData();
|
||||||
|
|
||||||
JSONObject json = new JSONObject();
|
JSONObject json = new JSONObject();
|
||||||
|
|
||||||
json.put("version", blockData.getVersion());
|
json.put("version", blockData.getVersion());
|
||||||
@ -205,13 +226,12 @@ public class BlockTransformer extends Transformer {
|
|||||||
JSONArray transactionsJson = new JSONArray();
|
JSONArray transactionsJson = new JSONArray();
|
||||||
boolean tradesHappened = false;
|
boolean tradesHappened = false;
|
||||||
|
|
||||||
/*
|
try {
|
||||||
* XXX Where do the transactions come from? A param? Do we pass a Block instead of BlockData?
|
for (Transaction transaction : block.getTransactions()) {
|
||||||
for (TransactionData transaction : blockData.getTransactions()) {
|
transactionsJson.add(TransactionTransformer.toJSON(transaction.getTransactionData()));
|
||||||
transactionsJson.add(transaction.toJSON());
|
|
||||||
|
|
||||||
// If this is an asset CreateOrderTransaction then check to see if any trades happened
|
// If this is an asset CreateOrderTransaction then check to see if any trades happened
|
||||||
if (transaction.getType() == Transaction.TransactionType.CREATE_ASSET_ORDER) {
|
if (transaction.getTransactionData().getType() == Transaction.TransactionType.CREATE_ASSET_ORDER) {
|
||||||
CreateOrderTransaction orderTransaction = (CreateOrderTransaction) transaction;
|
CreateOrderTransaction orderTransaction = (CreateOrderTransaction) transaction;
|
||||||
Order order = orderTransaction.getOrder();
|
Order order = orderTransaction.getOrder();
|
||||||
List<Trade> trades = order.getTrades();
|
List<Trade> trades = order.getTrades();
|
||||||
@ -222,14 +242,15 @@ public class BlockTransformer extends Transformer {
|
|||||||
// Any trades left?
|
// Any trades left?
|
||||||
if (!trades.isEmpty()) {
|
if (!trades.isEmpty()) {
|
||||||
tradesHappened = true;
|
tradesHappened = true;
|
||||||
|
|
||||||
// No need to check any further
|
// No need to check any further
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} catch (DataException e) {
|
||||||
|
throw new TransformationException("Unable to transform block into JSON", e);
|
||||||
|
}
|
||||||
json.put("transactions", transactionsJson);
|
json.put("transactions", transactionsJson);
|
||||||
*/
|
|
||||||
|
|
||||||
// Add asset trade activity flag
|
// Add asset trade activity flag
|
||||||
json.put("assetTrades", tradesHappened);
|
json.put("assetTrades", tradesHappened);
|
||||||
@ -262,7 +283,8 @@ public class BlockTransformer extends Transformer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static byte[] getBytesForTransactionsSignature(Block block) throws TransformationException {
|
public static byte[] getBytesForTransactionsSignature(Block block) throws TransformationException {
|
||||||
ByteArrayOutputStream bytes = new ByteArrayOutputStream(GENERATOR_SIGNATURE_LENGTH + block.getBlockData().getTransactionCount() * TransactionTransformer.SIGNATURE_LENGTH);
|
ByteArrayOutputStream bytes = new ByteArrayOutputStream(
|
||||||
|
GENERATOR_SIGNATURE_LENGTH + block.getBlockData().getTransactionCount() * TransactionTransformer.SIGNATURE_LENGTH);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
bytes.write(block.getBlockData().getGeneratorSignature());
|
bytes.write(block.getBlockData().getGeneratorSignature());
|
||||||
|
Loading…
x
Reference in New Issue
Block a user