@Override JSONStreamAware processRequest(HttpServletRequest req) { JSONObject response = new JSONObject(); long longId = Convert.fullHashToId(Convert.parseHexString(req.getParameter("fullHash"))); response.put("longId", String.valueOf(longId)); response.put("stringId", Long.toUnsignedString(longId)); return response; }
@Override public void run() { String shareRequest = plotFile.getAddress() + ":" + nonce + ":" + processing.getHeight() + " deadline {" + deadline + "}"; LOGGER.info("Submitting share {" + shareRequest + "}"); try { if (poolType.equals(POOL_TYPE_URAY)) { String request = poolUrl + "/burst?requestType=submitNonce&secretPhrase=pool-mining&nonce=" + Convert.toUnsignedLong(nonce) + "&accountId=" + Convert.toUnsignedLong(plotFile.getAddress()); String response = restTemplate.postForObject(request, shareRequest, String.class); LOGGER.info("Response {" + response + "}}"); plotFile.addShare(); } else if (poolType.equals(POOL_TYPE_OFFICIAL)) { shareRequest = plotFile.getAddress() + ":" + nonce + ":" + processing.getHeight() + "\n"; String response = restTemplate.postForObject(poolUrl + "/pool/submitWork", shareRequest, String.class); LOGGER.info("Response {" + response + "}}"); plotFile.addShare(); } lastShareSubmitTime = System.currentTimeMillis(); } catch (Exception ex) { LOGGER.info("Failed to submitShare {" + shareRequest + "}"); } }
@Override JSONStreamAware processRequest(HttpServletRequest req) { String accountIdString = Convert.emptyToNull(req.getParameter("account")); Long accountId = null; if (accountIdString != null) { try { accountId = Convert.parseUnsignedLong(accountIdString); } catch (RuntimeException e) { return INCORRECT_ACCOUNT; } } JSONArray transactionIds = new JSONArray(); for (Transaction transaction : Nxt.getTransactionProcessor().getAllUnconfirmedTransactions()) { if (accountId != null && !(accountId.equals(transaction.getSenderId()) || accountId.equals(transaction.getRecipientId()))) { continue; } transactionIds.add(transaction.getStringId()); } JSONObject response = new JSONObject(); response.put("unconfirmedTransactionIds", transactionIds); return response; }
public static String generateHallmark(String secretPhrase, String host, int weight, int date) { if (host.length() == 0 || host.length() > 100) { throw new IllegalArgumentException("Hostname length should be between 1 and 100"); } if (weight <= 0 || weight > Constants.MAX_BALANCE_NXT) { throw new IllegalArgumentException( "Weight should be between 1 and " + Constants.MAX_BALANCE_NXT); } byte[] publicKey = Crypto.getPublicKey(secretPhrase); byte[] hostBytes = Convert.toBytes(host); ByteBuffer buffer = ByteBuffer.allocate(32 + 2 + hostBytes.length + 4 + 4 + 1); buffer.order(ByteOrder.LITTLE_ENDIAN); buffer.put(publicKey); buffer.putShort((short) hostBytes.length); buffer.put(hostBytes); buffer.putInt(weight); buffer.putInt(date); byte[] data = buffer.array(); data[data.length - 1] = (byte) ThreadLocalRandom.current().nextInt(); byte[] signature = Crypto.sign(data, secretPhrase); return Convert.toHexString(data) + Convert.toHexString(signature); }
@Override JSONStreamAware processRequest(HttpServletRequest req) throws NxtException { long accountId = ParameterParser.getAccount(req).getId(); long assetId = 0; try { assetId = Convert.parseUnsignedLong(req.getParameter("asset")); } catch (RuntimeException e) { // ignore } int firstIndex = ParameterParser.getFirstIndex(req); int lastIndex = ParameterParser.getLastIndex(req); DbIterator<Order.Ask> askOrders; if (assetId == 0) { askOrders = Order.Ask.getAskOrdersByAccount(accountId, firstIndex, lastIndex); } else { askOrders = Order.Ask.getAskOrdersByAccountAsset(accountId, assetId, firstIndex, lastIndex); } JSONArray orderIds = new JSONArray(); try { while (askOrders.hasNext()) { orderIds.add(Convert.toUnsignedLong(askOrders.next().getId())); } } finally { askOrders.close(); } JSONObject response = new JSONObject(); response.put("askOrderIds", orderIds); return response; }
@Override public Object getCellValue(Object element) { ITransaction transaction = (ITransaction) element; Transaction t = transaction.getNative(); if (accountId.equals(t.getSenderId())) { return Convert.toUnsignedLong(t.getRecipientId()); } return Convert.toUnsignedLong(t.getSenderId()); }
@Test public void sha256() { byte[] hash = HashFunction.SHA256.hash(new byte[] {0x61, 0x62, 0x63}); Assert.assertEquals( "ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad", Convert.toHexString(hash)); hash = HashFunction.SHA256.hash(new byte[] {}); Assert.assertEquals( "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", Convert.toHexString(hash)); }
@Override public String toString() { return "AccountAsset account_id: " + Convert.toUnsignedLong(accountId) + " asset_id: " + Convert.toUnsignedLong(assetId) + " quantity: " + quantityQNT + " unconfirmedQuantity: " + unconfirmedQuantityQNT; }
@Test public void sha3() { byte[] hash = HashFunction.SHA3.hash(new byte[] {(byte) 0x41, (byte) 0xFB}); Assert.assertEquals( "A8EACEDA4D47B3281A795AD9E1EA2122B407BAF9AABCB9E18B5717B7873537D2".toLowerCase(), Convert.toHexString(hash)); hash = HashFunction.SHA3.hash(new byte[] {}); Assert.assertEquals( "c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", Convert.toHexString(hash)); }
@Test public void scrypt() { byte[] hash = HashFunction.SCRYPT.hash(new byte[] {(byte) 0x41, (byte) 0xFB}); Assert.assertEquals( "da3f4f010d772567a8896465d11df28693b244c91b8ba4bea5a30f6be572b667".toLowerCase(), Convert.toHexString(hash)); hash = HashFunction.SCRYPT.hash(new byte[] {}); Assert.assertEquals( "0cf2967ca5c120e80b37f8f75c971842e05da107278c1058e6ffbc68911c11f1", Convert.toHexString(hash)); }
void addToBalanceAndUnconfirmedBalanceNQT(long amountNQT) { if (amountNQT == 0) { return; } this.balanceNQT = Convert.safeAdd(this.balanceNQT, amountNQT); this.unconfirmedBalanceNQT = Convert.safeAdd(this.unconfirmedBalanceNQT, amountNQT); addToGuaranteedBalanceNQT(amountNQT); checkBalance(this.id, this.balanceNQT, this.unconfirmedBalanceNQT); accountTable.insert(this); listeners.notify(this, Event.BALANCE); listeners.notify(this, Event.UNCONFIRMED_BALANCE); }
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { resp.setHeader("Cache-Control", "no-cache, no-store, must-revalidate, private"); resp.setHeader("Pragma", "no-cache"); resp.setDateHeader("Expires", 0); resp.setContentType("text/html; charset=UTF-8"); if (API.allowedBotHosts != null && !API.allowedBotHosts.contains(req.getRemoteHost())) { resp.sendError(HttpServletResponse.SC_FORBIDDEN); return; } try (PrintWriter writer = resp.getWriter()) { writer.print(header1); writer.print(buildLinks(req)); writer.print(header2); String requestType = Convert.nullToEmpty(req.getParameter("requestType")); APIServlet.APIRequestHandler requestHandler = APIServlet.apiRequestHandlers.get(requestType); StringBuilder bufJSCalls = new StringBuilder(); if (requestHandler != null) { writer.print( form( requestType, true, requestHandler.getClass().getName(), requestHandler.getParameters(), requestHandler.requirePost())); bufJSCalls.append("apiCalls.push(\"").append(requestType).append("\");\n"); } else { String requestTag = Convert.nullToEmpty(req.getParameter("requestTag")); Set<String> taggedTypes = requestTags.get(requestTag); for (String type : (taggedTypes != null ? taggedTypes : allRequestTypes)) { requestHandler = APIServlet.apiRequestHandlers.get(type); writer.print( form( type, false, requestHandler.getClass().getName(), APIServlet.apiRequestHandlers.get(type).getParameters(), APIServlet.apiRequestHandlers.get(type).requirePost())); bufJSCalls.append("apiCalls.push(\"").append(type).append("\");\n"); } } writer.print(footer1); writer.print(bufJSCalls.toString()); writer.print(footer2); } }
@Override public Object getCellValue(Object element) { ITransaction transaction = (ITransaction) element; Transaction t = transaction.getNative(); IContact contact; if (t.getSenderId().equals(accountId)) contact = getContactsService().getContact(Convert.toUnsignedLong(t.getRecipientId())); else contact = getContactsService().getContact(Convert.toUnsignedLong(t.getSenderId())); if (contact != null) return contact.getName(); return EMPTY_STRING; }
public static Account getAccount(byte[] publicKey) { Account account = accountTable.get(accountDbKeyFactory.newKey(getId(publicKey))); if (account == null) { return null; } if (account.getPublicKey() == null || Arrays.equals(account.getPublicKey(), publicKey)) { return account; } throw new RuntimeException( "DUPLICATE KEY for account " + Convert.toUnsignedLong(account.getId()) + " existing key " + Convert.toHexString(account.getPublicKey()) + " new key " + Convert.toHexString(publicKey)); }
@Override JSONStreamAware processRequest(HttpServletRequest req) { String[] assets = req.getParameterValues("assets"); boolean includeCounts = !"false".equalsIgnoreCase(req.getParameter("includeCounts")); JSONObject response = new JSONObject(); JSONArray assetsJSONArray = new JSONArray(); response.put("assets", assetsJSONArray); for (String assetIdString : assets) { if (assetIdString == null || assetIdString.equals("")) { continue; } try { Asset asset = Asset.getAsset(Convert.parseUnsignedLong(assetIdString)); if (asset == null) { return UNKNOWN_ASSET; } assetsJSONArray.add(JSONData.asset(asset, includeCounts)); } catch (RuntimeException e) { return INCORRECT_ASSET; } } return response; }
private void addToGuaranteedBalanceNQT(long amountNQT) { if (amountNQT <= 0) { return; } int blockchainHeight = Nxt.getBlockchain().getHeight(); try (Connection con = Db.getConnection(); PreparedStatement pstmtSelect = con.prepareStatement( "SELECT additions FROM account_guaranteed_balance " + "WHERE account_id = ? and height = ?"); PreparedStatement pstmtUpdate = con.prepareStatement( "MERGE INTO account_guaranteed_balance (account_id, " + " additions, height) KEY (account_id, height) VALUES(?, ?, ?)")) { pstmtSelect.setLong(1, this.id); pstmtSelect.setInt(2, blockchainHeight); try (ResultSet rs = pstmtSelect.executeQuery()) { long additions = amountNQT; if (rs.next()) { additions = Convert.safeAdd(additions, rs.getLong("additions")); } pstmtUpdate.setLong(1, this.id); pstmtUpdate.setLong(2, additions); pstmtUpdate.setInt(3, blockchainHeight); pstmtUpdate.executeUpdate(); } } catch (SQLException e) { throw new RuntimeException(e.toString(), e); } }
@Override public void run() { try { try { List<Transaction> transactionList = new ArrayList<>(); int curTime = Convert.getEpochTime(); for (TransactionImpl transaction : nonBroadcastedTransactions.values()) { if (TransactionDb.hasTransaction(transaction.getId()) || transaction.getExpiration() < curTime) { nonBroadcastedTransactions.remove(transaction.getId()); } else if (transaction.getTimestamp() < curTime - 30) { transactionList.add(transaction); } } if (transactionList.size() > 0) { Peers.sendToSomePeers(transactionList); } } catch (Exception e) { Logger.logDebugMessage("Error in transaction re-broadcasting thread", e); } } catch (Throwable t) { Logger.logMessage("CRITICAL ERROR. PLEASE REPORT TO THE DEVELOPERS.\n" + t.toString()); t.printStackTrace(); System.exit(1); } }
@Override public Transaction newTransaction( short deadline, byte[] senderPublicKey, Long recipientId, long amountNQT, long feeNQT, String referencedTransactionFullHash, Attachment attachment) throws NxtException.ValidationException { TransactionImpl transaction = new TransactionImpl( attachment.getTransactionType(), Convert.getEpochTime(), deadline, senderPublicKey, recipientId, amountNQT, feeNQT, referencedTransactionFullHash, null); transaction.setAttachment(attachment); transaction.validateAttachment(); return transaction; }
void addToForgedBalanceNQT(long amountNQT) { if (amountNQT == 0) { return; } this.forgedBalanceNQT = Convert.safeAdd(this.forgedBalanceNQT, amountNQT); accountTable.insert(this); }
private static void checkBalance(long accountId, long confirmed, long unconfirmed) { if (confirmed < 0) { throw new DoubleSpendingException( "Negative balance or quantity for account " + Convert.toUnsignedLong(accountId)); } if (unconfirmed < 0) { throw new DoubleSpendingException( "Negative unconfirmed balance or quantity for account " + Convert.toUnsignedLong(accountId)); } if (unconfirmed > confirmed) { throw new DoubleSpendingException( "Unconfirmed exceeds confirmed balance or quantity for account " + Convert.toUnsignedLong(accountId)); } }
public long getGuaranteedBalanceNQT(final int numberOfConfirmations, final int currentHeight) { if (numberOfConfirmations >= Nxt.getBlockchain().getHeight()) { return 0; } if (numberOfConfirmations > 2880 || numberOfConfirmations < 0) { throw new IllegalArgumentException( "Number of required confirmations must be between 0 and " + 2880); } int height = currentHeight - numberOfConfirmations; try (Connection con = Db.getConnection(); PreparedStatement pstmt = con.prepareStatement( "SELECT SUM (additions) AS additions " + "FROM account_guaranteed_balance WHERE account_id = ? AND height > ? AND height <= ?")) { pstmt.setLong(1, this.id); pstmt.setInt(2, height); pstmt.setInt(3, currentHeight); try (ResultSet rs = pstmt.executeQuery()) { if (!rs.next()) { return balanceNQT; } return Math.max(Convert.safeSubtract(balanceNQT, rs.getLong("additions")), 0); } } catch (SQLException e) { throw new RuntimeException(e.toString(), e); } }
// returns true iff: // this.publicKey is set to null (in which case this.publicKey also gets set to key) // or // this.publicKey is already set to an array equal to key boolean setOrVerify(byte[] key, int height) { if (this.publicKey == null) { if (Db.isInTransaction()) { this.publicKey = key; this.keyHeight = -1; accountTable.insert(this); } return true; } else if (Arrays.equals(this.publicKey, key)) { return true; } else if (this.keyHeight == -1) { Logger.logMessage("DUPLICATE KEY!!!"); Logger.logMessage( "Account key for " + Convert.toUnsignedLong(id) + " was already set to a different one at the same height " + ", current height is " + height + ", rejecting new key"); return false; } else if (this.keyHeight >= height) { Logger.logMessage("DUPLICATE KEY!!!"); if (Db.isInTransaction()) { Logger.logMessage( "Changing key for account " + Convert.toUnsignedLong(id) + " at height " + height + ", was previously set to a different one at height " + keyHeight); this.publicKey = key; this.keyHeight = height; accountTable.insert(this); } return true; } Logger.logMessage("DUPLICATE KEY!!!"); Logger.logMessage( "Invalid key for account " + Convert.toUnsignedLong(id) + " at height " + height + ", was already set to a different one at height " + keyHeight); return false; }
private void loadPassPhrases() { try { List<String> passphrases = Files.readAllLines(Paths.get("passphrases.txt"), Charset.forName("US-ASCII")); for (String ps : passphrases) { if (!ps.isEmpty()) { byte[] publicKey = Crypto.getPublicKey(ps); byte[] publicKeyHash = Crypto.sha256().digest(publicKey); Long id = Convert.fullHashToId(publicKeyHash); loadedPassPhrases.put(id, ps); LOGGER.info("Added key: {" + ps + "} -> {" + Convert.toUnsignedLong(id) + "}"); } } } catch (IOException e) { LOGGER.info("Warning: no passphrases.txt found"); } }
@Override JSONStreamAware processRequest(HttpServletRequest req) throws NxtException { String transactionBytes = Convert.emptyToNull(req.getParameter("transactionBytes")); String transactionJSON = Convert.emptyToNull(req.getParameter("transactionJSON")); String prunableAttachmentJSON = Convert.emptyToNull(req.getParameter("prunableAttachmentJSON")); Transaction transaction = ParameterParser.parseTransaction(transactionJSON, transactionBytes, prunableAttachmentJSON) .build(); JSONObject response = JSONData.unconfirmedTransaction(transaction); try { transaction.validate(); } catch (NxtException.ValidationException | RuntimeException e) { Logger.logDebugMessage(e.getMessage(), e); response.put("validate", false); JSONData.putException(response, e, "Invalid transaction"); } response.put("verify", transaction.verifySignature()); return response; }
void addToAssetAndUnconfirmedAssetBalanceQNT(long assetId, long quantityQNT) { if (quantityQNT == 0) { return; } AccountAsset accountAsset; accountAsset = accountAssetTable.get(accountAssetDbKeyFactory.newKey(this.id, assetId)); long assetBalance = accountAsset == null ? 0 : accountAsset.quantityQNT; assetBalance = Convert.safeAdd(assetBalance, quantityQNT); long unconfirmedAssetBalance = accountAsset == null ? 0 : accountAsset.unconfirmedQuantityQNT; unconfirmedAssetBalance = Convert.safeAdd(unconfirmedAssetBalance, quantityQNT); if (accountAsset == null) { accountAsset = new AccountAsset(this.id, assetId, assetBalance, unconfirmedAssetBalance); } else { accountAsset.quantityQNT = assetBalance; accountAsset.unconfirmedQuantityQNT = unconfirmedAssetBalance; } accountAsset.save(); listeners.notify(this, Event.ASSET_BALANCE); listeners.notify(this, Event.UNCONFIRMED_ASSET_BALANCE); assetListeners.notify(accountAsset, Event.ASSET_BALANCE); assetListeners.notify(accountAsset, Event.UNCONFIRMED_ASSET_BALANCE); }
public static Hallmark parseHallmark(String hallmarkString) { byte[] hallmarkBytes = Convert.parseHexString(hallmarkString); ByteBuffer buffer = ByteBuffer.wrap(hallmarkBytes); buffer.order(ByteOrder.LITTLE_ENDIAN); byte[] publicKey = new byte[32]; buffer.get(publicKey); int hostLength = buffer.getShort(); if (hostLength > 300) { throw new IllegalArgumentException("Invalid host length"); } byte[] hostBytes = new byte[hostLength]; buffer.get(hostBytes); String host = Convert.toString(hostBytes); int weight = buffer.getInt(); int date = buffer.getInt(); buffer.get(); byte[] signature = new byte[64]; buffer.get(signature); byte[] data = new byte[hallmarkBytes.length - 64]; System.arraycopy(hallmarkBytes, 0, data, 0, data.length); boolean isValid = host.length() < 100 && weight > 0 && weight <= Constants.MAX_BALANCE_NXT && Crypto.verify(signature, data, publicKey, true); try { return new Hallmark(hallmarkString, publicKey, signature, host, weight, date, isValid); } catch (URISyntaxException e) { throw new RuntimeException(e.toString(), e); } }
@Override JSONStreamAware processRequest(HttpServletRequest req) throws ParameterException { String query = Convert.nullToEmpty(req.getParameter("query")); int firstIndex = ParameterParser.getFirstIndex(req); int lastIndex = ParameterParser.getLastIndex(req); boolean includeCounts = !"false".equalsIgnoreCase(req.getParameter("includeCounts")); JSONObject response = new JSONObject(); JSONArray jsonArray = new JSONArray(); try (DbIterator<Currency> currencies = Currency.searchCurrencies(query, firstIndex, lastIndex)) { while (currencies.hasNext()) { jsonArray.add(JSONData.currency(currencies.next(), includeCounts)); } } response.put("currencies", jsonArray); return response; }
void apply(byte[] key, int height) { if (!setOrVerify(key, this.creationHeight)) { throw new IllegalStateException("Public key mismatch"); } if (this.publicKey == null) { throw new IllegalStateException( "Public key has not been set for account " + Convert.toUnsignedLong(id) + " at height " + height + ", key height is " + keyHeight); } if (this.keyHeight == -1 || this.keyHeight > height) { this.keyHeight = height; accountTable.insert(this); } }
@Override protected JSONStreamAware processRequest(HttpServletRequest req) throws NxtException { DigitalGoodsStore.Goods goods = ParameterParser.getGoods(req); if (goods.isDelisted()) { return UNKNOWN_GOODS; } int quantity = ParameterParser.getGoodsQuantity(req); if (quantity > goods.getQuantity()) { return INCORRECT_PURCHASE_QUANTITY; } long priceNQT = ParameterParser.getPriceNQT(req); if (priceNQT != goods.getPriceNQT()) { return INCORRECT_PURCHASE_PRICE; } String deliveryDeadlineString = Convert.emptyToNull(req.getParameter("deliveryDeadlineTimestamp")); if (deliveryDeadlineString == null) { return MISSING_DELIVERY_DEADLINE_TIMESTAMP; } int deliveryDeadline; try { deliveryDeadline = Integer.parseInt(deliveryDeadlineString); if (deliveryDeadline <= Nxt.getEpochTime()) { return INCORRECT_DELIVERY_DEADLINE_TIMESTAMP; } } catch (NumberFormatException e) { return INCORRECT_DELIVERY_DEADLINE_TIMESTAMP; } Account buyerAccount = ParameterParser.getSenderAccount(req); Account sellerAccount = Account.getAccount(goods.getSellerId()); Attachment attachment = new Attachment.DigitalGoodsPurchase(goods.getId(), quantity, priceNQT, deliveryDeadline); try { return createTransaction(req, buyerAccount, sellerAccount.getId(), 0, attachment); } catch (NxtException.InsufficientBalanceException e) { return JSONResponses.NOT_ENOUGH_FUNDS; } }
private static String buildLinks(HttpServletRequest req) { StringBuilder buf = new StringBuilder(); String requestTag = Convert.nullToEmpty(req.getParameter("requestTag")); buf.append("<li"); if (requestTag.equals("")) { buf.append(" class=\"active\""); } buf.append("><a href=\"/test\">All</a></li>"); for (APITag apiTag : APITag.values()) { if (requestTags.get(apiTag.name()) != null) { buf.append("<li"); if (requestTag.equals(apiTag.name())) { buf.append(" class=\"active\""); } buf.append("><a href=\"/test?requestTag=").append(apiTag.name()).append("\">"); buf.append(apiTag.getDisplayName()).append("</a></li>").append(" "); } } return buf.toString(); }