private void loadExtensions( Wallet wallet, WalletExtension[] extensionsList, Protos.Wallet walletProto) throws UnreadableWalletException { final Map<String, WalletExtension> extensions = new HashMap<String, WalletExtension>(); for (WalletExtension e : extensionsList) extensions.put(e.getWalletExtensionID(), e); // The Wallet object, if subclassed, might have added some extensions to itself already. In that // case, don't // expect them to be passed in, just fetch them here and don't re-add. extensions.putAll(wallet.getExtensions()); for (Protos.Extension extProto : walletProto.getExtensionList()) { String id = extProto.getId(); WalletExtension extension = extensions.get(id); if (extension == null) { if (extProto.getMandatory()) { if (requireMandatoryExtensions) throw new UnreadableWalletException("Unknown mandatory extension in wallet: " + id); else log.error("Unknown extension in wallet {}, ignoring", id); } } else { log.info("Loading wallet extension {}", id); try { extension.deserializeWalletExtension(wallet, extProto.getData().toByteArray()); wallet.addOrGetExistingExtension(extension); } catch (Exception e) { if (extProto.getMandatory() && requireMandatoryExtensions) throw new UnreadableWalletException( "Could not parse mandatory extension in wallet: " + id); else log.error("Error whilst reading extension {}, ignoring", id, e); } } } }
private void readTransaction(Protos.Transaction txProto, NetworkParameters params) throws UnreadableWalletException { Transaction tx = new Transaction(params); if (txProto.hasUpdatedAt()) { tx.setUpdateTime(new Date(txProto.getUpdatedAt())); } for (Protos.TransactionOutput outputProto : txProto.getTransactionOutputList()) { Coin value = Coin.valueOf(outputProto.getValue()); byte[] scriptBytes = outputProto.getScriptBytes().toByteArray(); TransactionOutput output = new TransactionOutput(params, tx, value, scriptBytes); tx.addOutput(output); } for (Protos.TransactionInput inputProto : txProto.getTransactionInputList()) { byte[] scriptBytes = inputProto.getScriptBytes().toByteArray(); TransactionOutPoint outpoint = new TransactionOutPoint( params, inputProto.getTransactionOutPointIndex() & 0xFFFFFFFFL, byteStringToHash(inputProto.getTransactionOutPointHash())); Coin value = inputProto.hasValue() ? Coin.valueOf(inputProto.getValue()) : null; TransactionInput input = new TransactionInput(params, tx, scriptBytes, outpoint, value); if (inputProto.hasSequence()) { input.setSequenceNumber(inputProto.getSequence()); } tx.addInput(input); } for (int i = 0; i < txProto.getBlockHashCount(); i++) { ByteString blockHash = txProto.getBlockHash(i); int relativityOffset = 0; if (txProto.getBlockRelativityOffsetsCount() > 0) relativityOffset = txProto.getBlockRelativityOffsets(i); tx.addBlockAppearance(byteStringToHash(blockHash), relativityOffset); } if (txProto.hasLockTime()) { tx.setLockTime(0xffffffffL & txProto.getLockTime()); } if (txProto.hasPurpose()) { switch (txProto.getPurpose()) { case UNKNOWN: tx.setPurpose(Transaction.Purpose.UNKNOWN); break; case USER_PAYMENT: tx.setPurpose(Transaction.Purpose.USER_PAYMENT); break; case KEY_ROTATION: tx.setPurpose(Transaction.Purpose.KEY_ROTATION); break; case ASSURANCE_CONTRACT_CLAIM: tx.setPurpose(Transaction.Purpose.ASSURANCE_CONTRACT_CLAIM); break; case ASSURANCE_CONTRACT_PLEDGE: tx.setPurpose(Transaction.Purpose.ASSURANCE_CONTRACT_PLEDGE); break; case ASSURANCE_CONTRACT_STUB: tx.setPurpose(Transaction.Purpose.ASSURANCE_CONTRACT_STUB); break; default: throw new RuntimeException("New purpose serialization not implemented"); } } else { // Old wallet: assume a user payment as that's the only reason a new tx would have been // created back then. tx.setPurpose(Transaction.Purpose.USER_PAYMENT); } if (txProto.hasExchangeRate()) { Protos.ExchangeRate exchangeRateProto = txProto.getExchangeRate(); tx.setExchangeRate( new ExchangeRate( Coin.valueOf(exchangeRateProto.getCoinValue()), Fiat.valueOf( exchangeRateProto.getFiatCurrencyCode(), exchangeRateProto.getFiatValue()))); } if (txProto.hasMemo()) tx.setMemo(txProto.getMemo()); // Peercoin: Include time tx.setTime(txProto.getTime()); // Transaction should now be complete. Sha256Hash protoHash = byteStringToHash(txProto.getHash()); if (!tx.getHash().equals(protoHash)) throw new UnreadableWalletException( String.format( "Transaction did not deserialize completely: %s vs %s", tx.getHash(), protoHash)); if (txMap.containsKey(txProto.getHash())) throw new UnreadableWalletException( "Wallet contained duplicate transaction " + byteStringToHash(txProto.getHash())); txMap.put(txProto.getHash(), tx); }