public boolean isNymNotSpend(BlockChain bc) { //check locktime and compare to current bip113 time //we only accept p2sh if(!getLastTransactionOutput().getScriptPubKey().isPayToScriptHash()) { System.out.println("the psynym is not a p2sh"); return false; } //check that redeem script matches the p2sh output hash if(!ScriptBuilder.createP2SHOutputScript(sp.getRedeemScript()).equals(getLastTransactionOutput().getScriptPubKey())) { System.out.println("the redeem script doesn't match the p2sh output hash"); return false; } //check that the redeem script is the one we specified and check that it is still locked if(!sp.isRedeemScriptRightFormat() || !sp.isLocked(bc)) { System.out.println("redeem script is either not in right format or transaction is not locked, might be not spend, but we can't know without utxo set"); return false; } return true; }
public boolean isValidProof(BlockChain bc, PeerGroup pg, NetworkParameters params) { if(!isValidPath()) { System.out.println("path is not valid, thus proof not valid, abort"); return false; } if(!isValidGPTx()) { System.out.println("gptx is not valid, abort"); return false; } if(!isNymNotSpend(bc)) { System.out.println("nym is not locked anymore, consider spent, abort"); return false; } if(!isNymTxInBlockChain(params, bc, pg)) { System.out.println("nymtx is not in blockchain, consider proof invalid, abort"); return false; } System.out.println("proof seems valid"); return true; }
public static long currentBitcoinBIP113Time(BlockChain bc) { StoredBlock headBlock = bc.getChainHead(); StoredBlock iteratingBlock = headBlock; long[] blockTimeStamps = new long[11]; for(int i=0; i < 11; i++) { blockTimeStamps[i] = iteratingBlock.getHeader().getTimeSeconds(); try { iteratingBlock = iteratingBlock.getPrev(bc.getBlockStore()); } catch (BlockStoreException e) { e.printStackTrace(); } } Arrays.sort(blockTimeStamps); System.out.println("current bitcoinbip113time yielded " + new Date(blockTimeStamps[5]*1000)); return blockTimeStamps[5]; }
/** * Called by the {@link BlockChain} when we receive a new filtered block that contains a transactions previously * received by a call to {@link #receivePending}.<p> * * This is necessary for the internal book-keeping Wallet does. When a transaction is received that sends us * coins it is added to a pool so we can use it later to create spends. When a transaction is received that * consumes outputs they are marked as spent so they won't be used in future.<p> * * A transaction that spends our own coins can be received either because a spend we created was accepted by the * network and thus made it into a block, or because our keys are being shared between multiple instances and * some other node spent the coins instead. We still have to know about that to avoid accidentally trying to * double spend.<p> * * A transaction may be received multiple times if is included into blocks in parallel chains. The blockType * parameter describes whether the containing block is on the main/best chain or whether it's on a presently * inactive side chain. We must still record these transactions and the blocks they appear in because a future * block might change which chain is best causing a reorganize. A re-org can totally change our balance! */ @Override public boolean notifyTransactionIsInBlock(Sha256Hash txHash, StoredBlock block, BlockChain.NewBlockType blockType, int relativityOffset) throws VerificationException { lock.lock(); try { Transaction tx = transactions.get(txHash); if (tx == null) { tx = riskDropped.get(txHash); if (tx != null) { // If this happens our risk analysis is probably wrong and should be improved. log.info("Risk analysis dropped tx {} but was included in block anyway", tx.getHash()); } else { // False positive that was broadcast to us and ignored by us because it was irrelevant to our keys. return false; } } receive(tx, block, blockType, relativityOffset); return true; } finally { lock.unlock(); } }
@Test public void testInitialize() throws BlockStoreException { final BlockStore blockStore = new MemoryBlockStore(PARAMS); final BlockChain chain = new BlockChain(PARAMS, blockStore); // Build a historical chain of version 2 blocks long timeSeconds = 1231006505; StoredBlock chainHead = null; for (int height = 0; height < PARAMS.getMajorityWindow(); height++) { chainHead = FakeTxBuilder.createFakeBlock(blockStore, 2, timeSeconds, height).storedBlock; assertEquals(2, chainHead.getHeader().getVersion()); timeSeconds += 60; } VersionTally instance = new VersionTally(PARAMS); instance.initialize(blockStore, chainHead); assertEquals(PARAMS.getMajorityWindow(), instance.getCountAtOrAbove(2).intValue()); }
@Test public void isConsistent_duplicates() throws Exception { // This test ensures that isConsistent catches duplicate transactions, eg, because we submitted the same block // twice (this is not allowed). Transaction tx = createFakeTx(PARAMS, COIN, myAddress); TransactionOutput output = new TransactionOutput(PARAMS, tx, valueOf(0, 5), OTHER_ADDRESS); tx.addOutput(output); wallet.receiveFromBlock(tx, null, BlockChain.NewBlockType.BEST_CHAIN, 0); assertTrue(wallet.isConsistent()); Transaction txClone = PARAMS.getDefaultSerializer().makeTransaction(tx.bitcoinSerialize()); try { wallet.receiveFromBlock(txClone, null, BlockChain.NewBlockType.BEST_CHAIN, 0); fail("Illegal argument not thrown when it should have been."); } catch (IllegalStateException ex) { // expected } }
@Test public void watchingScriptsBloomFilter() throws Exception { assertFalse(wallet.isRequiringUpdateAllBloomFilter()); Address watchedAddress = new ECKey().toAddress(PARAMS); Transaction t1 = createFakeTx(PARAMS, CENT, watchedAddress); TransactionOutPoint outPoint = new TransactionOutPoint(PARAMS, 0, t1); wallet.addWatchedAddress(watchedAddress); assertTrue(wallet.isRequiringUpdateAllBloomFilter()); // Note that this has a 1e-12 chance of failing this unit test due to a false positive assertFalse(wallet.getBloomFilter(1e-12).contains(outPoint.unsafeBitcoinSerialize())); sendMoneyToWallet(BlockChain.NewBlockType.BEST_CHAIN, t1); assertTrue(wallet.getBloomFilter(1e-12).contains(outPoint.unsafeBitcoinSerialize())); }
@Test public void removeScriptsBloomFilter() throws Exception { List<Address> addressesForRemoval = new ArrayList<Address>(); for (int i = 0; i < 10; i++) { Address watchedAddress = new ECKey().toAddress(PARAMS); addressesForRemoval.add(watchedAddress); wallet.addWatchedAddress(watchedAddress); } wallet.removeWatchedAddresses(addressesForRemoval); for (Address addr : addressesForRemoval) { Transaction t1 = createFakeTx(PARAMS, CENT, addr); TransactionOutPoint outPoint = new TransactionOutPoint(PARAMS, 0, t1); // Note that this has a 1e-12 chance of failing this unit test due to a false positive assertFalse(wallet.getBloomFilter(1e-12).contains(outPoint.unsafeBitcoinSerialize())); sendMoneyToWallet(BlockChain.NewBlockType.BEST_CHAIN, t1); assertFalse(wallet.getBloomFilter(1e-12).contains(outPoint.unsafeBitcoinSerialize())); } }
@Bean public BlockChainService getBlockchainService(final NetworkParameters params, final BlockChain blockChain, final PeerGroup peerGroup, final TransactionStateService transactionService, final WalletDbService walletService, final AccountDbService accountService, final BlockchainSettings settings ){ final BitcoinjBlockchainServiceImpl blockChainService = new BitcoinjBlockchainServiceImpl(params, blockChain, peerGroup, transactionService, walletService, accountService, settings); blockChainService.init(); return blockChainService; }
public NameLookupLatestLevelDBTransactionCache (Context context, File directory, DBFactory dbFactory, BlockChain chain, BlockStore store, PeerGroup peerGroup) throws IOException { this.chain = chain; this.store = store; this.peerGroup = peerGroup; this.context = context; this.params = context.getParams(); this.path = directory; Options options = new Options(); options.createIfMissing(); try { tryOpen(directory, dbFactory, options); } catch (IOException e) { dbFactory.repair(directory, options); tryOpen(directory, dbFactory, options); } chain.addNewBestBlockListener(Threading.SAME_THREAD, this); chain.addReorganizeListener(Threading.SAME_THREAD, this); chain.addTransactionReceivedListener(Threading.SAME_THREAD, this); }
private void createMultiSigWallet(int threshold, int numKeys, boolean addSigners) throws BlockStoreException { wallet = new Wallet(params); blockStore = new MemoryBlockStore(params); chain = new BlockChain(params, wallet, blockStore); List<DeterministicKey> followingKeys = Lists.newArrayList(); for (int i = 0; i < numKeys - 1; i++) { final DeterministicKeyChain keyChain = new DeterministicKeyChain(new SecureRandom()); DeterministicKey partnerKey = DeterministicKey.deserializeB58(null, keyChain.getWatchingKey().serializePubB58()); followingKeys.add(partnerKey); if (addSigners && i < threshold - 1) wallet.addTransactionSigner(new KeyChainTransactionSigner(keyChain)); } // MarriedKeyChain chain = MarriedKeyChain.builder() // .random(new SecureRandom()) // .followingKeys(followingKeys) // .threshold(threshold).build(); // wallet.addAndActivateHDChain(chain); }
@Test public void removeScriptsBloomFilter() throws Exception { List<Address> addressesForRemoval = new ArrayList<>(); for (int i = 0; i < 10; i++) { Address watchedAddress = new ECKey().toAddress(PARAMS); addressesForRemoval.add(watchedAddress); wallet.addWatchedAddress(watchedAddress); } wallet.removeWatchedAddresses(addressesForRemoval); for (Address addr : addressesForRemoval) { Transaction t1 = createFakeTx(PARAMS, CENT, addr); TransactionOutPoint outPoint = new TransactionOutPoint(PARAMS, 0, t1); // Note that this has a 1e-12 chance of failing this unit test due to a false positive assertFalse(wallet.getBloomFilter(1e-12).contains(outPoint.unsafeBitcoinSerialize())); sendMoneyToWallet(BlockChain.NewBlockType.BEST_CHAIN, t1); assertFalse(wallet.getBloomFilter(1e-12).contains(outPoint.unsafeBitcoinSerialize())); } }
public TransactionGenerator(NetworkParameters params, PeerGroup pg, Wallet w, BlockChain bc) { this.params = params; this.pg = pg; this.w = w; this.bc = bc; }
private Sha256Hash getBlockHashByHeight(BlockChain bc, int appearedInChainheight2) { int bestchainheight = bc.getBestChainHeight(); StoredBlock block = bc.getChainHead(); assert(block != null); for(int i=0; i < bestchainheight-appearedInChainheight2; i++) { try { System.out.println("iteration: " + i); assert(block != null); block = block.getPrev(bc.getBlockStore()); } catch (BlockStoreException e) { e.printStackTrace(); } } return block.getHeader().getHash(); }
public Mixer(PTP ptp, BroadcastAnnouncement bca, ProofMessage pm, Wallet w, NetworkParameters params, PeerGroup pg, BlockChain bc) { this.ptp = ptp; this.bca = bca; this.mixPartnerAdress = new Identifier(bca.getOnionAdress() + ".onion"); this.ownProof = pm; this.w = w; this.params = params; this.pg = pg; this.bc = bc; this.mfListeners = new ArrayList<MixFinishedEventListener>(); this.lockTime = 0; }
public Mixer(PTP ptp, String onionAddress, ProofMessage pm, Wallet w, NetworkParameters params, PeerGroup pg, BlockChain bc) { this.ptp = ptp; this.mixPartnerAdress = new Identifier(onionAddress); this.ownProof = pm; this.w = w; this.params = params; this.pg = pg; this.bc = bc; this.mfListeners = new ArrayList<MixFinishedEventListener>(); this.lockTime = 0; }
public Mixer(PTP ptp, ProofMessage pm, Wallet w, NetworkParameters params, PeerGroup pg, BlockChain bc) { this.ptp = ptp; this.ownProof = pm; this.w = w; this.params = params; this.pg = pg; this.bc = bc; this.mfListeners = new ArrayList<MixFinishedEventListener>(); this.lockTime = 0; }
public ChallengeResponseVerifier(PTP ptp, Wallet w, NetworkParameters params, PeerGroup pg, BlockChain bc) { this.ptp = ptp; this.w = w; this.params = params; this.pg = pg; this.bc = bc; }
public MixPartnerDiscovery(NetworkParameters params, PeerGroup pg, BlockChain bc, Wallet wallet) { this.pg = pg; this.bc = bc; this.head = null; this.wallet = wallet; this.broadcasts = new ArrayList<Transaction>(); this.listeners = new ArrayList<BroadcastAnnouncementChangeEventListener>(); }
@Test public void balance() throws Exception { // Receive 5 coins then half a coin. Coin v1 = valueOf(5, 0); Coin v2 = valueOf(0, 50); Coin expected = valueOf(5, 50); assertEquals(0, wallet.getTransactions(true).size()); sendMoneyToWallet(AbstractBlockChain.NewBlockType.BEST_CHAIN, v1); assertEquals(1, wallet.getPoolSize(WalletTransaction.Pool.UNSPENT)); sendMoneyToWallet(AbstractBlockChain.NewBlockType.BEST_CHAIN, v2); assertEquals(2, wallet.getPoolSize(WalletTransaction.Pool.UNSPENT)); assertEquals(expected, wallet.getBalance()); // Now spend one coin. Coin v3 = COIN; Transaction spend = wallet.createSend(OTHER_ADDRESS, v3); wallet.commitTx(spend); assertEquals(1, wallet.getPoolSize(WalletTransaction.Pool.PENDING)); // Available and estimated balances should not be the same. We don't check the exact available balance here // because it depends on the coin selection algorithm. assertEquals(valueOf(4, 50), wallet.getBalance(Wallet.BalanceType.ESTIMATED)); assertFalse(wallet.getBalance(Wallet.BalanceType.AVAILABLE).equals( wallet.getBalance(Wallet.BalanceType.ESTIMATED))); // Now confirm the transaction by including it into a block. sendMoneyToWallet(BlockChain.NewBlockType.BEST_CHAIN, spend); // Change is confirmed. We started with 5.50 so we should have 4.50 left. Coin v4 = valueOf(4, 50); assertEquals(v4, wallet.getBalance(Wallet.BalanceType.AVAILABLE)); }
@Test public void isConsistent_pools() throws Exception { // This test ensures that isConsistent catches transactions that are in incompatible pools. Transaction tx = createFakeTx(PARAMS, COIN, myAddress); TransactionOutput output = new TransactionOutput(PARAMS, tx, valueOf(0, 5), OTHER_ADDRESS); tx.addOutput(output); wallet.receiveFromBlock(tx, null, BlockChain.NewBlockType.BEST_CHAIN, 0); assertTrue(wallet.isConsistent()); wallet.addWalletTransaction(new WalletTransaction(Pool.PENDING, tx)); assertFalse(wallet.isConsistent()); }
@Test(expected = InsufficientMoneyException.class) public void watchingScriptsConfirmed() throws Exception { Address watchedAddress = new ECKey().toAddress(PARAMS); wallet.addWatchedAddress(watchedAddress); sendMoneyToWallet(BlockChain.NewBlockType.BEST_CHAIN, CENT, watchedAddress); assertEquals(CENT, wallet.getBalance()); // We can't spend watched balances wallet.createSend(OTHER_ADDRESS, CENT); }
@Test public void marriedKeychainBloomFilter() throws Exception { createMarriedWallet(2, 2); Address address = wallet.currentReceiveAddress(); assertTrue(wallet.getBloomFilter(0.001).contains(address.getHash160())); Transaction t1 = createFakeTx(PARAMS, CENT, address); TransactionOutPoint outPoint = new TransactionOutPoint(PARAMS, 0, t1); assertFalse(wallet.getBloomFilter(0.001).contains(outPoint.unsafeBitcoinSerialize())); sendMoneyToWallet(BlockChain.NewBlockType.BEST_CHAIN, t1); assertTrue(wallet.getBloomFilter(0.001).contains(outPoint.unsafeBitcoinSerialize())); }
@Bean public BlockChain getChain(final NetworkParameters params, final SPVBlockStore blockStore, final Context context) throws BlockStoreException { return new BlockChain(context, blockStore); }
@Before public void setUp() throws Exception { this.blockStore = new SPVBlockStore(this.params, new File("tbtc_blockstore")); final BlockChain chain = new BlockChain(new Context(this.params), this.blockStore); final PeerGroup peerGroup = new PeerGroup(this.params, chain); final BlockchainSettings settings = new BlockchainSettings(1, BigDecimal.ZERO, BigDecimal.TEN, "target", "central.wallet", "admin", "password"); this.service = new BitcoinjBlockchainServiceImpl(this.params, chain, peerGroup, this.transactionService, this.walletService, this.accountService, settings); this.service.init(); this.wallets.add(this.wallet); when(this.accountService.getByEmail("admin")).thenReturn(this.account); when(this.account.getWallets()).thenReturn(this.wallets); when(this.transactionService.getByReceiverHash(anyString())).thenReturn(this.transaction, this.transaction); when(this.wallet.toBuilder()).thenReturn(Wallet.builder()); when(this.wallet.getContent()).thenAnswer(new Answer<String>() { @Override public String answer(final InvocationOnMock invocation) throws Throwable { counter ++; if (counter == 1) { return FileUtils.readFileToString(new File("src/test/resources/content.cnt")); } return FileUtils.readFileToString(new File("src/test/resources/content1.cnt")); } }); }
public NameLookupLatestRestMerkleApi (NetworkParameters params, String restUrlPrefix, String restUrlSuffix, BlockChain chain, BlockStore store, NameLookupByBlockHeightHashCache heightLookup) { this.params = params; this.restUrlPrefix = restUrlPrefix; this.restUrlSuffix = restUrlSuffix; this.chain = chain; this.store = store; this.heightLookup = heightLookup; }
public NameLookupByBlockHeightHashCache (BlockChain chain, NameLookupByBlockHash hashLookup) throws Exception { this.chain = chain; this.store = chain.getBlockStore(); this.hashLookup = hashLookup; initBlockHashCache(); }
/** * Starts a bitcoin network peer and begins to listen * * @throws BlockStoreException */ public void start() throws BlockStoreException { BlockChain blockChain = new BlockChain(NET_PARAMS, new MemoryBlockStore(NET_PARAMS)); PeerGroup peerGroup = new PeerGroup(NET_PARAMS, blockChain); peerGroup.addPeerDiscovery(new DnsDiscovery(NET_PARAMS)); peerGroup.addEventListener(peerEventListener); peerGroup.startAsync(); }