mirror of
https://github.com/Qortal/altcoinj.git
synced 2025-01-30 23:02:15 +00:00
Cleanup and finish merge with 0.3
This commit is contained in:
parent
f731c8591d
commit
b7b1c039dc
8
pom.xml
8
pom.xml
@ -245,6 +245,12 @@
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.apache.derby</groupId>
|
||||
<artifactId>derby</artifactId>
|
||||
<version>10.8.2.2</version>
|
||||
</dependency>
|
||||
|
||||
<!-- In Android these libraries are incomplete,
|
||||
so use the dedicated artifact (bitcoinj-<version>-android.jar) -->
|
||||
<dependency>
|
||||
@ -263,4 +269,4 @@
|
||||
<slf4j.version>1.6.2</slf4j.version>
|
||||
</properties>
|
||||
|
||||
</project>
|
||||
</project>
|
||||
|
@ -16,14 +16,26 @@
|
||||
|
||||
package com.google.bitcoin.examples;
|
||||
|
||||
import com.google.bitcoin.core.*;
|
||||
import com.google.bitcoin.core.AbstractWalletEventListener;
|
||||
import com.google.bitcoin.core.Address;
|
||||
import com.google.bitcoin.core.BlockChain;
|
||||
import com.google.bitcoin.core.ECKey;
|
||||
import com.google.bitcoin.core.NetworkParameters;
|
||||
import com.google.bitcoin.core.PeerAddress;
|
||||
import com.google.bitcoin.core.PeerGroup;
|
||||
import com.google.bitcoin.core.ScriptException;
|
||||
import com.google.bitcoin.core.StoredBlock;
|
||||
import com.google.bitcoin.core.Transaction;
|
||||
import com.google.bitcoin.core.TransactionInput;
|
||||
import com.google.bitcoin.core.Utils;
|
||||
import com.google.bitcoin.core.Wallet;
|
||||
import com.google.bitcoin.store.BlockStoreException;
|
||||
import com.google.bitcoin.store.DerbyBlockStore;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.math.BigInteger;
|
||||
import java.net.InetAddress;
|
||||
import java.util.concurrent.CountDownLatch;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
/**
|
||||
* PingService demonstrates basic usage of the library. It sits on the network and when it receives coins, simply
|
||||
@ -61,14 +73,14 @@ public class DerbyPingService {
|
||||
|
||||
// Connect to the localhost node. One minute timeout since we won't try any other peers
|
||||
System.out.println("Connecting ...");
|
||||
NetworkConnection conn = new NetworkConnection(InetAddress.getLocalHost(), params,
|
||||
blockStore.getChainHead().getHeight(), 60000);
|
||||
BlockChain chain = new BlockChain(params, wallet, blockStore);
|
||||
final Peer peer = new Peer(params, conn, chain);
|
||||
peer.start();
|
||||
final PeerGroup peerGroup = new PeerGroup(blockStore, params, chain);
|
||||
peerGroup.addAddress(new PeerAddress(InetAddress.getLocalHost()));
|
||||
peerGroup.start();
|
||||
|
||||
// We want to know when the balance changes.
|
||||
wallet.addEventListener(new WalletEventListener() {
|
||||
wallet.addEventListener(new AbstractWalletEventListener() {
|
||||
@Override
|
||||
public void onCoinsReceived(Wallet w, Transaction tx, BigInteger prevBalance, BigInteger newBalance) {
|
||||
// Running on a peer thread.
|
||||
assert !newBalance.equals(BigInteger.ZERO);
|
||||
@ -81,7 +93,7 @@ public class DerbyPingService {
|
||||
BigInteger value = tx.getValueSentToMe(w);
|
||||
System.out.println("Received " + Utils.bitcoinValueToFriendlyString(value) + " from " + from.toString());
|
||||
// Now send the coins back!
|
||||
Transaction sendTx = w.sendCoins(peer, from, value);
|
||||
Transaction sendTx = w.sendCoins(peerGroup, from, value);
|
||||
assert sendTx != null; // We should never try to send more coins than we have!
|
||||
System.out.println("Sent coins back! Transaction hash is " + sendTx.getHashAsString());
|
||||
w.saveToFile(walletFile);
|
||||
@ -96,18 +108,8 @@ public class DerbyPingService {
|
||||
}
|
||||
});
|
||||
|
||||
CountDownLatch progress = peer.startBlockChainDownload();
|
||||
long max = progress.getCount(); // Racy but no big deal.
|
||||
if (max > 0) {
|
||||
System.out.println("Downloading block chain. " + (max > 1000 ? "This may take a while." : ""));
|
||||
long current = max;
|
||||
while (current > 0) {
|
||||
double pct = 100.0 - (100.0 * (current / (double)max));
|
||||
System.out.println(String.format("Chain download %d%% done", (int)pct));
|
||||
progress.await(1, TimeUnit.SECONDS);
|
||||
current = progress.getCount();
|
||||
}
|
||||
}
|
||||
peerGroup.downloadBlockChain();
|
||||
|
||||
System.out.println("Send coins to: " + key.toAddress(params).toString());
|
||||
System.out.println("Waiting for coins to arrive. Press Ctrl-C to quit.");
|
||||
// The peer thread keeps us alive until something kills the process.
|
||||
@ -117,7 +119,7 @@ public class DerbyPingService {
|
||||
* @param blockStore
|
||||
* @throws BlockStoreException
|
||||
*/
|
||||
private static void iterateAll(DerbyBlockStore blockStore) throws BlockStoreException {
|
||||
static void iterateAll(DerbyBlockStore blockStore) throws BlockStoreException {
|
||||
long time = System.currentTimeMillis();
|
||||
StoredBlock block = blockStore.getChainHead();
|
||||
int count = 0;
|
||||
|
@ -1,4 +1,4 @@
|
||||
package com.google.bitcoin.core;
|
||||
package com.google.bitcoin.store;
|
||||
|
||||
/**
|
||||
* Copyright 2011 Google Inc.
|
||||
@ -16,6 +16,14 @@ package com.google.bitcoin.core;
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import com.google.bitcoin.core.Block;
|
||||
import com.google.bitcoin.core.NetworkParameters;
|
||||
import com.google.bitcoin.core.ProtocolException;
|
||||
import com.google.bitcoin.core.Sha256Hash;
|
||||
import com.google.bitcoin.core.StoredBlock;
|
||||
import com.google.bitcoin.core.Utils;
|
||||
import com.google.bitcoin.core.VerificationException;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
@ -33,9 +41,6 @@ import java.sql.Statement;
|
||||
* @author miron@google.com (Miron Cuperman)
|
||||
*/
|
||||
public class DerbyBlockStore implements BlockStore {
|
||||
/**
|
||||
*
|
||||
*/
|
||||
private static final int COMMIT_INTERVAL = 2 * 1000;
|
||||
|
||||
private static final Logger log = LoggerFactory.getLogger(DerbyBlockStore.class);
|
||||
@ -161,13 +166,13 @@ public class DerbyBlockStore implements BlockStore {
|
||||
if (!rs.next()) {
|
||||
throw new BlockStoreException("corrupt Derby block store - no chain head pointer");
|
||||
}
|
||||
byte[] hash = rs.getBytes(1);
|
||||
Sha256Hash hash = new Sha256Hash(rs.getBytes(1));
|
||||
this.chainHeadBlock = get(hash);
|
||||
if (this.chainHeadBlock == null)
|
||||
{
|
||||
throw new BlockStoreException("corrupt Derby block store - head block not found");
|
||||
}
|
||||
this.chainHeadHash = new Sha256Hash(hash);
|
||||
this.chainHeadHash = hash;
|
||||
}
|
||||
|
||||
private void createNewStore(NetworkParameters params) throws BlockStoreException {
|
||||
@ -178,7 +183,7 @@ public class DerbyBlockStore implements BlockStore {
|
||||
StoredBlock storedGenesis = new StoredBlock(genesis,
|
||||
genesis.getWork(), 0);
|
||||
this.chainHeadBlock = storedGenesis;
|
||||
this.chainHeadHash = new Sha256Hash(storedGenesis.getHeader().getHash());
|
||||
this.chainHeadHash = storedGenesis.getHeader().getHash();
|
||||
setChainHead(storedGenesis);
|
||||
put(storedGenesis);
|
||||
} catch (VerificationException e1) {
|
||||
@ -199,13 +204,12 @@ public class DerbyBlockStore implements BlockStore {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void put(StoredBlock stored) throws BlockStoreException {
|
||||
try {
|
||||
PreparedStatement s =
|
||||
conn.prepareStatement("INSERT INTO blocks(hash, chainWork, height, header)"
|
||||
+ " VALUES(?, ?, ?, ?)");
|
||||
s.setBytes(1, stored.getHeader().getHash());
|
||||
s.setBytes(1, stored.getHeader().getHash().getBytes());
|
||||
s.setBytes(2, stored.getChainWork().toByteArray());
|
||||
s.setLong(3, stored.getHeight());
|
||||
s.setBytes(4, stored.getHeader().bitcoinSerialize());
|
||||
@ -217,15 +221,14 @@ public class DerbyBlockStore implements BlockStore {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public StoredBlock get(byte[] hash) throws BlockStoreException {
|
||||
public StoredBlock get(Sha256Hash hash) throws BlockStoreException {
|
||||
// Optimize for chain head
|
||||
if (chainHeadHash != null && chainHeadHash.equals(new Sha256Hash(hash)))
|
||||
if (chainHeadHash != null && chainHeadHash.equals(hash))
|
||||
return chainHeadBlock;
|
||||
try {
|
||||
PreparedStatement s = conn
|
||||
.prepareStatement("SELECT chainWork, height, header FROM blocks WHERE hash = ?");
|
||||
s.setBytes(1, hash);
|
||||
.prepareStatement("SELECT chainWork, height, header FROM blocks WHERE hash = ?");
|
||||
s.setBytes(1, hash.getBytes());
|
||||
ResultSet results = s.executeQuery();
|
||||
if (!results.next()) {
|
||||
return null;
|
||||
@ -240,7 +243,7 @@ public class DerbyBlockStore implements BlockStore {
|
||||
stored = new StoredBlock(params.genesisBlock.cloneAsHeader(),
|
||||
params.genesisBlock.getWork(), 0);
|
||||
} else {
|
||||
b.verify();
|
||||
b.verifyHeader();
|
||||
stored = new StoredBlock(b, chainWork, height);
|
||||
}
|
||||
return stored;
|
||||
@ -257,21 +260,19 @@ public class DerbyBlockStore implements BlockStore {
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
@Override
|
||||
public StoredBlock getChainHead() throws BlockStoreException {
|
||||
return chainHeadBlock;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setChainHead(StoredBlock chainHead) throws BlockStoreException {
|
||||
byte[] hash = chainHead.getHeader().getHash();
|
||||
this.chainHeadHash = new Sha256Hash(hash);
|
||||
Sha256Hash hash = chainHead.getHeader().getHash();
|
||||
this.chainHeadHash = hash;
|
||||
this.chainHeadBlock = chainHead;
|
||||
try {
|
||||
PreparedStatement s = conn
|
||||
.prepareStatement("UPDATE settings SET value = ? WHERE name = ?");
|
||||
s.setString(2, CHAIN_HEAD_SETTING);
|
||||
s.setBytes(1, hash);
|
||||
s.setBytes(1, hash.getBytes());
|
||||
s.executeUpdate();
|
||||
s.close();
|
||||
startCommitter();
|
||||
@ -316,7 +317,6 @@ public class DerbyBlockStore implements BlockStore {
|
||||
// A thread that is guaranteed to try a commit as long as
|
||||
// committerThread is not null
|
||||
Runnable committer = new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
log.info("commit scheduled");
|
@ -13,20 +13,30 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.google.bitcoin.core;
|
||||
package com.google.bitcoin.store;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
import com.google.bitcoin.core.Address;
|
||||
import com.google.bitcoin.core.ECKey;
|
||||
import com.google.bitcoin.core.NetworkParameters;
|
||||
import com.google.bitcoin.core.StoredBlock;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.IOException;
|
||||
|
||||
public class DerbyBlockStoreTest {
|
||||
/**
|
||||
*
|
||||
* This path will be deleted recursively!
|
||||
*/
|
||||
private static final String DB_NAME = ".bitcoinj.unittest.derby";
|
||||
|
||||
@Test
|
||||
public void testStorage() throws Exception {
|
||||
deleteRecursively(new File(DB_NAME));
|
||||
NetworkParameters params = NetworkParameters.unitTests();
|
||||
Address to = new ECKey().toAddress(params);
|
||||
DerbyBlockStore store = new DerbyBlockStore(params, DB_NAME);
|
||||
@ -49,4 +59,13 @@ public class DerbyBlockStoreTest {
|
||||
assertEquals(b1, store.getChainHead());
|
||||
store.dump();
|
||||
}
|
||||
|
||||
void deleteRecursively(File f) throws IOException {
|
||||
if (f.isDirectory()) {
|
||||
for (File c : f.listFiles())
|
||||
deleteRecursively(c);
|
||||
}
|
||||
if (!f.delete())
|
||||
throw new FileNotFoundException("Failed to delete file: " + f);
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user