Skip to content

Commit

Permalink
updated for memoryblockstore
Browse files Browse the repository at this point in the history
  • Loading branch information
milansismanovic committed Mar 1, 2018
1 parent 5ee280c commit d6cbb1d
Show file tree
Hide file tree
Showing 15 changed files with 585 additions and 91 deletions.
8 changes: 4 additions & 4 deletions .classpath
Original file line number Diff line number Diff line change
Expand Up @@ -28,12 +28,12 @@
<attribute name="owner.project.facets" value="jst.web"/>
</attributes>
</classpathentry>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.7">
<classpathentry kind="con" path="org.eclipse.jdt.junit.JUNIT_CONTAINER/4"/>
<classpathentry kind="lib" path="src/main/webapp/WEB-INF/lib/BitcoindClient4J.jar"/>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/jre1.8.0_162">
<attributes>
<attribute name="maven.pomderived" value="true"/>
<attribute name="owner.project.facets" value="java"/>
</attributes>
</classpathentry>
<classpathentry kind="con" path="org.eclipse.jdt.junit.JUNIT_CONTAINER/4"/>
<classpathentry kind="lib" path="src/main/webapp/WEB-INF/lib/BitcoindClient4J.jar"/>
<classpathentry kind="output" path="target/classes"/>
</classpath>
6 changes: 3 additions & 3 deletions .settings/org.eclipse.jdt.core.prefs
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
eclipse.preferences.version=1
org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.7
org.eclipse.jdt.core.compiler.compliance=1.7
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8
org.eclipse.jdt.core.compiler.compliance=1.8
org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning
org.eclipse.jdt.core.compiler.source=1.7
org.eclipse.jdt.core.compiler.source=1.8
18 changes: 9 additions & 9 deletions .settings/org.eclipse.wst.common.project.facet.core.xml
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
<?xml version="1.0" encoding="UTF-8"?>
<faceted-project>
<runtime name="Apache Tomcat v7.0"/>
<fixed facet="wst.jsdt.web"/>
<installed facet="java" version="1.7"/>
<installed facet="jst.web" version="2.5"/>
<installed facet="jst.jaxrs" version="2.0"/>
<installed facet="wst.jsdt.web" version="1.0"/>
</faceted-project>
<?xml version="1.0" encoding="UTF-8"?>
<faceted-project>
<runtime name="Apache Tomcat v7.0"/>
<fixed facet="wst.jsdt.web"/>
<installed facet="jst.web" version="2.5"/>
<installed facet="jst.jaxrs" version="2.0"/>
<installed facet="wst.jsdt.web" version="1.0"/>
<installed facet="java" version="1.8"/>
</faceted-project>
5 changes: 5 additions & 0 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,11 @@
<artifactId>commons-beanutils</artifactId>
<version>1.9.3</version>
</dependency>
<dependency>
<groupId>commons-dbutils</groupId>
<artifactId>commons-dbutils</artifactId>
<version>1.7</version>
</dependency>
</dependencies>
<properties>
<jersey.version>2.26</jersey.version>
Expand Down
26 changes: 17 additions & 9 deletions src/main/java/rest/bitcoin/Bitcoin.java
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
import store.bitcoin.BlockStore;
import store.bitcoin.BlockStoreException;
import store.bitcoin.DBBlockStore;
import store.bitcoin.MemoryBlockStore;
import store.bitcoin.StoreLoader;
import store.bitcoin.pojo.StoredTransaction;

