public synchronized boolean addUserClient(String username, ClientThread clientThread) { checkNotNull(username); checkNotNull(clientThread); if (takenUsernames.containsKey(username)) return false; takenUsernames.put(username, clientThread); return true; }
@Override public FieldDefinition getField(final String fieldName) { if (fields.containsKey(fieldName)) { return fields.get(fieldName); } else if (priorityField != null && priorityField.getName().equals(fieldName)) { return priorityField; } else { return null; } }
public boolean renameChatroom(Chatroom chatroom, String newName) { checkNotNull(chatroom); checkNotNull(newName); if (isChatroomExisting(newName)) return false; if (newName.equals(defaultChatName)) return false; String oldName = chatroom.getName(); chatrooms.remove(oldName); chatrooms.put(newName, chatroom); return true; }
public synchronized boolean addChatroom(Chatroom chatroom) { checkNotNull(chatroom); if (isChatroomExisting(chatroom.getName())) return false; if (chatroom.getName().equals(defaultChatName)) return false; chatrooms.put(chatroom.getName(), chatroom); return true; }
public synchronized boolean removeUserClient(ClientThread client) { checkNotNull(client); if (!containsUser(client.getData().getUsername())) return false; takenUsernames.remove(client.getData().getUsername()); client.getData().setUsername(null); return true; }
@Override public List<Protos.Key> serializeToProtobuf() { lock.lock(); try { // Most of the serialization work is delegated to the basic key chain, which will serialize // the bulk of the // data (handling encryption along the way), and letting us patch it up with the extra data we // care about. LinkedList<Protos.Key> entries = newLinkedList(); if (seed != null) { Protos.Key.Builder mnemonicEntry = BasicKeyChain.serializeEncryptableItem(seed); mnemonicEntry.setType(Protos.Key.Type.DETERMINISTIC_MNEMONIC); entries.add(mnemonicEntry.build()); } Map<ECKey, Protos.Key.Builder> keys = basicKeyChain.serializeToEditableProtobufs(); for (Map.Entry<ECKey, Protos.Key.Builder> entry : keys.entrySet()) { DeterministicKey key = (DeterministicKey) entry.getKey(); Protos.Key.Builder proto = entry.getValue(); proto.setType(Protos.Key.Type.DETERMINISTIC_KEY); final Protos.DeterministicKey.Builder detKey = proto.getDeterministicKeyBuilder(); detKey.setChainCode(ByteString.copyFrom(key.getChainCode())); for (ChildNumber num : key.getPath()) detKey.addPath(num.i()); if (key.equals(externalKey)) { detKey.setIssuedSubkeys(issuedExternalKeys); detKey.setLookaheadSize(lookaheadSize); } else if (key.equals(internalKey)) { detKey.setIssuedSubkeys(issuedInternalKeys); detKey.setLookaheadSize(lookaheadSize); } // Flag the very first key of following keychain. if (entries.isEmpty() && isFollowing()) { detKey.setIsFollowing(true); } if (key.getParent() != null) { // HD keys inherit the timestamp of their parent if they have one, so no need to serialize // it. proto.clearCreationTimestamp(); } entries.add(proto.build()); } return entries; } finally { lock.unlock(); } }
private static void informListenerForNewTransactions( Block block, NewBlockType newBlockType, @Nullable List<Sha256Hash> filteredTxHashList, @Nullable Map<Sha256Hash, Transaction> filteredTxn, StoredBlock newStoredBlock, boolean first, BlockChainListener listener, Set<Sha256Hash> falsePositives) throws VerificationException { if (block.transactions != null) { // If this is not the first wallet, ask for the transactions to be duplicated before being // given // to the wallet when relevant. This ensures that if we have two connected wallets and a tx // that // is relevant to both of them, they don't end up accidentally sharing the same object (which // can // result in temporary in-memory corruption during re-orgs). See bug 257. We only duplicate in // the case of multiple wallets to avoid an unnecessary efficiency hit in the common case. sendTransactionsToListener( newStoredBlock, newBlockType, listener, 0, block.transactions, !first, falsePositives); } else if (filteredTxHashList != null) { checkNotNull(filteredTxn); // We must send transactions to listeners in the order they appeared in the block - thus we // iterate over the // set of hashes and call sendTransactionsToListener with individual txn when they have not // already been // seen in loose broadcasts - otherwise notifyTransactionIsInBlock on the hash. int relativityOffset = 0; for (Sha256Hash hash : filteredTxHashList) { Transaction tx = filteredTxn.get(hash); if (tx != null) { sendTransactionsToListener( newStoredBlock, newBlockType, listener, relativityOffset, Collections.singletonList(tx), !first, falsePositives); } else { if (listener.notifyTransactionIsInBlock( hash, newStoredBlock, newBlockType, relativityOffset)) { falsePositives.remove(hash); } } relativityOffset++; } } }
@Override public EntityHookDefinition getHook( final String type, final String className, final String methodName) { EntityHookDefinition hook = hooksByMethodPath.get( type.toUpperCase(Locale.ENGLISH) + "." + className + "." + methodName); checkNotNull( hook, "Cannot find hook " + type.toUpperCase(Locale.ENGLISH) + "." + className + "." + methodName + " for dataDefinition " + this); return hook; }
public synchronized ClientThread getChatClientByUsername(String username) throws UsernameNotFoundException { checkNotNull(username); if (!containsUser(username)) throw new UsernameNotFoundException(username); return takenUsernames.get(username); }
// expensiveChecks enables checks that require looking at blocks further back in the chain // than the previous one when connecting (eg median timestamp check) // It could be exposed, but for now we just set it to shouldVerifyTransactions() private void connectBlock( final Block block, StoredBlock storedPrev, boolean expensiveChecks, @Nullable final List<Sha256Hash> filteredTxHashList, @Nullable final Map<Sha256Hash, Transaction> filteredTxn) throws BlockStoreException, VerificationException, PrunedException { checkState(lock.isHeldByCurrentThread()); boolean filtered = filteredTxHashList != null && filteredTxn != null; // Check that we aren't connecting a block that fails a checkpoint check if (!params.passesCheckpoint(storedPrev.getHeight() + 1, block.getHash())) throw new VerificationException( "Block failed checkpoint lockin at " + (storedPrev.getHeight() + 1)); if (shouldVerifyTransactions()) { checkNotNull(block.transactions); for (Transaction tx : block.transactions) if (!tx.isFinal(storedPrev.getHeight() + 1, block.getTimeSeconds())) throw new VerificationException("Block contains non-final transaction"); } StoredBlock head = getChainHead(); if (storedPrev.equals(head)) { if (filtered && filteredTxn.size() > 0) { log.debug( "Block {} connects to top of best chain with {} transaction(s) of which we were sent {}", block.getHashAsString(), filteredTxHashList.size(), filteredTxn.size()); for (Sha256Hash hash : filteredTxHashList) log.debug(" matched tx {}", hash); } if (expensiveChecks && block.getTimeSeconds() <= getMedianTimestampOfRecentBlocks(head, blockStore)) throw new VerificationException("Block's timestamp is too early"); // This block connects to the best known block, it is a normal continuation of the system. TransactionOutputChanges txOutChanges = null; if (shouldVerifyTransactions()) txOutChanges = connectTransactions(storedPrev.getHeight() + 1, block); StoredBlock newStoredBlock = addToBlockStore( storedPrev, block.transactions == null ? block : block.cloneAsHeader(), txOutChanges); setChainHead(newStoredBlock); log.debug("Chain is now {} blocks high, running listeners", newStoredBlock.getHeight()); informListenersForNewBlock( block, NewBlockType.BEST_CHAIN, filteredTxHashList, filteredTxn, newStoredBlock); } else { // This block connects to somewhere other than the top of the best known chain. We treat these // differently. // // Note that we send the transactions to the wallet FIRST, even if we're about to re-organize // this block // to become the new best chain head. This simplifies handling of the re-org in the Wallet // class. StoredBlock newBlock = storedPrev.build(block); boolean haveNewBestChain = newBlock.moreWorkThan(head); if (haveNewBestChain) { log.info("Block is causing a re-organize"); } else { StoredBlock splitPoint = findSplit(newBlock, head, blockStore); if (splitPoint != null && splitPoint.equals(newBlock)) { // newStoredBlock is a part of the same chain, there's no fork. This happens when we // receive a block // that we already saw and linked into the chain previously, which isn't the chain head. // Re-processing it is confusing for the wallet so just skip. log.warn( "Saw duplicated block in main chain at height {}: {}", newBlock.getHeight(), newBlock.getHeader().getHash()); return; } if (splitPoint == null) { // This should absolutely never happen // (lets not write the full block to disk to keep any bugs which allow this to happen // from writing unreasonable amounts of data to disk) throw new VerificationException("Block forks the chain but splitPoint is null"); } else { // We aren't actually spending any transactions (yet) because we are on a fork addToBlockStore(storedPrev, block); int splitPointHeight = splitPoint.getHeight(); String splitPointHash = splitPoint.getHeader().getHashAsString(); log.info( "Block forks the chain at height {}/block {}, but it did not cause a reorganize:\n{}", splitPointHeight, splitPointHash, newBlock.getHeader().getHashAsString()); } } // We may not have any transactions if we received only a header, which can happen during fast // catchup. // If we do, send them to the wallet but state that they are on a side chain so it knows not // to try and // spend them until they become activated. if (block.transactions != null || filtered) { informListenersForNewBlock( block, NewBlockType.SIDE_CHAIN, filteredTxHashList, filteredTxn, newBlock); } if (haveNewBestChain) handleNewBestChain(storedPrev, newBlock, block, expensiveChecks); } }
public synchronized boolean removeChatroom(Chatroom chatroom) { checkNotNull(chatroom); if (!isChatroomExisting(chatroom.getName())) return false; chatrooms.remove(chatroom.getName()); return true; }
public synchronized Chatroom getChatroomByName(String chatroom) throws ChatroomNotFoundExeption { checkNotNull(chatroom); if (chatroom.equals(defaultChatName)) return defaultChat; if (!chatrooms.containsKey(chatroom)) throw new ChatroomNotFoundExeption(chatroom); return chatrooms.get(chatroom); }
public synchronized boolean isChatroomExisting(String chatroomName) { checkNotNull(chatroomName); return chatrooms.containsKey(chatroomName); }
public synchronized Collection<Chatroom> getChatrooms() { return Collections.unmodifiableCollection(chatrooms.values()); }
/** Chatroom operation * */ public synchronized Set<String> getChatRoomNames() { return Collections.unmodifiableSet(chatrooms.keySet()); }
public void withField(final FieldDefinition field) { fields.put(field.getName(), field); }
public void addHook(final HooksTag tag, final EntityHookDefinition hook) { hook.initialize(this); hooksByMethodPath.put(tag.toString() + "." + hook.getName(), hook); entityHooks.put(tag, hook); }
public synchronized boolean containsUser(String user) { return takenUsernames.containsKey(user); }