public static Block getECBlock(int timestamp) {
   Block block = blockchain.getLastBlock();
   if (timestamp < block.getTimestamp() - 15) {
     throw new IllegalArgumentException(
         "Timestamp cannot be more than 15 s earlier than last block timestamp: "
             + block.getTimestamp());
   }
   int distance = 0;
   while (block.getTimestamp() > timestamp - Constants.EC_RULE_TERMINATOR
       && distance < Constants.EC_BLOCK_DISTANCE_LIMIT) {
     block = blockchain.getBlock(block.getPreviousBlockId());
     distance += 1;
   }
   return block;
 }
 public static boolean verifyFork(Transaction transaction) {
   if (blockchain.getHeight() < Constants.DIGITAL_GOODS_STORE_BLOCK) {
     return true;
   }
   if (transaction.getReferencedTransactionFullHash() != null) {
     return true;
   }
   if (blockchain.getHeight() < Constants.EC_CHANGE_BLOCK_1) {
     if (blockchain.getHeight() - transaction.getECBlockHeight()
         > Constants.EC_BLOCK_DISTANCE_LIMIT) {
       return false;
     }
   }
   Block ecBlock = blockchain.getBlock(transaction.getECBlockId());
   return ecBlock != null && ecBlock.getHeight() == transaction.getECBlockHeight();
 }
Пример #3
0
 /**
  * Trim the account ledger table
  *
  * @param height Trim height
  */
 @Override
 public void trim(int height) {
   if (trimKeep <= 0) return;
   try (Connection con = db.getConnection();
       PreparedStatement pstmt =
           con.prepareStatement("DELETE FROM account_ledger WHERE height <= ?")) {
     int trimHeight = Math.max(blockchain.getHeight() - trimKeep, 0);
     pstmt.setInt(1, trimHeight);
     pstmt.executeUpdate();
   } catch (SQLException e) {
     throw new RuntimeException(e.toString(), e);
   }
 }
Пример #4
0
 static boolean mustLogEntry(long accountId, boolean isUnconfirmed) {
   //
   // Must be tracking this account
   //
   if (!ledgerEnabled || (!trackAllAccounts && !trackAccounts.contains(accountId))) {
     return false;
   }
   // confirmed changes only occur while processing block, and unconfirmed changes are
   // only logged while processing block
   if (!blockchainProcessor.isProcessingBlock()) {
     return false;
   }
   //
   // Log unconfirmed changes only when processing a block and logUnconfirmed does not equal 0
   // Log confirmed changes unless logUnconfirmed equals 2
   //
   if (isUnconfirmed && logUnconfirmed == 0) {
     return false;
   }
   if (!isUnconfirmed && logUnconfirmed == 2) {
     return false;
   }
   if (trimKeep > 0 && blockchain.getHeight() <= Constants.LAST_KNOWN_BLOCK - trimKeep) {
     return false;
   }
   //
   // Don't log account changes if we are scanning the blockchain and the current height
   // is less than the minimum account_ledger trim height
   //
   if (blockchainProcessor.isScanning()
       && trimKeep > 0
       && blockchain.getHeight() <= blockchainProcessor.getInitialScanHeight() - trimKeep) {
     return false;
   }
   return true;
 }
Пример #5
0
 /**
  * Create a ledger entry
  *
  * @param event Event
  * @param eventId Event identifier
  * @param accountId Account identifier
  * @param holding Holding or null
  * @param holdingId Holding identifier or null
  * @param change Change in balance
  * @param balance New balance
  */
 public LedgerEntry(
     LedgerEvent event,
     long eventId,
     long accountId,
     LedgerHolding holding,
     Long holdingId,
     long change,
     long balance) {
   this.event = event;
   this.eventId = eventId;
   this.accountId = accountId;
   this.holding = holding;
   this.holdingId = holdingId;
   this.change = change;
   this.balance = balance;
   Block block = blockchain.getLastBlock();
   this.blockId = block.getId();
   this.height = block.getHeight();
   this.timestamp = block.getTimestamp();
 }
Пример #6
0
 /**
  * Return the ledger entries sorted in descending insert order
  *
  * @param accountId Account identifier or zero if no account identifier
  * @param event Ledger event or null
  * @param eventId Ledger event identifier or zero if no event identifier
  * @param holding Ledger holding or null
  * @param holdingId Ledger holding identifier or zero if no holding identifier
  * @param firstIndex First matching entry index, inclusive
  * @param lastIndex Last matching entry index, inclusive
  * @return List of ledger entries
  */
 public static List<LedgerEntry> getEntries(
     long accountId,
     LedgerEvent event,
     long eventId,
     LedgerHolding holding,
     long holdingId,
     int firstIndex,
     int lastIndex) {
   if (!ledgerEnabled) {
     return Collections.emptyList();
   }
   List<LedgerEntry> entryList = new ArrayList<>();
   //
   // Build the SELECT statement to search the entries
   StringBuilder sb = new StringBuilder(128);
   sb.append("SELECT * FROM account_ledger ");
   if (accountId != 0 || event != null || holding != null) {
     sb.append("WHERE ");
   }
   if (accountId != 0) {
     sb.append("account_id = ? ");
   }
   if (event != null) {
     if (accountId != 0) {
       sb.append("AND ");
     }
     sb.append("event_type = ? ");
     if (eventId != 0) sb.append("AND event_id = ? ");
   }
   if (holding != null) {
     if (accountId != 0 || event != null) {
       sb.append("AND ");
     }
     sb.append("holding_type = ? ");
     if (holdingId != 0) sb.append("AND holding_id = ? ");
   }
   sb.append("ORDER BY db_id DESC ");
   sb.append(DbUtils.limitsClause(firstIndex, lastIndex));
   //
   // Get the ledger entries
   //
   blockchain.readLock();
   try (Connection con = Db.db.getConnection();
       PreparedStatement pstmt = con.prepareStatement(sb.toString())) {
     int i = 0;
     if (accountId != 0) {
       pstmt.setLong(++i, accountId);
     }
     if (event != null) {
       pstmt.setByte(++i, (byte) event.getCode());
       if (eventId != 0) {
         pstmt.setLong(++i, eventId);
       }
     }
     if (holding != null) {
       pstmt.setByte(++i, (byte) holding.getCode());
       if (holdingId != 0) {
         pstmt.setLong(++i, holdingId);
       }
     }
     DbUtils.setLimits(++i, pstmt, firstIndex, lastIndex);
     try (ResultSet rs = pstmt.executeQuery()) {
       while (rs.next()) {
         entryList.add(new LedgerEntry(rs));
       }
     }
   } catch (SQLException e) {
     throw new RuntimeException(e.toString(), e);
   } finally {
     blockchain.readUnlock();
   }
   return entryList;
 }