Fix for lint OutOfMemory error.
Finished implementing blockstore for android using ormlite.
This commit is contained in:
parent
b3afe42f38
commit
b36e784bd5
|
@ -80,6 +80,12 @@ public class MainActivity extends ActionBarActivity {
|
||||||
return super.onOptionsItemSelected(item);
|
return super.onOptionsItemSelected(item);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onDestroy() {
|
||||||
|
super.onDestroy();
|
||||||
|
ethereumManager.onDestroy();
|
||||||
|
}
|
||||||
|
|
||||||
// The definition of our task class
|
// The definition of our task class
|
||||||
private class PostTask extends AsyncTask<Context, Integer, String> {
|
private class PostTask extends AsyncTask<Context, Integer, String> {
|
||||||
|
|
||||||
|
|
|
@ -2,6 +2,8 @@ package org.ethereum.android;
|
||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
|
|
||||||
|
import com.j256.ormlite.android.apptools.OpenHelperManager;
|
||||||
|
|
||||||
import org.ethereum.android.di.modules.EthereumModule;
|
import org.ethereum.android.di.modules.EthereumModule;
|
||||||
import org.ethereum.android.di.components.DaggerEthereumComponent;
|
import org.ethereum.android.di.components.DaggerEthereumComponent;
|
||||||
import org.ethereum.config.SystemProperties;
|
import org.ethereum.config.SystemProperties;
|
||||||
|
@ -57,4 +59,8 @@ public class EthereumManager {
|
||||||
jsonRpcServer.start();
|
jsonRpcServer.start();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void onDestroy() {
|
||||||
|
OpenHelperManager.releaseHelper();
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,84 +0,0 @@
|
||||||
package org.ethereum.android.db;
|
|
||||||
|
|
||||||
|
|
||||||
import java.sql.SQLException;
|
|
||||||
|
|
||||||
import android.content.Context;
|
|
||||||
import android.database.sqlite.SQLiteDatabase;
|
|
||||||
import android.util.Log;
|
|
||||||
|
|
||||||
import com.j256.ormlite.android.apptools.OrmLiteSqliteOpenHelper;
|
|
||||||
import com.j256.ormlite.dao.Dao;
|
|
||||||
import com.j256.ormlite.support.ConnectionSource;
|
|
||||||
import com.j256.ormlite.table.TableUtils;
|
|
||||||
|
|
||||||
import org.ethereum.db.BlockVO;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Database helper class used to manage the creation and upgrading of your database. This class also usually provides
|
|
||||||
* the DAOs used by the other classes.
|
|
||||||
*/
|
|
||||||
public class BlockDatabaseHelper extends OrmLiteSqliteOpenHelper {
|
|
||||||
|
|
||||||
private static final String DATABASE_NAME = "blocks.db";
|
|
||||||
private static final int DATABASE_VERSION = 1;
|
|
||||||
|
|
||||||
// the DAO object we use to access the SimpleData table
|
|
||||||
private Dao<BlockVO, Integer> blockDao = null;
|
|
||||||
|
|
||||||
public BlockDatabaseHelper(Context context) {
|
|
||||||
super(context, DATABASE_NAME, null, DATABASE_VERSION);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This is called when the database is first created. Usually you should call createTable statements here to create
|
|
||||||
* the tables that will store your data.
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public void onCreate(SQLiteDatabase db, ConnectionSource connectionSource) {
|
|
||||||
try {
|
|
||||||
Log.i(BlockDatabaseHelper.class.getName(), "onCreate");
|
|
||||||
TableUtils.createTable(connectionSource, BlockVO.class);
|
|
||||||
} catch (SQLException e) {
|
|
||||||
Log.e(BlockDatabaseHelper.class.getName(), "Can't create database", e);
|
|
||||||
throw new RuntimeException(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This is called when your application is upgraded and it has a higher version number. This allows you to adjust
|
|
||||||
* the various data to match the new version number.
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public void onUpgrade(SQLiteDatabase db, ConnectionSource connectionSource, int oldVersion, int newVersion) {
|
|
||||||
try {
|
|
||||||
Log.i(BlockDatabaseHelper.class.getName(), "onUpgrade");
|
|
||||||
TableUtils.dropTable(connectionSource, BlockVO.class, true);
|
|
||||||
// after we drop the old databases, we create the new ones
|
|
||||||
onCreate(db, connectionSource);
|
|
||||||
} catch (SQLException e) {
|
|
||||||
Log.e(BlockDatabaseHelper.class.getName(), "Can't drop databases", e);
|
|
||||||
throw new RuntimeException(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the Database Access Object (DAO) for our SimpleData class. It will create it or just give the cached
|
|
||||||
* value.
|
|
||||||
*/
|
|
||||||
public Dao<BlockVO, Integer> getBlockDao() throws SQLException {
|
|
||||||
if (blockDao == null) {
|
|
||||||
blockDao = getDao(BlockVO.class);
|
|
||||||
}
|
|
||||||
return blockDao;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Close the database connections and clear any cached DAOs.
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public void close() {
|
|
||||||
super.close();
|
|
||||||
blockDao = null;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -0,0 +1,34 @@
|
||||||
|
package org.ethereum.android.db;
|
||||||
|
|
||||||
|
import org.ethereum.core.Block;
|
||||||
|
import org.ethereum.core.TransactionReceipt;
|
||||||
|
|
||||||
|
import java.math.BigInteger;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public interface BlockStoreDatabase {
|
||||||
|
|
||||||
|
public List<BlockVO> getByNumber(Long number);
|
||||||
|
|
||||||
|
public List<BlockVO> getByHash(byte[] hash);
|
||||||
|
|
||||||
|
public List<byte[]> getHashListByNumberLimit(Long from, Long to);
|
||||||
|
|
||||||
|
public void deleteBlocksSince(long number);
|
||||||
|
|
||||||
|
public void save(BlockVO block);
|
||||||
|
|
||||||
|
public BigInteger getTotalDifficultySince(long number);
|
||||||
|
|
||||||
|
public BigInteger getTotalDifficulty();
|
||||||
|
|
||||||
|
public Block getBestBlock();
|
||||||
|
|
||||||
|
public List<Block> getAllBlocks();
|
||||||
|
|
||||||
|
public void reset();
|
||||||
|
|
||||||
|
public void save(TransactionReceiptVO transactionReceiptVO);
|
||||||
|
|
||||||
|
public TransactionReceipt getTransactionReceiptByHash(byte[] hash);
|
||||||
|
}
|
|
@ -6,17 +6,16 @@ import org.ethereum.db.BlockStore;
|
||||||
import org.ethereum.util.ByteUtil;
|
import org.ethereum.util.ByteUtil;
|
||||||
|
|
||||||
import java.math.BigInteger;
|
import java.math.BigInteger;
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
public class BlockStoreImpl implements BlockStore {
|
public class BlockStoreImpl implements BlockStore {
|
||||||
|
|
||||||
private BlockDatabaseHelper blockDao;
|
private BlockStoreDatabase database;
|
||||||
private TransactionDatabaseHelper transactionDao;
|
|
||||||
|
|
||||||
public BlockStoreImpl(BlockDatabaseHelper blockDao, TransactionDatabaseHelper transactionDao) {
|
public BlockStoreImpl(BlockStoreDatabase database) {
|
||||||
|
|
||||||
this.blockDao = blockDao;
|
this.database = database;
|
||||||
this.transactionDao = transactionDao;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public byte[] getBlockHashByNumber(long blockNumber) {
|
public byte[] getBlockHashByNumber(long blockNumber) {
|
||||||
|
@ -29,65 +28,86 @@ public class BlockStoreImpl implements BlockStore {
|
||||||
|
|
||||||
public Block getBlockByNumber(long blockNumber) {
|
public Block getBlockByNumber(long blockNumber) {
|
||||||
|
|
||||||
/*
|
|
||||||
List result = sessionFactory.getCurrentSession().
|
List result = database.getByNumber(blockNumber);
|
||||||
createQuery("from BlockVO where number = :number").
|
if (result.size() == 0) return null;
|
||||||
setParameter("number", blockNumber).list();
|
BlockVO vo = (BlockVO) result.get(0);
|
||||||
|
|
||||||
|
return new Block(vo.rlp);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Block getBlockByHash(byte[] hash) {
|
||||||
|
|
||||||
|
List result = database.getByHash(hash);
|
||||||
|
|
||||||
if (result.size() == 0) return null;
|
if (result.size() == 0) return null;
|
||||||
BlockVO vo = (BlockVO) result.get(0);
|
BlockVO vo = (BlockVO) result.get(0);
|
||||||
|
|
||||||
return new Block(vo.rlp);
|
return new Block(vo.rlp);
|
||||||
*/
|
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public Block getBlockByHash(byte[] hash) {
|
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
|
||||||
public List<byte[]> getListOfHashesStartFrom(byte[] hash, int qty) {
|
public List<byte[]> getListOfHashesStartFrom(byte[] hash, int qty) {
|
||||||
|
|
||||||
return null;
|
List<byte[]> hashes = new ArrayList<byte[]>();
|
||||||
|
|
||||||
|
// find block number of that block hash
|
||||||
|
Block block = getBlockByHash(hash);
|
||||||
|
if (block == null) return hashes;
|
||||||
|
|
||||||
|
hashes = database.getHashListByNumberLimit(block.getNumber(), block.getNumber() - qty);
|
||||||
|
|
||||||
|
return hashes;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void deleteBlocksSince(long number) {
|
public void deleteBlocksSince(long number) {
|
||||||
|
|
||||||
|
database.deleteBlocksSince(number);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void saveBlock(Block block, List<TransactionReceipt> receipts) {
|
public void saveBlock(Block block, List<TransactionReceipt> receipts) {
|
||||||
|
|
||||||
|
BlockVO blockVO = new BlockVO(block.getNumber(), block.getHash(),
|
||||||
|
block.getEncoded(), block.getCumulativeDifficulty());
|
||||||
|
|
||||||
|
for (TransactionReceipt receipt : receipts) {
|
||||||
|
|
||||||
|
byte[] hash = receipt.getTransaction().getHash();
|
||||||
|
byte[] rlp = receipt.getEncoded();
|
||||||
|
|
||||||
|
TransactionReceiptVO transactionReceiptVO = new TransactionReceiptVO(hash, rlp);
|
||||||
|
database.save(transactionReceiptVO);
|
||||||
|
}
|
||||||
|
|
||||||
|
database.save(blockVO);
|
||||||
}
|
}
|
||||||
|
|
||||||
public BigInteger getTotalDifficultySince(long number) {
|
public BigInteger getTotalDifficultySince(long number) {
|
||||||
|
|
||||||
return null;
|
return database.getTotalDifficultySince(number);
|
||||||
}
|
}
|
||||||
|
|
||||||
public BigInteger getTotalDifficulty() {
|
public BigInteger getTotalDifficulty() {
|
||||||
|
|
||||||
return null;
|
return database.getTotalDifficulty();
|
||||||
}
|
}
|
||||||
|
|
||||||
public Block getBestBlock() {
|
public Block getBestBlock() {
|
||||||
|
|
||||||
return null;
|
return database.getBestBlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
|
||||||
public List<Block> getAllBlocks() {
|
public List<Block> getAllBlocks() {
|
||||||
|
|
||||||
return null;
|
return database.getAllBlocks();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void reset() {
|
public void reset() {
|
||||||
|
|
||||||
|
database.reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
public TransactionReceipt getTransactionReceiptByHash(byte[] hash) {
|
public TransactionReceipt getTransactionReceiptByHash(byte[] hash) {
|
||||||
|
|
||||||
return null;
|
return database.getTransactionReceiptByHash(hash);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,66 @@
|
||||||
|
package org.ethereum.android.db;
|
||||||
|
|
||||||
|
import com.j256.ormlite.field.DataType;
|
||||||
|
import com.j256.ormlite.field.DatabaseField;
|
||||||
|
import com.j256.ormlite.table.DatabaseTable;
|
||||||
|
|
||||||
|
import java.math.BigInteger;
|
||||||
|
|
||||||
|
@DatabaseTable(tableName = "block")
|
||||||
|
public class BlockVO {
|
||||||
|
|
||||||
|
@DatabaseField(index = true, dataType = DataType.BYTE_ARRAY)
|
||||||
|
byte[] hash;
|
||||||
|
|
||||||
|
@DatabaseField(index = true, dataType = DataType.LONG_OBJ)
|
||||||
|
Long number;
|
||||||
|
|
||||||
|
@DatabaseField(columnName = "cumulativedifficulty", dataType = DataType.BIG_INTEGER)
|
||||||
|
BigInteger cumulativeDifficulty;
|
||||||
|
|
||||||
|
@DatabaseField(dataType = DataType.BYTE_ARRAY)
|
||||||
|
byte[] rlp;
|
||||||
|
|
||||||
|
public BlockVO() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public BlockVO(Long number, byte[] hash, byte[] rlp, BigInteger cumulativeDifficulty) {
|
||||||
|
this.number = number;
|
||||||
|
this.hash = hash;
|
||||||
|
this.rlp = rlp;
|
||||||
|
this.cumulativeDifficulty = cumulativeDifficulty;
|
||||||
|
}
|
||||||
|
|
||||||
|
public byte[] getHash() {
|
||||||
|
return hash;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setHash(byte[] hash) {
|
||||||
|
this.hash = hash;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Long getIndex() {
|
||||||
|
return number;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setIndex(Long number) {
|
||||||
|
this.number = number;
|
||||||
|
}
|
||||||
|
|
||||||
|
public byte[] getRlp() {
|
||||||
|
return rlp;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setRlp(byte[] rlp) {
|
||||||
|
this.rlp = rlp;
|
||||||
|
}
|
||||||
|
|
||||||
|
public BigInteger getCumulativeDifficulty() {
|
||||||
|
return cumulativeDifficulty;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setCumulativeDifficulty(BigInteger cumulativeDifficulty) {
|
||||||
|
this.cumulativeDifficulty = cumulativeDifficulty;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,255 @@
|
||||||
|
package org.ethereum.android.db;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.database.sqlite.SQLiteDatabase;
|
||||||
|
import android.util.Log;
|
||||||
|
|
||||||
|
import com.j256.ormlite.android.apptools.OrmLiteSqliteOpenHelper;
|
||||||
|
import com.j256.ormlite.dao.Dao;
|
||||||
|
import com.j256.ormlite.dao.GenericRawResults;
|
||||||
|
import com.j256.ormlite.stmt.DeleteBuilder;
|
||||||
|
import com.j256.ormlite.support.ConnectionSource;
|
||||||
|
import com.j256.ormlite.table.TableUtils;
|
||||||
|
|
||||||
|
import org.ethereum.core.Block;
|
||||||
|
import org.ethereum.core.TransactionReceipt;
|
||||||
|
|
||||||
|
import java.math.BigInteger;
|
||||||
|
import java.sql.SQLException;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class OrmLiteBlockStoreDatabase extends OrmLiteSqliteOpenHelper implements BlockStoreDatabase {
|
||||||
|
|
||||||
|
private static final String DATABASE_NAME = "blockchain.db";
|
||||||
|
private static final int DATABASE_VERSION = 1;
|
||||||
|
|
||||||
|
private Dao<BlockVO, Integer> blockDao = null;
|
||||||
|
private Dao<TransactionReceiptVO, Integer> transactionDao = null;
|
||||||
|
|
||||||
|
public OrmLiteBlockStoreDatabase(Context context) {
|
||||||
|
super(context, DATABASE_NAME, null, DATABASE_VERSION);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This is called when the database is first created. Usually you should call createTable statements here to create
|
||||||
|
* the tables that will store your data.
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void onCreate(SQLiteDatabase db, ConnectionSource connectionSource) {
|
||||||
|
|
||||||
|
try {
|
||||||
|
Log.i(OrmLiteBlockStoreDatabase.class.getName(), "onCreate");
|
||||||
|
TableUtils.createTable(connectionSource, BlockVO.class);
|
||||||
|
TableUtils.createTable(connectionSource, TransactionReceiptVO.class);
|
||||||
|
} catch (SQLException e) {
|
||||||
|
Log.e(OrmLiteBlockStoreDatabase.class.getName(), "Can't create database", e);
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This is called when your application is upgraded and it has a higher version number. This allows you to adjust
|
||||||
|
* the various data to match the new version number.
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void onUpgrade(SQLiteDatabase db, ConnectionSource connectionSource, int oldVersion, int newVersion) {
|
||||||
|
|
||||||
|
try {
|
||||||
|
Log.i(OrmLiteBlockStoreDatabase.class.getName(), "onUpgrade");
|
||||||
|
TableUtils.dropTable(connectionSource, BlockVO.class, true);
|
||||||
|
TableUtils.dropTable(connectionSource, TransactionReceiptVO.class, true);
|
||||||
|
// after we drop the old databases, we create the new ones
|
||||||
|
onCreate(db, connectionSource);
|
||||||
|
} catch (SQLException e) {
|
||||||
|
Log.e(OrmLiteBlockStoreDatabase.class.getName(), "Can't drop databases", e);
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the Database Access Object (DAO) for our SimpleData class. It will create it or just give the cached
|
||||||
|
* value.
|
||||||
|
*/
|
||||||
|
public Dao<BlockVO, Integer> getBlockDao() throws SQLException {
|
||||||
|
|
||||||
|
if (blockDao == null) {
|
||||||
|
blockDao = getDao(BlockVO.class);
|
||||||
|
}
|
||||||
|
return blockDao;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the Database Access Object (DAO) for our SimpleData class. It will create it or just give the cached
|
||||||
|
* value.
|
||||||
|
*/
|
||||||
|
public Dao<TransactionReceiptVO, Integer> getTransactionDao() throws SQLException {
|
||||||
|
if (transactionDao == null) {
|
||||||
|
transactionDao = getDao(TransactionReceiptVO.class);
|
||||||
|
}
|
||||||
|
return transactionDao;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Close the database connections and clear any cached DAOs.
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void close() {
|
||||||
|
|
||||||
|
super.close();
|
||||||
|
blockDao = null;
|
||||||
|
transactionDao = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<BlockVO> getByNumber(Long number) {
|
||||||
|
|
||||||
|
List<BlockVO> list = new ArrayList<BlockVO>();
|
||||||
|
try {
|
||||||
|
list = getBlockDao().queryForEq("number", number);
|
||||||
|
} catch(java.sql.SQLException e) {
|
||||||
|
Log.e(OrmLiteBlockStoreDatabase.class.getName(), "Error querying for number", e);
|
||||||
|
}
|
||||||
|
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<BlockVO> getByHash(byte[] hash) {
|
||||||
|
|
||||||
|
List<BlockVO> list = new ArrayList<BlockVO>();
|
||||||
|
try {
|
||||||
|
list = getBlockDao().queryForEq("hash", hash);
|
||||||
|
} catch(java.sql.SQLException e) {
|
||||||
|
Log.e(OrmLiteBlockStoreDatabase.class.getName(), "Error querying for hash", e);
|
||||||
|
}
|
||||||
|
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<byte[]> getHashListByNumberLimit(Long from, Long to) {
|
||||||
|
|
||||||
|
List<byte[]> results = new ArrayList<byte[]>();
|
||||||
|
try {
|
||||||
|
List<BlockVO> list = new ArrayList<BlockVO>();
|
||||||
|
list = getBlockDao().queryBuilder().orderBy("number", false).limit(to - from).where().between("number", from, to).query();
|
||||||
|
for (BlockVO block : list) {
|
||||||
|
results.add(block.hash);
|
||||||
|
}
|
||||||
|
} catch(java.sql.SQLException e) {
|
||||||
|
Log.e(OrmLiteBlockStoreDatabase.class.getName(), "Error querying for hash list", e);
|
||||||
|
}
|
||||||
|
|
||||||
|
return results;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void deleteBlocksSince(long number) {
|
||||||
|
|
||||||
|
try {
|
||||||
|
DeleteBuilder<BlockVO, Integer> deleteBuilder = getBlockDao().deleteBuilder();
|
||||||
|
deleteBuilder.where().gt("number", number);
|
||||||
|
deleteBuilder.delete();
|
||||||
|
} catch(java.sql.SQLException e) {
|
||||||
|
Log.e(OrmLiteBlockStoreDatabase.class.getName(), "Error deleting blocks since", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void save(BlockVO block) {
|
||||||
|
|
||||||
|
try {
|
||||||
|
getBlockDao().create(block);
|
||||||
|
} catch(java.sql.SQLException e) {
|
||||||
|
Log.e(OrmLiteBlockStoreDatabase.class.getName(), "Error saving block", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public BigInteger getTotalDifficultySince(long number) {
|
||||||
|
|
||||||
|
try {
|
||||||
|
GenericRawResults<String[]> rawResults = getBlockDao().queryRaw("select sum(cumulativedifficulty) from block where number > " + number);
|
||||||
|
List<String[]> results = rawResults.getResults();
|
||||||
|
return new BigInteger(results.get(0)[0]);
|
||||||
|
} catch(java.sql.SQLException e) {
|
||||||
|
Log.e(OrmLiteBlockStoreDatabase.class.getName(), "Error getting total difficulty since", e);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public BigInteger getTotalDifficulty() {
|
||||||
|
|
||||||
|
try {
|
||||||
|
GenericRawResults<String[]> rawResults = getBlockDao().queryRaw("select sum(cumulativedifficulty) from block");
|
||||||
|
List<String[]> results = rawResults.getResults();
|
||||||
|
return new BigInteger(results.get(0)[0]);
|
||||||
|
} catch(java.sql.SQLException e) {
|
||||||
|
Log.e(OrmLiteBlockStoreDatabase.class.getName(), "Error getting total difficulty", e);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Block getBestBlock() {
|
||||||
|
|
||||||
|
Long bestNumber = null;
|
||||||
|
try {
|
||||||
|
GenericRawResults<String[]> rawResults = getBlockDao().queryRaw("select max(number) from block");
|
||||||
|
List<String[]> results = rawResults.getResults();
|
||||||
|
if (results.size() > 0 && results.get(0).length > 0) {
|
||||||
|
bestNumber = Long.valueOf(results.get(0)[0]);
|
||||||
|
}
|
||||||
|
} catch(java.sql.SQLException e) {
|
||||||
|
Log.e(OrmLiteBlockStoreDatabase.class.getName(), "Sql Error getting best block", e);
|
||||||
|
} catch (Exception e) {
|
||||||
|
Log.e(OrmLiteBlockStoreDatabase.class.getName(), "Error getting best block", e);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (bestNumber == null) return null;
|
||||||
|
List result = getByNumber(bestNumber);
|
||||||
|
|
||||||
|
if (result.isEmpty()) return null;
|
||||||
|
BlockVO vo = (BlockVO) result.get(0);
|
||||||
|
|
||||||
|
return new Block(vo.rlp);
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<Block> getAllBlocks() {
|
||||||
|
|
||||||
|
ArrayList<Block> blocks = new ArrayList<>();
|
||||||
|
try {
|
||||||
|
for (BlockVO blockVO : getBlockDao()) {
|
||||||
|
blocks.add(new Block(blockVO.getRlp()));
|
||||||
|
}
|
||||||
|
} catch(java.sql.SQLException e) {
|
||||||
|
Log.e(OrmLiteBlockStoreDatabase.class.getName(), "Error getting all blocks", e);
|
||||||
|
}
|
||||||
|
|
||||||
|
return blocks;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void reset() {
|
||||||
|
|
||||||
|
deleteBlocksSince(Long.valueOf(0));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void save(TransactionReceiptVO transactionReceiptVO) {
|
||||||
|
|
||||||
|
try {
|
||||||
|
getTransactionDao().create(transactionReceiptVO);
|
||||||
|
} catch(java.sql.SQLException e) {
|
||||||
|
Log.e(OrmLiteBlockStoreDatabase.class.getName(), "Error saving transaction", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public TransactionReceipt getTransactionReceiptByHash(byte[] hash) {
|
||||||
|
|
||||||
|
List<TransactionReceiptVO> list = new ArrayList<TransactionReceiptVO>();
|
||||||
|
try {
|
||||||
|
list = getTransactionDao().queryForEq("hash", hash);
|
||||||
|
} catch(java.sql.SQLException e) {
|
||||||
|
Log.e(OrmLiteBlockStoreDatabase.class.getName(), "Error querying for hash", e);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (list.size() == 0) return null;
|
||||||
|
TransactionReceiptVO vo = list.get(0);
|
||||||
|
|
||||||
|
return new TransactionReceipt(vo.rlp);
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,84 +0,0 @@
|
||||||
package org.ethereum.android.db;
|
|
||||||
|
|
||||||
|
|
||||||
import java.sql.SQLException;
|
|
||||||
|
|
||||||
import android.content.Context;
|
|
||||||
import android.database.sqlite.SQLiteDatabase;
|
|
||||||
import android.util.Log;
|
|
||||||
|
|
||||||
import com.j256.ormlite.android.apptools.OrmLiteSqliteOpenHelper;
|
|
||||||
import com.j256.ormlite.dao.Dao;
|
|
||||||
import com.j256.ormlite.support.ConnectionSource;
|
|
||||||
import com.j256.ormlite.table.TableUtils;
|
|
||||||
|
|
||||||
import org.ethereum.db.TransactionReceiptVO;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Database helper class used to manage the creation and upgrading of your database. This class also usually provides
|
|
||||||
* the DAOs used by the other classes.
|
|
||||||
*/
|
|
||||||
public class TransactionDatabaseHelper extends OrmLiteSqliteOpenHelper {
|
|
||||||
|
|
||||||
private static final String DATABASE_NAME = "transactions.db";
|
|
||||||
private static final int DATABASE_VERSION = 1;
|
|
||||||
|
|
||||||
// the DAO object we use to access the SimpleData table
|
|
||||||
private Dao<TransactionReceiptVO, Integer> dao = null;
|
|
||||||
|
|
||||||
public TransactionDatabaseHelper(Context context) {
|
|
||||||
super(context, DATABASE_NAME, null, DATABASE_VERSION);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This is called when the database is first created. Usually you should call createTable statements here to create
|
|
||||||
* the tables that will store your data.
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public void onCreate(SQLiteDatabase db, ConnectionSource connectionSource) {
|
|
||||||
try {
|
|
||||||
Log.i(BlockDatabaseHelper.class.getName(), "onCreate");
|
|
||||||
TableUtils.createTable(connectionSource, TransactionReceiptVO.class);
|
|
||||||
} catch (SQLException e) {
|
|
||||||
Log.e(BlockDatabaseHelper.class.getName(), "Can't create database", e);
|
|
||||||
throw new RuntimeException(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This is called when your application is upgraded and it has a higher version number. This allows you to adjust
|
|
||||||
* the various data to match the new version number.
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public void onUpgrade(SQLiteDatabase db, ConnectionSource connectionSource, int oldVersion, int newVersion) {
|
|
||||||
try {
|
|
||||||
Log.i(BlockDatabaseHelper.class.getName(), "onUpgrade");
|
|
||||||
TableUtils.dropTable(connectionSource, TransactionReceiptVO.class, true);
|
|
||||||
// after we drop the old databases, we create the new ones
|
|
||||||
onCreate(db, connectionSource);
|
|
||||||
} catch (SQLException e) {
|
|
||||||
Log.e(BlockDatabaseHelper.class.getName(), "Can't drop databases", e);
|
|
||||||
throw new RuntimeException(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the Database Access Object (DAO) for our SimpleData class. It will create it or just give the cached
|
|
||||||
* value.
|
|
||||||
*/
|
|
||||||
public Dao<TransactionReceiptVO, Integer> getBlockDao() throws SQLException {
|
|
||||||
if (dao == null) {
|
|
||||||
dao = getDao(TransactionReceiptVO.class);
|
|
||||||
}
|
|
||||||
return dao;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Close the database connections and clear any cached DAOs.
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public void close() {
|
|
||||||
super.close();
|
|
||||||
dao = null;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -0,0 +1,49 @@
|
||||||
|
package org.ethereum.android.db;
|
||||||
|
|
||||||
|
import com.j256.ormlite.field.DataType;
|
||||||
|
import com.j256.ormlite.field.DatabaseField;
|
||||||
|
import com.j256.ormlite.table.DatabaseTable;
|
||||||
|
|
||||||
|
import javax.persistence.Entity;
|
||||||
|
import javax.persistence.Id;
|
||||||
|
import javax.persistence.Lob;
|
||||||
|
import javax.persistence.Table;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Roman Mandeleil
|
||||||
|
* @since 14.11.2014
|
||||||
|
*/
|
||||||
|
@DatabaseTable(tableName = "transaction_receipt")
|
||||||
|
public class TransactionReceiptVO {
|
||||||
|
|
||||||
|
@DatabaseField(index = true, dataType = DataType.BYTE_ARRAY)
|
||||||
|
byte[] hash;
|
||||||
|
|
||||||
|
@DatabaseField(dataType = DataType.BYTE_ARRAY)
|
||||||
|
byte[] rlp;
|
||||||
|
|
||||||
|
public TransactionReceiptVO() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public TransactionReceiptVO(byte[] hash, byte[] rlp) {
|
||||||
|
this.hash = hash;
|
||||||
|
this.rlp = rlp;
|
||||||
|
}
|
||||||
|
|
||||||
|
public byte[] getHash() {
|
||||||
|
return hash;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setHash(byte[] hash) {
|
||||||
|
this.hash = hash;
|
||||||
|
}
|
||||||
|
|
||||||
|
public byte[] getRlp() {
|
||||||
|
return rlp;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setRlp(byte[] rlp) {
|
||||||
|
this.rlp = rlp;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -2,12 +2,15 @@ package org.ethereum.android.di.modules;
|
||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
|
|
||||||
|
import com.j256.ormlite.android.apptools.OpenHelperManager;
|
||||||
|
|
||||||
import org.ethereum.android.datasource.LevelDbDataSource;
|
import org.ethereum.android.datasource.LevelDbDataSource;
|
||||||
|
import org.ethereum.android.db.OrmLiteBlockStoreDatabase;
|
||||||
|
import org.ethereum.android.db.BlockStoreImpl;
|
||||||
import org.ethereum.config.SystemProperties;
|
import org.ethereum.config.SystemProperties;
|
||||||
import org.ethereum.core.BlockchainImpl;
|
import org.ethereum.core.BlockchainImpl;
|
||||||
import org.ethereum.core.Wallet;
|
import org.ethereum.core.Wallet;
|
||||||
import org.ethereum.db.BlockStore;
|
import org.ethereum.db.BlockStore;
|
||||||
import org.ethereum.db.InMemoryBlockStore;
|
|
||||||
import org.ethereum.db.RepositoryImpl;
|
import org.ethereum.db.RepositoryImpl;
|
||||||
import org.ethereum.facade.Blockchain;
|
import org.ethereum.facade.Blockchain;
|
||||||
import org.ethereum.facade.Ethereum;
|
import org.ethereum.facade.Ethereum;
|
||||||
|
@ -72,7 +75,8 @@ public class EthereumModule {
|
||||||
@Provides
|
@Provides
|
||||||
@Singleton
|
@Singleton
|
||||||
BlockStore provideBlockStore() {
|
BlockStore provideBlockStore() {
|
||||||
return new InMemoryBlockStore();
|
OrmLiteBlockStoreDatabase database = OpenHelperManager.getHelper(context, OrmLiteBlockStoreDatabase.class);
|
||||||
|
return new BlockStoreImpl(database);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Provides
|
@Provides
|
||||||
|
|
|
@ -100,7 +100,7 @@ test {
|
||||||
logger.lifecycle("Running test: ${descriptor}")
|
logger.lifecycle("Running test: ${descriptor}")
|
||||||
}
|
}
|
||||||
|
|
||||||
jvmArgs '-Xss32m'
|
jvmArgs += [ "-Xss32m", "-XX:MaxPermSize=256m" ]
|
||||||
|
|
||||||
testLogging {
|
testLogging {
|
||||||
events "failed"
|
events "failed"
|
||||||
|
|
|
@ -16,3 +16,5 @@
|
||||||
# This option should only be used with decoupled projects. More details, visit
|
# This option should only be used with decoupled projects. More details, visit
|
||||||
# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
|
# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
|
||||||
# org.gradle.parallel=true
|
# org.gradle.parallel=true
|
||||||
|
|
||||||
|
org.gradle.jvmargs=-XX:MaxPermSize=512m
|
Loading…
Reference in New Issue