@Nullable public synchronized Transaction getRawTransaction(Sha256Hash hash) { lock.lock(); try { NxtTransaction tx = rawtransactions.get(hash); if (tx != null) { return tx.getRawTransaction(); } else { return null; } } finally { lock.unlock(); } }
@VisibleForTesting void addNewTransactionIfNeeded(NxtTransaction tx) { lock.lock(); try { // If was fetching this tx, remove it //fetchingTransactions.remove(tx.getFullHash()); log.info("adding transaction to wallet"); // This tx not in wallet, add it NxtTransaction storedTx = rawtransactions.get(tx.getHash()); if (storedTx == null) { log.info("transaction added"); rawtransactions.put(tx.getHash(), tx); //tx.getConfidence().setConfidenceType(TransactionConfidence.ConfidenceType.PENDING); //addWalletTransaction(WalletTransaction.Pool.PENDING, tx, true); queueOnNewBalance(); } else { storedTx.setDepthInBlocks(tx.getDepthInBlocks()); storedTx.setAppearedAtChainHeight(tx.getAppearedAtChainHeight()); } } finally { lock.unlock(); } }
@Override public void onTransactionUpdate(NxtTransaction tx) { if (log.isInfoEnabled()) log.info("Got a new transaction {}", tx.getHashAsString()); lock.lock(); try { addNewTransactionIfNeeded(tx); } finally { lock.unlock(); } }
@Test public void testNxtTransaction() throws WalletAccount.WalletAccountException, NxtException.ValidationException { NxtAddress destination = (NxtAddress) otherAccount.getReceiveAddress(); Value amount = NXT.value("1"); NxtSendRequest req = nxtAccount.sendCoinsOffline(destination, amount); nxtAccount.completeAndSignTx(req); Transaction nxtTx = req.nxtTxBuilder.build(); // nxtTx.sign(nxtSecret); byte[] txBytes = req.nxtTxBuilder.build().getBytes(); req.tx = new NxtTransaction(NXT, req.nxtTxBuilder.build()); Transaction parsedTx = TransactionImpl.parseTransaction(txBytes); assertEquals(Attachment.ORDINARY_PAYMENT, parsedTx.getAttachment()); assertEquals(NxtFamily.DEFAULT_DEADLINE, parsedTx.getDeadline()); assertEquals((req.tx.getRawTransaction()).getTimestamp(), parsedTx.getTimestamp()); assertEquals(nxtAccountId, parsedTx.getSenderId()); assertArrayEquals(nxtPublicKey, parsedTx.getSenderPublicKey()); assertEquals(amount.value, parsedTx.getAmountNQT()); assertEquals(req.fee.value, parsedTx.getFeeNQT()); assertEquals(destination.getAccountId(), parsedTx.getRecipientId()); // System.out.println(Convert.toHexString(nxtTx.getBytes())); // TODO check signature }
@Override public void onResponse(Response response) throws IOException { try { if (!response.isSuccessful()) { log.info("Unable to fetch txs."); log.info("[Error code] = " + response.code()); } JSONObject reply = parseReply(response); //String txId = reply.getString("transaction"); //Integer confirmations = reply.getInt("confirmations"); //getTransactionBytes(txId, listener, confirmations); NxtTransaction tx = new NxtTransaction(type, TransactionImpl.parseTransaction(reply)); //log.info("Transaction fetched"); listener.onTransactionUpdate(tx); } catch (IOException e) { log.info("IOException: " + e.getMessage()); } catch (JSONException e) { log.info("Could not parse JSON: " + e.getMessage()); }catch (NxtException.NotValidException e) { log.info("Not valid transaction: " + e.getMessage()); } } });
@Override public void onResponse(Response response) throws IOException { try { if (!response.isSuccessful()) { log.info("Unable to fetch txs."); log.info("[Error code] = " + response.code()); } JSONObject reply = parseReply(response); String txBytes = reply.getString("transactionBytes"); TransactionImpl rawTx = TransactionImpl.parseTransaction(Convert.parseHexString(txBytes)); rawTx.setConfirmations(confirmations); NxtTransaction tx = new NxtTransaction(type, rawTx); log.info("Fetching tx bytes"); listener.onTransactionUpdate(tx); } catch (IOException e) { log.info("IOException: " + e.getMessage()); } catch (JSONException e) { log.info("Could not parse JSON: " + e.getMessage()); } catch (NxtException.ValidationException e) { log.info("Transaction is invalid"); e.printStackTrace(); } } });
@Override public String getHashAsString() { return getHash().toString(); }
public void signTransaction(NxtSendRequest request) { checkArgument(request.isCompleted(), "Send request is not completed"); checkArgument(request.tx != null, "No transaction found in send request"); Transaction tx = request.tx.getRawTransaction(); byte[] privateKey; if (rootKey.isEncrypted()) { checkArgument(request.aesKey != null, "Wallet is encrypted but no decryption key provided"); privateKey = rootKey.toDecrypted(request.aesKey).getPrivateKey(); } else { privateKey = rootKey.getPrivateKey(); } tx.sign(privateKey); Arrays.fill(privateKey, (byte) 0); // clear private key }
public void completeTransaction(NxtSendRequest request) throws WalletAccountException { checkArgument(!request.isCompleted(), "Given SendRequest has already been completed."); if (request.type.getTransactionVersion() > 0) { request.nxtTxBuilder.ecBlockHeight(lastEcBlockHeight); request.nxtTxBuilder.ecBlockId(lastEcBlockId); } // TODO check if the destination public key was announced and if so, remove it from the tx: // request.nxtTxBuilder.publicKeyAnnouncement(null); try { request.tx = new NxtTransaction(type, request.nxtTxBuilder.build()); request.setCompleted(true); } catch (NxtException.NotValidException e) { throw new WalletAccount.WalletAccountException(e); } if (request.signTransaction) { signTransaction(request); } }
@Override public byte[] getHashBytes() { return getHash().getBytes(); }
public boolean broadcastNxtTxSync(NxtTransaction tx) throws TransactionBroadcastException { if (isConnected()) { if (log.isInfoEnabled()) { log.info("Broadcasting tx {}", Utils.HEX.encode(tx.getRawTransaction().getBytes())); } boolean success = blockchainConnection.broadcastTxSync(tx); if (success) { onTransactionBroadcast(tx); } else { onTransactionBroadcastError(tx); } return success; } else { throw new TransactionBroadcastException("No connection available"); } }
@Override public boolean broadcastTxSync(final NxtTransaction tx) { RequestBody formBody = new FormEncodingBuilder().add("requestType","broadcastTransaction") .add("transactionBytes", Convert.toHexString(tx.getRawTransaction().getBytes())).build(); Request request = new Request.Builder().url(getBaseUrl()).post(formBody).build(); // FIXME this is not a sync call getHttpClient().newCall(request).enqueue(new Callback() { @Override public void onFailure(Request request, IOException e) { log.info("Failed to communicate with server: " + request.toString()); } @Override public void onResponse(Response response) throws IOException { try { if (!response.isSuccessful()) { log.info("Unable to fetch txs."); log.info("[Error code] = " + response.code()); } JSONObject reply = parseReply(response); log.info("Transaction broadcasted {0}", reply.toString()); } catch (IOException e) { log.info("IOException: " + e.getMessage()); } catch (JSONException e) { log.info("Could not parse JSON: " + e.getMessage()); } } }); return true; }