public static String hash2(String a, String b){ // Reverse inputs before and after hashing due to big-endian / little-endian nonsense byte[] a1 = Utils.hexStringToByteArray(a); byte[] b1 = Utils.hexStringToByteArray(b); Utils.reverse(a1); Utils.reverse(b1); byte[] ab = new byte[a1.length + b1.length]; System.arraycopy(a1, 0, ab, 0, a1.length); System.arraycopy(b1, 0, ab, a1.length, b1.length); byte[] hash = Sha256Hash.hash(Sha256Hash.hash(ab)); Utils.reverse(hash); return Utils.byteArrayToHex(hash); }
@Override public synchronized void put(StoredBlock block) throws BlockStoreException { blocksDataSource.open(); Sha256Hash hash = block.getHeader().getHash(); try { blocksDataSource.getHash(hash.toString()); } catch (Exception e) { DBBlock dbBlock = new DBBlock(); dbBlock.setHash(hash.toString()); dbBlock.setHeight(block.getHeight()); dbBlock.setHeader(block.getHeader().bitcoinSerialize()); dbBlock.setChainWork(block.getChainWork()); blocksDataSource.insert(dbBlock); } blocksDataSource.close(); }
@Override public synchronized StoredBlock get(Sha256Hash hash) throws BlockStoreException { if(hash==null) throw new BlockStoreException("Invalid hash"); blocksDataSource.open(); DBBlock block = null; try { block = blocksDataSource.getHash(hash.toString()); } catch (Exception e) { blocksDataSource.close(); return null; } Block b = new Block(params, block.getHeader()); StoredBlock s = build(b); blocksDataSource.close(); return s; }
/** * Signs the raw bytes using a travel document. * Follows the steps in this answer: https://bitcoin.stackexchange.com/a/5241 * @return signedRawTransaction */ public byte[] signRawTransaction(PublicKey pubkey, byte[][] parts, PassportConnection pcon) throws Exception { byte[] rawTransaction = Bytes.concat(parts[0], parts[1], parts[2], parts[3], parts[4], parts[5], parts[6], parts[7], parts[8], parts[9], parts[10], parts[11], parts[12]); // Double hash transaction byte[] step14 = Sha256Hash.hash(Sha256Hash.hash(rawTransaction)); // Generate signature and get publickey byte[] multiSignature = new byte[320]; byte[] hashPart; for (int i = 0; i < 4; i++) { hashPart = Arrays.copyOfRange(step14, i * 8, i * 8 + 8); System.arraycopy(pcon.signData(hashPart), 0, multiSignature, i * 80, 80); } byte[] signatureLength = Util.hexStringToByteArray("fd97014d4101"); byte[] hashCodeType = Util.hexStringToByteArray("01"); byte[] publicKeyASN = pubkey.getEncoded(); byte[] publicKey = new byte[81]; System.arraycopy(publicKeyASN, publicKeyASN.length-81, publicKey, 0, 81); byte[] publickeyLength = Util.hexStringToByteArray("4c51"); // Set signature and pubkey in format byte[] step16 = Bytes.concat(signatureLength, multiSignature, hashCodeType, publickeyLength, publicKey); // Update transaction with signature and remove hash code type byte[] step19 = Bytes.concat(parts[0], parts[1], parts[2], parts[3], step16, parts[6], parts[7], parts[8], parts[9], parts[10], parts[11], parts[12]); return step19; }
@Override public void onBlocksDownloaded(Peer arg0, Block arg1, @Nullable FilteredBlock arg2, int arg3) { System.out.println("received block"); boolean receivedBcastAnnouncmnt = false; Map<Sha256Hash, Transaction> assocTxs = arg2.getAssociatedTransactions(); for(Transaction tx : assocTxs.values()) { System.out.println("from within mixpartner discovery " + tx); if(tx.getOutputs().size() > 1 && BroadcastAnnouncement.isBroadcastAnnouncementScript(tx.getOutput(1).getScriptBytes())) //&& !wallet.isTransactionRelevant(tx)) { //tx.getInput(0).getScriptSig().getChunks().get(0) { if(!this.broadcasts.contains(tx) && wallet.getTransaction(tx.getHash()) == null) { this.broadcasts.add(tx); receivedBcastAnnouncmnt = true; } } } if(receivedBcastAnnouncmnt) { for(BroadcastAnnouncementChangeEventListener l : listeners) { l.onBroadcastAnnouncementChanged(); } } }
/** * Creates an MnemonicCode object, initializing with words read from the supplied input stream. If a wordListDigest * is supplied the digest of the words will be checked. */ public MnemonicCode(InputStream wordstream, String wordListDigest) throws IOException, IllegalArgumentException { BufferedReader br = new BufferedReader(new InputStreamReader(wordstream, "UTF-8")); this.wordList = new ArrayList<>(2048); MessageDigest md = Sha256Hash.newDigest(); String word; while ((word = br.readLine()) != null) { md.update(word.getBytes()); this.wordList.add(word); } br.close(); if (this.wordList.size() != 2048) throw new IllegalArgumentException("input stream did not contain 2048 words"); // If a wordListDigest is supplied check to make sure it matches. if (wordListDigest != null) { byte[] digest = md.digest(); String hexdigest = HEX.encode(digest); if (!hexdigest.equals(wordListDigest)) throw new IllegalArgumentException("wordlist digest mismatch"); } }
/** * 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(); } }
/** {@inheritDoc} */ @Override public Map<Sha256Hash, Transaction> getTransactionPool(Pool pool) { lock.lock(); try { switch (pool) { case UNSPENT: return unspent; case SPENT: return spent; case PENDING: return pending; case DEAD: return dead; default: throw new RuntimeException("Unknown wallet transaction type " + pool); } } finally { lock.unlock(); } }
EnumSet<Pool> getContainingPools(Transaction tx) { lock.lock(); try { EnumSet<Pool> result = EnumSet.noneOf(Pool.class); Sha256Hash txHash = tx.getHash(); if (unspent.containsKey(txHash)) { result.add(Pool.UNSPENT); } if (spent.containsKey(txHash)) { result.add(Pool.SPENT); } if (pending.containsKey(txHash)) { result.add(Pool.PENDING); } if (dead.containsKey(txHash)) { result.add(Pool.DEAD); } return result; } finally { lock.unlock(); } }
@VisibleForTesting public boolean poolContainsTxHash(final WalletTransaction.Pool pool, final Sha256Hash txHash) { lock.lock(); try { switch (pool) { case UNSPENT: return unspent.containsKey(txHash); case SPENT: return spent.containsKey(txHash); case PENDING: return pending.containsKey(txHash); case DEAD: return dead.containsKey(txHash); } throw new RuntimeException("Unreachable"); } finally { lock.unlock(); } }
@Override public void onCoinsReceived(final Wallet wallet, final Transaction tx, final Coin prevBalance, final Coin newBalance) { transactionsReceived.incrementAndGet(); final int bestChainHeight = blockChain.getBestChainHeight(); final Address address = WalletUtils.getWalletAddressOfReceived(tx, wallet); final Coin amount = tx.getValue(wallet); final ConfidenceType confidenceType = tx.getConfidence().getConfidenceType(); final Sha256Hash hash = tx.getHash(); handler.post(new Runnable() { @Override public void run() { final boolean isReceived = amount.signum() > 0; final boolean replaying = bestChainHeight < config.getBestChainHeightEver(); final boolean isReplayedTx = confidenceType == ConfidenceType.BUILDING && replaying; if (isReceived && !isReplayedTx) notifyCoinsReceived(address, amount, hash); } }); }
private synchronized void refreshOutputs() { adapter.getItems().clear(); adapter.getItems().addAll(walletServiceBinder.getUnspentInstantOutputs()); Collections.sort(adapter.getItems(), new Comparator<TransactionOutput>() { @Override public int compare(TransactionOutput lhs, TransactionOutput rhs) { Sha256Hash lhsHash = lhs.getParentTransactionHash(); Sha256Hash rhsHash = lhs.getParentTransactionHash(); if (lhsHash != null && rhsHash != null) { int hashCmp = lhsHash.toString().compareTo(rhsHash.toString()); if (hashCmp != 0) return hashCmp; else return Long.compare(lhs.getIndex(), rhs.getIndex()); } else if (lhsHash != null) return -1; else if (rhsHash != null) return 1; else return 0; } }); adapter.notifyDataSetChanged(); }
/** * Creates an MnemonicCode object, initializing with words read from the supplied input stream. If a wordListDigest * is supplied the digest of the words will be checked. */ public MnemonicCode(InputStream wordstream, String wordListDigest) throws IOException, IllegalArgumentException { BufferedReader br = new BufferedReader(new InputStreamReader(wordstream, "UTF-8")); this.wordList = new ArrayList<String>(2048); MessageDigest md = Sha256Hash.newDigest(); String word; while ((word = br.readLine()) != null) { md.update(word.getBytes()); this.wordList.add(word); } br.close(); if (this.wordList.size() != 2048) throw new IllegalArgumentException("input stream did not contain 2048 words"); // If a wordListDigest is supplied check to make sure it matches. if (wordListDigest != null) { byte[] digest = md.digest(); String hexdigest = HEX.encode(digest); if (!hexdigest.equals(wordListDigest)) throw new IllegalArgumentException("wordlist digest mismatch"); } }
private Wallet(Context context, KeyChainGroup keyChainGroup) { this.context = context; this.params = context.getParams(); this.keyChainGroup = checkNotNull(keyChainGroup); if (params.getId().equals(NetworkParameters.ID_UNITTESTNET)) this.keyChainGroup.setLookaheadSize(5); // Cut down excess computation for unit tests. // If this keyChainGroup was created fresh just now (new wallet), make HD so a backup can be made immediately // without having to call current/freshReceiveKey. If there are already keys in the chain of any kind then // we're probably being deserialized so leave things alone: the API user can upgrade later. if (this.keyChainGroup.numKeys() == 0) this.keyChainGroup.createAndActivateNewHDChain(); watchedScripts = Sets.newHashSet(); unspent = new HashMap<Sha256Hash, Transaction>(); spent = new HashMap<Sha256Hash, Transaction>(); pending = new HashMap<Sha256Hash, Transaction>(); dead = new HashMap<Sha256Hash, Transaction>(); transactions = new HashMap<Sha256Hash, Transaction>(); extensions = new HashMap<String, WalletExtension>(); // Use a linked hash map to ensure ordering of event listeners is correct. confidenceChanged = new LinkedHashMap<Transaction, TransactionConfidence.Listener.ChangeReason>(); signers = new ArrayList<TransactionSigner>(); addTransactionSigner(new LocalTransactionSigner()); createTransientState(); }
private void createTransientState() { ignoreNextNewBlock = new HashSet<Sha256Hash>(); txConfidenceListener = new TransactionConfidence.Listener() { @Override public void onConfidenceChanged(TransactionConfidence confidence, TransactionConfidence.Listener.ChangeReason reason) { // This will run on the user code thread so we shouldn't do anything too complicated here. // We only want to queue a wallet changed event and auto-save if the number of peers announcing // the transaction has changed, as that confidence change is made by the networking code which // doesn't necessarily know at that point which wallets contain which transactions, so it's up // to us to listen for that. Other types of confidence changes (type, etc) are triggered by us, // so we'll queue up a wallet change event in other parts of the code. if (reason == ChangeReason.SEEN_PEERS) { lock.lock(); try { checkBalanceFuturesLocked(null); Transaction tx = getTransaction(confidence.getTransactionHash()); queueOnTransactionConfidenceChanged(tx); maybeQueueOnWalletChanged(); } finally { lock.unlock(); } } } }; acceptRiskyTransactions = false; }
@Test public void deriveCoin() throws Exception { DeterministicHierarchy hierarchy = new DeterministicHierarchy(masterKey); DeterministicKey rootKey = hierarchy.get(BitcoinMain.get().getBip44Path(0), false, true); chain = new SimpleHDKeyChain(rootKey); ECKey key1 = chain.getKey(SimpleHDKeyChain.KeyPurpose.RECEIVE_FUNDS); ECKey key2 = chain.getKey(SimpleHDKeyChain.KeyPurpose.RECEIVE_FUNDS); final Address address = new Address(BitcoinMain.get(), "1Fp7CA7ZVqZNFVNQ9TpeqWUas7K28K9zig"); assertEquals(address, key1.toAddress(BitcoinMain.get())); assertEquals("1AKqkQM4VqyVis6hscj8695WHPCCzgHNY3", key2.toAddress(BitcoinMain.get()).toString()); assertEquals(key1, chain.findKeyFromPubHash(address.getHash160())); assertEquals(key2, chain.findKeyFromPubKey(key2.getPubKey())); key1.sign(Sha256Hash.ZERO_HASH); ECKey key3 = chain.getKey(SimpleHDKeyChain.KeyPurpose.CHANGE); assertEquals("18YvGiRqXKxrzB72ckfrRSizWeHgwRP94V", key3.toAddress(BitcoinMain.get()).toString()); key3.sign(Sha256Hash.ZERO_HASH); ECKey key4 = chain.getKey(SimpleHDKeyChain.KeyPurpose.CHANGE); assertEquals("1861TX2MbyPEUrxDQVWgV4Tp9991bK1zpy", key4.toAddress(BitcoinMain.get()).toString()); key4.sign(Sha256Hash.ZERO_HASH); }
@Test public void autosaveImmediate() throws Exception { // Test that the wallet will save itself automatically when it changes. File f = File.createTempFile("bitcoinj-unit-test", null); Sha256Hash hash1 = Sha256Hash.of(f); // Start with zero delay and ensure the wallet file changes after adding a key. wallet.autosaveToFile(f, 0, TimeUnit.SECONDS, null); ECKey key = wallet.freshReceiveKey(); Sha256Hash hash2 = Sha256Hash.of(f); assertFalse("Wallet not saved after generating fresh key", hash1.equals(hash2)); // File has changed. Transaction t1 = createFakeTx(PARAMS, valueOf(5, 0), key); if (wallet.isPendingTransactionRelevant(t1)) wallet.receivePending(t1, null); Sha256Hash hash3 = Sha256Hash.of(f); assertFalse("Wallet not saved after receivePending", hash2.equals(hash3)); // File has changed again. }
private void parseMini(String key) throws KeyFormatException { byte[] bytes = key.getBytes(); byte[] checkBytes = new byte[31]; // 30 chars + '?' List<byte[]> allBytes = ImmutableList.of(bytes, checkBytes); if (!key.startsWith("S")) { clearDataAndThrow(allBytes, "Mini private keys must start with 'S'"); } if (bytes.length != 30) { clearDataAndThrow(allBytes, "Mini private keys must be 30 characters long"); } System.arraycopy(bytes, 0, checkBytes, 0, 30); checkBytes[30] = '?'; // Check if the sha256 hash of key + "?" starts with 0x00 if (Sha256Hash.create(checkBytes).getBytes()[0] != 0x00) { clearDataAndThrow(allBytes, "Not well formed mini private key"); } compressed = false; // Mini keys are not compressed content = Sha256Hash.create(bytes).getBytes(); clearData(allBytes); }
public TypedKey decryptBip38(String passphrase) throws BadPassphraseException { String normalizedPassphrase = Normalizer.normalize(passphrase, Normalizer.Form.NFC); ECKey key = ecMultiply ? decryptBip38EC(normalizedPassphrase) : decryptBip38NoEC(normalizedPassphrase); String address = null; for (CoinType type : CoinID.getSupportedCoins()) { String possibleAddress = key.toAddress(type).toString(); Sha256Hash hash = Sha256Hash.createDouble(possibleAddress.getBytes(Charsets.US_ASCII)); byte[] actualAddressHash = Arrays.copyOfRange(hash.getBytes(), 0, 4); if (Arrays.equals(actualAddressHash, addressHash)) { address = possibleAddress; } } if (address == null) { throw new BadPassphraseException(); } try { return new TypedKey(GenericUtils.getPossibleTypes(address), key); } catch (AddressMalformedException e) { throw new RuntimeException(e); // Should not happen } }
private Map<TrimmedOutPoint, OutPointOutput> getDummyUtxoSet() throws AddressMalformedException, JSONException { final HashMap<TrimmedOutPoint, OutPointOutput> unspentOutputs = new HashMap<>(); for (int i = 0; i < statuses.length; i++) { BitAddress address = (BitAddress) DOGE.newAddress(addresses.get(i)); JSONArray utxoArray = new JSONArray(unspent[i]); for (int j = 0; j < utxoArray.length(); j++) { JSONObject utxoObject = utxoArray.getJSONObject(j); //"[{\"tx_hash\": \"ef74da273e8a77e2d60b707414fb7e0ccb35c7b1b936800a49fe953195b1799f\", \"tx_pos\": 11, \"value\": 500000000, \"height\": 160267}]", TrimmedOutPoint outPoint = new TrimmedOutPoint(DOGE, utxoObject.getInt("tx_pos"), new Sha256Hash(utxoObject.getString("tx_hash"))); TransactionOutput output = new TransactionOutput(DOGE, null, Coin.valueOf(utxoObject.getLong("value")), address); OutPointOutput utxo = new OutPointOutput(outPoint, output, false); unspentOutputs.put(outPoint, utxo); } } return unspentOutputs; }
public void reDownloadBlockTransactions(Integer blockHeight) { Database db = Database.getInstance(); ResultSet rs = db.executeQuery("select * from blocks where block_index='"+blockHeight.toString()+"';"); try { if (rs.next()) { Block block = peerGroup.getDownloadPeer().getBlock(new Sha256Hash(rs.getString("block_hash"))).get(); db.executeUpdate("delete from transactions where block_index='"+blockHeight.toString()+"';"); Integer txSnInBlock=0; for (Transaction tx : block.getTransactions()) { importPPkTransaction(tx,txSnInBlock, block, blockHeight); txSnInBlock++; } } } catch (Exception e) { } }
public BitTransaction(Sha256Hash transactionId, Transaction transaction, boolean isTrimmed, Value valueSent, Value valueReceived, @Nullable Value fee) { tx = Preconditions.checkNotNull(transaction); type = (CoinType) tx.getParams(); this.isTrimmed = isTrimmed; if (isTrimmed) { hash = Preconditions.checkNotNull(transactionId); this.valueSent = Preconditions.checkNotNull(valueSent); this.valueReceived = Preconditions.checkNotNull(valueReceived); this.value = valueReceived.subtract(valueSent); this.fee = fee; } else { hash = null; this.valueSent = null; this.valueReceived = null; this.value = null; this.fee = null; } }
private void updateTransactionTimes(BlockHeader header) { checkState(lock.isHeldByCurrentThread(), "Lock is held by another thread"); Integer height = header.getBlockHeight(); Long timestamp = header.getTimestamp(); boolean mustSave = false; blockTimes.put(height, timestamp); if (missingTimestamps.containsKey(height)) { for (Sha256Hash hash : missingTimestamps.get(height)) { if (rawTransactions.containsKey(hash)) { rawTransactions.get(hash).setTimestamp(timestamp); mustSave = true; } } } missingTimestamps.remove(height); if (mustSave) { walletSaveLater(); } }
private void fetchTimestamp(BitTransaction tx, Integer height) { checkState(lock.isHeldByCurrentThread(), "Lock is held by another thread"); if (blockTimes.containsKey(height)) { tx.setTimestamp(blockTimes.get(height)); } else { if (log.isDebugEnabled()) log.debug("Must get timestamp for {} block on height {}", type.getName(), height); if (!missingTimestamps.containsKey(height)) { missingTimestamps.put(height, new HashSet<Sha256Hash>()); missingTimestamps.get(height).add(tx.getHash()); if (blockchainConnection != null) { blockchainConnection.getBlock(height, this); } } else { missingTimestamps.get(height).add(tx.getHash()); } } }
private void fetchTransactionIfNeeded(Sha256Hash txHash, @Nullable Integer height) { checkState(lock.isHeldByCurrentThread(), "Lock is held by another thread"); // Check if need to fetch the transaction if (!isTransactionAvailableOrQueued(txHash)) { fetchingTransactions.put(txHash, height); log.info("Going to fetch transaction with hash {}", txHash); if (blockchainConnection != null) { blockchainConnection.getTransaction(txHash, this); } } else if (fetchingTransactions.containsKey(txHash)) { // Check if we should update the confirmation height Integer txHeight = fetchingTransactions.get(txHash); if (height != null && txHeight != null && height < txHeight) { fetchingTransactions.put(txHash, height); } } }
public Optional<String> getToken() { final ListenableFuture<String> masterPassword = encyptionKeyProvider.getMasterPassword(); if (!masterPassword.isDone()) { return Optional.empty(); } final String key = encyptionKeyProvider.getImmediatePassword(); final String s = key + " meta"; final ECKey privKey = ECKey.fromPrivate(Sha256Hash.twiceOf(s.getBytes(Charsets.UTF_8)).getBytes()); /* @POST @Path("/token") @Produces(MediaType.APPLICATION_OCTET_STREAM) public Response createToken(@QueryParam("timestamp") Long nonce, @QueryParam("signature") String signature) { */ // } final long timeStamp = Instant.now().toEpochMilli(); try { final String url = rootPath + "auth/token"; final HttpResponse<String> token = Unirest.post(url) .queryString("timestamp", timeStamp) .queryString("signature", privKey.signMessage(String.valueOf(timeStamp))) .asString(); if (token.getStatus() != 200) { return Optional.empty(); } return Optional.of(token.getBody()); } catch (UnirestException e) { LOGGER.error("exception from remote service when trying to get token", e); return Optional.empty(); } }
public synchronized void put(StoredBlock block) throws BlockStoreException { ensureOpen(); try { Sha256Hash hash = block.getHeader().getHash(); checkState(blockMap.get(hash) == null, "Attempt to insert duplicate"); // Append to the end of the file. The other fields in StoredBlock will be recalculated when it's reloaded. byte[] bytes = block.getHeader().bitcoinSerialize(); file.write(bytes); blockMap.put(hash, block); } catch (IOException e) { throw new BlockStoreException(e); } }
@Test public void testBuildRawTransaction() { byte[][] transaction = ptf.buildRawTransaction(); assertEquals(1, value(transaction[0])); assertEquals(1, value(transaction[1])); //check for number of outputs assertEquals(1, value(transaction[7])); //check for zero coins assertEquals(0, value(transaction[8])); //check length of script assertEquals(25, value(transaction[9])); // Create the raw transaction and hash it byte[] raw = Bytes.concat(transaction[0], transaction[1], transaction[2], transaction[3], transaction[4], transaction[5], transaction[6], transaction[7], transaction[8], transaction[9], transaction[10], transaction[11], transaction[12]); byte[] hashRaw = Sha256Hash.hash(Sha256Hash.hash(raw)); //check for the correct hash byte[] correctHash = Util.hexStringToByteArray("09AB317A17BBEB4F46EFA2BDA80F137059608AA6696FF5155F0E2A72DC6C249E"); for(int i=0; i< correctHash.length; i++) { assertEquals(correctHash[i], hashRaw[i]); } }
/** * Add a transaction to the tracked list. The TransactionList automatically adds itself as a confidence listener * at this transaction * @param transaction to be added to the list */ void add(Transaction transaction) { logger.debug("Adding tx %s to TransactionList", transaction.getHashAsString()); Sha256Hash txHash = transaction.getHash(); Transaction prevValue = transactions.put(txHash, transaction); if (null != prevValue) prevValue.getConfidence().removeEventListener(this); transaction.getConfidence().addEventListener(this); logger.debug("This list has now %d transactions", transactions.size()); informStateListenersTransactionsChanged(getTransactions()); }
/** * A List of Transactions with their state. * @return A Transactions Object as used in the swagger REST api */ public Transactions getTransactions() { Transactions txes = new Transactions(); for (Map.Entry<Sha256Hash, Transaction> element : transactions.entrySet()) { TransactionsInner transactionsInner = new TransactionsInner(); transactionsInner.setTransactionId(element.getKey().toString()); transactionsInner.setState(mapConfidenceToState(element.getValue().getConfidence())); txes.add(transactionsInner); } return txes; }
@Override public void onConfidenceChanged(TransactionConfidence confidence, ChangeReason reason) { logger.info(String.format(" tx %s changed state to (%s, %d, %d) for change reason %s", confidence.getTransactionHash().toString(), confidence.getConfidenceType().toString(), confidence.numBroadcastPeers(), confidence.getDepthInBlocks(), reason.toString())); boolean refreshNeeded = false; if (lastState == null || lastMostConfidentTxHash == null) { lastState = mapConfidenceToState(confidence); lastMostConfidentTxHash = confidence.getTransactionHash(); refreshNeeded = true; } else { TransactionConfidence newMostConfidentConfidence = tryDetermineMostConfidentTransaction().getConfidence(); State newState = mapConfidenceToState(newMostConfidentConfidence); Sha256Hash newTxHash = newMostConfidentConfidence.getTransactionHash(); if (lastMostConfidentTxHash != newTxHash || statesAreDifferent(lastState, newState)) { lastMostConfidentTxHash = newTxHash; lastState = newState; refreshNeeded = true; } } if (refreshNeeded) { informStateListenersMostConfidentState(lastMostConfidentTxHash, lastState); } Transactions newTransactions = getTransactions(); if (transactionsAreDifferent(newTransactions, lastTransactions)) { lastTransactions = newTransactions; informStateListenersTransactionsChanged(lastTransactions); } }
public static long longHash(final Sha256Hash hash) { final byte[] bytes = hash.getBytes(); return (bytes[31] & 0xFFl) | ((bytes[30] & 0xFFl) << 8) | ((bytes[29] & 0xFFl) << 16) | ((bytes[28] & 0xFFl) << 24) | ((bytes[27] & 0xFFl) << 32) | ((bytes[26] & 0xFFl) << 40) | ((bytes[25] & 0xFFl) << 48) | ((bytes[23] & 0xFFl) << 56); }
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(); }
/** * Returns a transaction object given its hash, if it exists in this wallet, or null otherwise. */ @Nullable public Transaction getTransaction(Sha256Hash hash) { lock.lock(); try { return transactions.get(hash); } finally { lock.unlock(); } }
private void toStringHelper(StringBuilder builder, Map<Sha256Hash, Transaction> transactionMap, @Nullable AbstractBlockChain chain, @Nullable Comparator<Transaction> sortOrder) { checkState(lock.isHeldByCurrentThread()); final Collection<Transaction> txns; if (sortOrder != null) { txns = new TreeSet<>(sortOrder); txns.addAll(transactionMap.values()); } else { txns = transactionMap.values(); } for (Transaction tx : txns) { try { builder.append(tx.getValue(this).toFriendlyString()); builder.append(" total value (sends "); builder.append(tx.getValueSentFromMe(this).toFriendlyString()); builder.append(" and receives "); builder.append(tx.getValueSentToMe(this).toFriendlyString()); builder.append(")\n"); } catch (ScriptException e) { // Ignore and don't print this line. } if (tx.hasConfidence()) builder.append(" confidence: ").append(tx.getConfidence()).append('\n'); builder.append(tx.toString(chain)); } }
/** Returns the hash of the last seen best-chain block, or null if the wallet is too old to store this data. */ @Nullable public Sha256Hash getLastBlockSeenHash() { lock.lock(); try { return lastBlockSeenHash; } finally { lock.unlock(); } }