Expand Down Expand Up @@ -61,19 +62,25 @@ public class Bitcoin {
final static String clientAddresses2[] = { "1FYU384h3Y7quk1bYy9BZzCFdFA7ojiCfc" };
// FIXME add fresh 3rd key set
final static String clientPrivateKeys3[] = { "KySuyZ6jnGbGW2Qc9VpCk7F8z2rqfaS5EfTsqLxycczaZSuPxJwp" };
final static String clientPublicKeys3[] = { "021AD207A99E408F840C0911BD8BCDDA9C6089B23AC0CFBB62D76961018E59C282" };
final static String clientAddresses3[] = { "1FYU384h3Y7quk1bYy9BZzCFdFA7ojiCfc" };
final static String clientPublicKeys3[] = { "02B7EC7437DC90F5F1BE5F963E97B81538AD87C81B4DC1C6E311140F22759D9C46" };
final static String clientAddresses3[] = { "n1NBeDoig6XWgSYLs1mgDwh27YccgiDxv9" };

static BitcoindInterface client;
static BlockStore store;
static Configuration config;
static StoreLoader storeLoader;

public Bitcoin() throws MalformedURLException, IOException, BlockStoreException, ConfigurationException {
config = new Configurations().properties(new File("bitcoin.properties"));
BitcoindClientFactory clientFactory = new BitcoindClientFactory(new URL(config.getString("bitcoin.rpc.URL")),
config.getString("bitcoin.rpc.rpcuser"), config.getString("bitcoin.rpc.rpcpassword"));
client = clientFactory.getClient();
store = new DBBlockStore();
// store = new DBBlockStore();
if(store==null)
store = new MemoryBlockStore();
if(storeLoader==null)
storeLoader = new StoreLoader(store, client);
storeLoader.loadStore(6 * 24 * 28); // 28 days in the past);
}

String[] getClientprivatekeys1() {
Expand All @@ -90,11 +97,12 @@ String[] getClientaddresses1() {

static long lastRefresh = -1;

// TODO create anonymous inner class to run the sync to update the db
// ensure the thread is only spanned once.
class DBRefresher {

}
// // TODO implement a clever sync from store to the bitcoin network
// // suggestion: create anonymous inner class to run the sync to update the db
// // as a singleton to ensure the thread is only spanned once.
// class DBRefresher {
//
// }

void refreshDB() {
if (System.currentTimeMillis() - lastRefresh < 1000 * 30) {
Expand All @@ -103,7 +111,7 @@ void refreshDB() {
Thread refreshDBRunnable = new Thread() {
public void run() {
try {
new StoreLoader(store, client).loadStore(1000);
storeLoader.loadStore(1000);
lastRefresh = System.currentTimeMillis();
} catch (BlockStoreException e) {
log.error("error refreshing block store", e);
Expand Down
16 changes: 16 additions & 0 deletions src/main/java/store/bitcoin/BlockStore.java
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ public StoredBlock getChainHead() throws BlockStoreException {

/**
* update chainhead if block newer than current chainhead
*
* @param block
* @throws BlockStoreException
*/
Expand All @@ -29,6 +30,7 @@ public void updateChainHead(StoredBlock block) throws BlockStoreException {

/**
* gets the chain head height or -1 if the chain head is null
*
* @return
* @throws BlockStoreException
*/
Expand All @@ -39,6 +41,8 @@ public int getChainHeadHeight() throws BlockStoreException {

public abstract StoredBlock get(String hash) throws BlockStoreException;

public abstract StoredBlock get(int height) throws BlockStoreException;

public abstract void put(StoredBlock block) throws BlockStoreException;

public abstract List<StoredTransaction> getTx(List<String> addresses) throws BlockStoreException;
Expand All @@ -48,4 +52,16 @@ public int getChainHeadHeight() throws BlockStoreException {
public abstract BigInteger getBalance(List<String> addresses) throws BlockStoreException;

public abstract void resetStore() throws BlockStoreException;

/**
* Set the vout to spend for all given addresses.
* @param tx
* @param parentTx
* @param addresses
* @throws BlockStoreException
*/
public abstract void updateUTXO(StoredTransaction tx, StoredTransaction parentTx, int parentVoutIndex)
throws BlockStoreException;

public abstract StoredTransaction getTx(String inputTxid);
}
128 changes: 100 additions & 28 deletions src/main/java/store/bitcoin/DBBlockStore.java
Original file line number Diff line number Diff line change
Expand Up @@ -41,10 +41,10 @@
*/
public class DBBlockStore extends BlockStore {
private static final Logger log = LoggerFactory.getLogger(DBBlockStore.class);
// private static final String DB_HOSTNAME = "localhost";
// private static final String DB_NAME = "bitcoin_test";
// private static final String DB_USERNAME = "bitcoin";
// private static final String DB_PASSWORD = "password";
// private static final String DB_HOSTNAME = "localhost";
// private static final String DB_NAME = "bitcoin_test";
// private static final String DB_USERNAME = "bitcoin";
// private static final String DB_PASSWORD = "password";

// private static final String DATABASE_DRIVER_CLASS = "com.mysql.jdbc.Driver";
private static final String DATABASE_DRIVER_CLASS = "com.mysql.cj.jdbc.Driver";
Expand Down Expand Up @@ -229,6 +229,34 @@ public StoredBlock get(String hash) throws BlockStoreException {
return null;
}

public StoredBlock get(int height) {
try {
String sql = "SELECT `blockheaders`.`hash`,\r\n" + " `blockheaders`.`height`,\r\n"
+ " `blockheaders`.`time`,\r\n" + " `blockheaders`.`previousblockhash`\r\n"
+ "FROM `bitcoin_test`.`blockheaders`;\r\n" + "WHERE height=?";
PreparedStatement s = connection.prepareStatement(sql);
s.setInt(1, height);
ResultSet rs = s.executeQuery();
if (rs.next()) {
byte[] hashbytes = rs.getBytes(1);
String hash2 = Utils.HEX.encode(hashbytes);
Timestamp timeStamp = rs.getTimestamp(3);
long time = timeStamp.getTime() / 1000;
byte[] previousHash = rs.getBytes(4);
String previousblockhash = Utils.HEX.encode(previousHash);
StoredBlock block = new StoredBlock(hash2, height, time, previousblockhash, null);
// TODO get txs here
return block;
} else {
return null;
}
} catch (SQLException e) {
log.debug("couldn't find block with this hash: {}", height);
}
return null;

}

/**
* Puts a block into the store.
*/
Expand Down Expand Up @@ -266,6 +294,9 @@ public void put(StoredBlock block) throws BlockStoreException {
log.debug(stx.toString());
stx.executeUpdate();
stx.close();
// put for each address in vout an entry in the addresstransaction table
// consider putting only our clients' address-transaction combinations in
// the future
PreparedStatement satx = connection.prepareStatement(INSERT_ADDRESSTRANSACTIONS);
for (StoredVout vout : tx.getVouts()) {
List<String> addresses = vout.getAddresses();
Expand All @@ -284,8 +315,9 @@ public void put(StoredBlock block) throws BlockStoreException {
satx.executeBatch();
satx.close();
}
// put txs including their vins and vouts to db
// TODO implement
// put txs vins to db
// TODO implement - ACTUALLY CAN'T AS WE PROBABLY DON'T HAVE THE PREVIOUS
// TRANSACTION YET LOADED/PUT INTO THE DB
} catch (SQLException e) {
throw new BlockStoreException("error inserting block", e);
} catch (IOException e) {
Expand All @@ -294,6 +326,35 @@ public void put(StoredBlock block) throws BlockStoreException {
updateChainHead(block);
}

void updateVins() {
// go through the blockchain and update the vins for all tx

}

public StoredTransaction getTx(String txid) {
// get all tx from the transactions table
String txsql = "SELECT `txblob` FROM `transactions` WHERE txid=?;";
PreparedStatement txstmt;
byte[] txidBytes = Utils.HEX.decode(txid);
StoredTransaction tx = null;
try {
txstmt = connection.prepareStatement(txsql);
txstmt.setBytes(1, txidBytes);
ResultSet txrs = txstmt.executeQuery();
if (txrs.next()) {
byte[] txBytes = txrs.getBytes(1);
ByteArrayInputStream baip = new ByteArrayInputStream(txBytes);
ObjectInputStream ois = new ObjectInputStream(baip);
Object object = ois.readObject();
tx = (StoredTransaction) object;
}
} catch (Exception e) {
// don't care if it fails as we return null then
// most likely because tx is not stored
}
return tx;
}

public List<StoredTransaction> getTx(List<String> addresses) throws BlockStoreException {
List<StoredTransaction> txs = new LinkedList<>();
// FIXME there is probably a more elegant way to have a multi value where
Expand Down Expand Up @@ -356,27 +417,38 @@ public BigInteger getBalance(List<String> addresses) throws BlockStoreException
return null;
}

public void test() throws BlockStoreException {
// try {
// // get
// String txsql = "SELECT txblob FROM `transactions`;";
// PreparedStatement txstmt = connection.prepareStatement(txsql);
// ResultSet txrs = txstmt.executeQuery();
// while (txrs.next()) {
// byte[] txBytes = txrs.getBytes(1);
// ByteArrayInputStream baip = new ByteArrayInputStream(txBytes);
// ObjectInputStream ois = new ObjectInputStream(baip);
// StoredTransaction tx = (StoredTransaction) ois.readObject();
// log.info(tx.toString());
// }
// } catch (SQLException e) {
// throw new BlockStoreException("db error fetching transactions", e);
// } catch (IOException e) {
// throw new BlockStoreException("serialization error converting transactions",
// e);
// } catch (ClassNotFoundException e) {
// throw new BlockStoreException("serialization error converting
// StoredTransaction", e);
// }
@Override
public void updateUTXO(StoredTransaction tx, StoredTransaction parentTx, int parentVoutIndex)
throws BlockStoreException {
// TODO Auto-generated method stub
}

public void test(List<String> addresses) throws BlockStoreException {
try {
// get all tx for this address
List<StoredTransaction> txs = getTx(addresses);
for (StoredTransaction tx : txs) {
log.info(tx.toString());
// get
String txsql = "SELECT txblob FROM `transactions`;";
PreparedStatement txstmt = connection.prepareStatement(txsql);
ResultSet txrs = txstmt.executeQuery();
while (txrs.next()) {
byte[] txBytes = txrs.getBytes(1);
ByteArrayInputStream baip = new ByteArrayInputStream(txBytes);
ObjectInputStream ois = new ObjectInputStream(baip);
StoredTransaction txR = (StoredTransaction) ois.readObject();
log.info(txR.toString());
}
}
} catch (SQLException e) {
throw new BlockStoreException("db error fetching transactions", e);
} catch (IOException e) {
throw new BlockStoreException("serialization error converting transactions", e);
} catch (ClassNotFoundException e) {
throw new BlockStoreException("serialization error converting StoredTransaction", e);
}
}


}
Loading

0 comments on commit d6cbb1d

Please sign in to comment.