private void parsePaymentRequest(Protos.PaymentRequest request) throws PaymentRequestException { try { if (request == null) throw new PaymentRequestException("request cannot be null"); if (!request.hasPaymentDetailsVersion()) throw new PaymentRequestException.InvalidVersion("No version"); if (request.getPaymentDetailsVersion() != 1) throw new PaymentRequestException.InvalidVersion( "Version 1 required. Received version " + request.getPaymentDetailsVersion()); paymentRequest = request; if (!request.hasSerializedPaymentDetails()) throw new PaymentRequestException("No PaymentDetails"); paymentDetails = Protos.PaymentDetails.newBuilder() .mergeFrom(request.getSerializedPaymentDetails()) .build(); if (paymentDetails == null) throw new PaymentRequestException("Invalid PaymentDetails"); if (!paymentDetails.hasNetwork()) params = MainNetParams.get(); else params = NetworkParameters.fromPmtProtocolID(paymentDetails.getNetwork()); if (params == null) throw new PaymentRequestException.InvalidNetwork( "Invalid network " + paymentDetails.getNetwork()); if (paymentDetails.getOutputsCount() < 1) throw new PaymentRequestException.InvalidOutputs("No outputs"); for (Protos.Output output : paymentDetails.getOutputsList()) { if (output.hasAmount()) totalValue = totalValue.add(BigInteger.valueOf(output.getAmount())); } // This won't ever happen in practice. It would only happen if the user provided outputs // that are obviously invalid. Still, we don't want to silently overflow. if (totalValue.compareTo(BigInteger.valueOf(Long.MAX_VALUE)) > 0) throw new PaymentRequestException.InvalidOutputs("The outputs are way too big."); } catch (InvalidProtocolBufferException e) { throw new PaymentRequestException(e); } }
/** * Parses the given private key as created by the "dumpprivkey" Bitcoin C++ RPC. * * @param params The expected network parameters of the key. If you don't care, provide null. * @param encoded The base58 encoded string. * @throws AddressFormatException If the string is invalid or the header byte doesn't match the * network params. */ public DumpedPrivateKey(NetworkParameters params, String encoded) throws AddressFormatException { super(encoded); if (params != null && version != params.getDumpedPrivateKeyHeader()) throw new AddressFormatException( "Mismatched version number, trying to cross networks? " + version + " vs " + params.getDumpedPrivateKeyHeader()); if (bytes.length == 33 && bytes[32] == 1) { compressed = true; bytes = Arrays.copyOf(bytes, 32); // Chop off the additional marker byte. } else if (bytes.length == 32) { compressed = false; } else { throw new AddressFormatException("Wrong number of bytes for a private key, not 32 or 33"); } }
/** * Parses a wallet from the given stream, using the provided Wallet instance to load data into. * This is primarily used when you want to register extensions. Data in the proto will be added * into the wallet where applicable and overwrite where not. */ public Wallet readWallet(InputStream input) throws IOException { Protos.Wallet walletProto = parseToProto(input); // System.out.println(TextFormat.printToString(walletProto)); NetworkParameters params = NetworkParameters.fromID(walletProto.getNetworkIdentifier()); Wallet wallet = new Wallet(params); readWallet(walletProto, wallet); return wallet; }
private void createNewStore(NetworkParameters params) throws BlockStoreException { try { // Set up the genesis block. When we start out fresh, it is by // definition the top of the chain. StoredBlock storedGenesisHeader = new StoredBlock( params.getGenesisBlock().cloneAsHeader(), params.getGenesisBlock().getWork(), 0); // The coinbase in the genesis block is not spendable. This is because of how the reference // client inits // its database - the genesis transaction isn't actually in the db so its spent flags can // never be updated. List<Transaction> genesisTransactions = Lists.newLinkedList(); StoredUndoableBlock storedGenesis = new StoredUndoableBlock(params.getGenesisBlock().getHash(), genesisTransactions); put(storedGenesisHeader, storedGenesis); setChainHead(storedGenesisHeader); setVerifiedChainHead(storedGenesisHeader); } catch (VerificationException e) { throw new RuntimeException(e); // Cannot happen. } }
/** * Cheap test to see if input stream is a wallet. This checks for a magic value at the beginning * of the stream. * * @param is input stream to test * @return true if input stream is a wallet */ public static boolean isWallet(InputStream is) { try { final CodedInputStream cis = CodedInputStream.newInstance(is); final int tag = cis.readTag(); final int field = WireFormat.getTagFieldNumber(tag); if (field != 1) // network_identifier return false; final String network = cis.readString(); return NetworkParameters.fromID(network) != null; } catch (IOException x) { return false; } }
public class MemoryPoolTest { private NetworkParameters params = NetworkParameters.unitTests(); private Transaction tx1, tx2; private PeerAddress address1, address2, address3; @Before public void setup() throws Exception { BriefLogFormatter.init(); tx1 = TestUtils.createFakeTx(params, Utils.toNanoCoins(1, 0), new ECKey().toAddress(params)); tx2 = new Transaction(params, tx1.bitcoinSerialize()); address1 = new PeerAddress(InetAddress.getByAddress(new byte[] {127, 0, 0, 1})); address2 = new PeerAddress(InetAddress.getByAddress(new byte[] {127, 0, 0, 2})); address3 = new PeerAddress(InetAddress.getByAddress(new byte[] {127, 0, 0, 3})); } @Test public void canonicalInstance() throws Exception { MemoryPool pool = new MemoryPool(); // Check that if we repeatedly send it the same transaction but with different objects, we get // back the same // canonical instance with the confidences update. assertEquals(0, pool.numBroadcastPeers(tx1.getHash())); assertEquals(tx1, pool.seen(tx1, address1)); assertEquals(1, tx1.getConfidence().numBroadcastPeers()); assertEquals(1, pool.numBroadcastPeers(tx1.getHash())); assertEquals(tx1, pool.seen(tx2, address2)); assertEquals(2, tx1.getConfidence().numBroadcastPeers()); assertEquals(2, pool.numBroadcastPeers(tx1.getHash())); assertEquals(tx1, pool.get(tx1.getHash())); } @Test public void invAndDownload() throws Exception { MemoryPool pool = new MemoryPool(); // Base case: we see a transaction announced twice and then download it. The count is in the // confidence object. assertEquals(0, pool.numBroadcastPeers(tx1.getHash())); pool.seen(tx1.getHash(), address1); assertEquals(1, pool.numBroadcastPeers(tx1.getHash())); assertTrue(pool.maybeWasSeen(tx1.getHash())); pool.seen(tx1.getHash(), address2); assertEquals(2, pool.numBroadcastPeers(tx1.getHash())); Transaction t = pool.seen(tx1, address1); assertEquals(2, t.getConfidence().numBroadcastPeers()); // And now we see another inv. pool.seen(tx1.getHash(), address3); assertEquals(3, t.getConfidence().numBroadcastPeers()); assertEquals(3, pool.numBroadcastPeers(tx1.getHash())); } }
/** * Parses a wallet from the given stream, using the provided Wallet instance to load data into. * This is primarily used when you want to register extensions. Data in the proto will be added * into the wallet where applicable and overwrite where not. * * <p>A wallet can be unreadable for various reasons, such as inability to open the file, corrupt * data, internally inconsistent data, a wallet extension marked as mandatory that cannot be * handled and so on. You should always handle {@link UnreadableWalletException} and communicate * failure to the user in an appropriate manner. * * @throws UnreadableWalletException thrown in various error conditions (see description). */ public Wallet readWallet(InputStream input) throws UnreadableWalletException { try { Protos.Wallet walletProto = parseToProto(input); final String paramsID = walletProto.getNetworkIdentifier(); NetworkParameters params = NetworkParameters.fromID(paramsID); if (params == null) throw new UnreadableWalletException("Unknown network parameters ID " + paramsID); return readWallet(params, null, walletProto); } catch (IOException e) { throw new UnreadableWalletException("Could not parse input stream to protobuf", e); } catch (IllegalStateException e) { throw new UnreadableWalletException("Could not parse input stream to protobuf", e); } }
private void initNewStore(NetworkParameters params) throws Exception { byte[] header; header = HEADER_MAGIC.getBytes("US-ASCII"); buffer.put(header); // Insert the genesis block. lock.lock(); try { setRingCursor(buffer, FILE_PROLOGUE_BYTES); } finally { lock.unlock(); } Block genesis = params.getGenesisBlock().cloneAsHeader(); StoredBlock storedGenesis = new StoredBlock(genesis, genesis.getWork(), 0); put(storedGenesis); setChainHead(storedGenesis); }
// Sets up all objects needed for network communication but does not bring up the peers. private static void setup() throws BlockStoreException { if (store != null) return; // Already done. // Will create a fresh chain if one doesn't exist or there is an issue with this one. if (!chainFileName.exists() && wallet.getTransactions(true).size() > 0) { // No chain, so reset the wallet as we will be downloading from scratch. System.out.println("Chain file is missing so clearing transactions from the wallet."); reset(); } if (mode == ValidationMode.SPV) { store = new SPVBlockStore(params, chainFileName); chain = new BlockChain(params, wallet, store); } else if (mode == ValidationMode.FULL) { FullPrunedBlockStore s = new H2FullPrunedBlockStore(params, chainFileName.getAbsolutePath(), 5000); store = s; chain = new FullPrunedBlockChain(params, wallet, s); } // This will ensure the wallet is saved when it changes. wallet.autosaveToFile(walletFile, 200, TimeUnit.MILLISECONDS, null); peers = new PeerGroup(params, chain); peers.setUserAgent("WalletTool", "1.0"); peers.addWallet(wallet); if (options.has("peers")) { String peersFlag = (String) options.valueOf("peers"); String[] peerAddrs = peersFlag.split(","); for (String peer : peerAddrs) { try { peers.addAddress(new PeerAddress(InetAddress.getByName(peer), params.getPort())); } catch (UnknownHostException e) { System.err.println( "Could not understand peer domain name/IP address: " + peer + ": " + e.getMessage()); System.exit(1); } } } else { peers.addPeerDiscovery(new DnsDiscovery(params)); } }
@Test public void testStorage() throws Exception { File temp = File.createTempFile("bitcoinj-test", null, null); System.out.println(temp.getAbsolutePath()); temp.deleteOnExit(); NetworkParameters params = NetworkParameters.unitTests(); Address to = new ECKey().toAddress(params); BoundedOverheadBlockStore store = new BoundedOverheadBlockStore(params, temp); // Check the first block in a new store is the genesis block. StoredBlock genesis = store.getChainHead(); assertEquals(params.genesisBlock, genesis.getHeader()); // Build a new block. StoredBlock b1 = genesis.build(genesis.getHeader().createNextBlock(to).cloneAsHeader()); store.put(b1); store.setChainHead(b1); // Check we can get it back out again if we rebuild the store object. store = new BoundedOverheadBlockStore(params, temp); StoredBlock b2 = store.get(b1.getHeader().getHash()); assertEquals(b1, b2); // Check the chain head was stored correctly also. assertEquals(b1, store.getChainHead()); }
// Used by ECKey.getPrivateKeyEncoded() DumpedPrivateKey(NetworkParameters params, byte[] keyBytes, boolean compressed) { super(params.getDumpedPrivateKeyHeader(), encode(keyBytes, compressed)); this.compressed = compressed; }
/** * Loads wallet data from the given protocol buffer and inserts it into the given Wallet object. * This is primarily useful when you wish to pre-register extension objects. Note that if loading * fails the provided Wallet object may be in an indeterminate state and should be thrown away. * * <p>A wallet can be unreadable for various reasons, such as inability to open the file, corrupt * data, internally inconsistent data, a wallet extension marked as mandatory that cannot be * handled and so on. You should always handle {@link UnreadableWalletException} and communicate * failure to the user in an appropriate manner. * * @throws UnreadableWalletException thrown in various error conditions (see description). */ public Wallet readWallet( NetworkParameters params, @Nullable WalletExtension[] extensions, Protos.Wallet walletProto) throws UnreadableWalletException { if (walletProto.getVersion() > 1) throw new UnreadableWalletException.FutureVersion(); if (!walletProto.getNetworkIdentifier().equals(params.getId())) throw new UnreadableWalletException.WrongNetwork(); int sigsRequiredToSpend = walletProto.getSigsRequiredToSpend(); // Read the scrypt parameters that specify how encryption and decryption is performed. KeyChainGroup chain; if (walletProto.hasEncryptionParameters()) { Protos.ScryptParameters encryptionParameters = walletProto.getEncryptionParameters(); final KeyCrypterScrypt keyCrypter = new KeyCrypterScrypt(encryptionParameters); chain = KeyChainGroup.fromProtobufEncrypted( params, walletProto.getKeyList(), sigsRequiredToSpend, keyCrypter); } else { chain = KeyChainGroup.fromProtobufUnencrypted( params, walletProto.getKeyList(), sigsRequiredToSpend); } Wallet wallet = factory.create(params, chain); List<Script> scripts = Lists.newArrayList(); for (Protos.Script protoScript : walletProto.getWatchedScriptList()) { try { Script script = new Script( protoScript.getProgram().toByteArray(), protoScript.getCreationTimestamp() / 1000); scripts.add(script); } catch (ScriptException e) { throw new UnreadableWalletException("Unparseable script in wallet"); } } wallet.addWatchedScripts(scripts); if (walletProto.hasDescription()) { wallet.setDescription(walletProto.getDescription()); } // Read all transactions and insert into the txMap. for (Protos.Transaction txProto : walletProto.getTransactionList()) { readTransaction(txProto, wallet.getParams()); } // Update transaction outputs to point to inputs that spend them for (Protos.Transaction txProto : walletProto.getTransactionList()) { WalletTransaction wtx = connectTransactionOutputs(txProto); wallet.addWalletTransaction(wtx); } // Update the lastBlockSeenHash. if (!walletProto.hasLastSeenBlockHash()) { wallet.setLastBlockSeenHash(null); } else { wallet.setLastBlockSeenHash(byteStringToHash(walletProto.getLastSeenBlockHash())); } if (!walletProto.hasLastSeenBlockHeight()) { wallet.setLastBlockSeenHeight(-1); } else { wallet.setLastBlockSeenHeight(walletProto.getLastSeenBlockHeight()); } // Will default to zero if not present. wallet.setLastBlockSeenTimeSecs(walletProto.getLastSeenBlockTimeSecs()); if (walletProto.hasKeyRotationTime()) { wallet.setKeyRotationTime(new Date(walletProto.getKeyRotationTime() * 1000)); } loadExtensions(wallet, extensions != null ? extensions : new WalletExtension[0], walletProto); for (Protos.Tag tag : walletProto.getTagsList()) { wallet.setTag(tag.getTag(), tag.getData()); } for (Protos.TransactionSigner signerProto : walletProto.getTransactionSignersList()) { try { Class signerClass = Class.forName(signerProto.getClassName()); TransactionSigner signer = (TransactionSigner) signerClass.newInstance(); signer.deserialize(signerProto.getData().toByteArray()); wallet.addTransactionSigner(signer); } catch (Exception e) { throw new UnreadableWalletException( "Unable to deserialize TransactionSigner instance: " + signerProto.getClassName(), e); } } if (walletProto.hasVersion()) { wallet.setVersion(walletProto.getVersion()); } // Make sure the object can be re-used to read another wallet without corruption. txMap.clear(); return wallet; }
public static void main(String[] args) throws Exception { OptionParser parser = new OptionParser(); parser.accepts("help"); parser.accepts("force"); parser.accepts("debuglog"); OptionSpec<String> walletFileName = parser.accepts("wallet").withRequiredArg().defaultsTo("wallet"); OptionSpec<NetworkEnum> netFlag = parser .accepts("net") .withOptionalArg() .ofType(NetworkEnum.class) .defaultsTo(NetworkEnum.PROD); dateFlag = parser .accepts("date") .withRequiredArg() .ofType(Date.class) .withValuesConvertedBy(DateConverter.datePattern("yyyy/MM/dd")); OptionSpec<WaitForEnum> waitForFlag = parser.accepts("waitfor").withRequiredArg().ofType(WaitForEnum.class); OptionSpec<ValidationMode> modeFlag = parser .accepts("mode") .withRequiredArg() .ofType(ValidationMode.class) .defaultsTo(ValidationMode.SPV); OptionSpec<String> chainFlag = parser.accepts("chain").withRequiredArg(); // For addkey/delkey. parser.accepts("pubkey").withRequiredArg(); parser.accepts("privkey").withRequiredArg(); parser.accepts("addr").withRequiredArg(); parser.accepts("peers").withRequiredArg(); OptionSpec<String> outputFlag = parser.accepts("output").withRequiredArg(); parser.accepts("value").withRequiredArg(); parser.accepts("fee").withRequiredArg(); unixtimeFlag = parser.accepts("unixtime").withRequiredArg().ofType(Integer.class); OptionSpec<String> conditionFlag = parser.accepts("condition").withRequiredArg(); parser.accepts("locktime").withRequiredArg(); parser.accepts("allow-unconfirmed"); parser.accepts("offline"); parser.accepts("ignore-mandatory-extensions"); OptionSpec<String> passwordFlag = parser.accepts("password").withRequiredArg(); OptionSpec<String> paymentRequestLocation = parser.accepts("payment-request").withRequiredArg(); parser.accepts("no-pki"); options = parser.parse(args); final String HELP_TEXT = Resources.toString(WalletTool.class.getResource("wallet-tool-help.txt"), Charsets.UTF_8); if (args.length == 0 || options.has("help") || options.nonOptionArguments().size() < 1) { System.out.println(HELP_TEXT); return; } ActionEnum action; try { String actionStr = options.nonOptionArguments().get(0); actionStr = actionStr.toUpperCase().replace("-", "_"); action = ActionEnum.valueOf(actionStr); } catch (IllegalArgumentException e) { System.err.println("Could not understand action name " + options.nonOptionArguments().get(0)); return; } if (options.has("debuglog")) { BriefLogFormatter.init(); log.info("Starting up ..."); } else { // Disable logspam unless there is a flag. java.util.logging.Logger logger = LogManager.getLogManager().getLogger(""); logger.setLevel(Level.SEVERE); } switch (netFlag.value(options)) { case PROD: params = MainNetParams.get(); chainFileName = new File("prodnet.chain"); break; case TEST: params = TestNet3Params.get(); chainFileName = new File("testnet.chain"); break; case REGTEST: params = RegTestParams.get(); chainFileName = new File("regtest.chain"); break; default: throw new RuntimeException("Unreachable."); } mode = modeFlag.value(options); // Allow the user to override the name of the chain used. if (options.has(chainFlag)) { chainFileName = new File(chainFlag.value(options)); } if (options.has("condition")) { condition = new Condition(conditionFlag.value(options)); } if (options.has(passwordFlag)) { password = passwordFlag.value(options); } walletFile = new File(walletFileName.value(options)); if (action == ActionEnum.CREATE) { createWallet(options, params, walletFile); return; // We're done. } if (!walletFile.exists()) { System.err.println( "Specified wallet file " + walletFile + " does not exist. Try wallet-tool --wallet=" + walletFile + " create"); return; } if (action == ActionEnum.RAW_DUMP) { // Just parse the protobuf and print, then bail out. Don't try and do a real deserialization. // This is // useful mostly for investigating corrupted wallets. FileInputStream stream = new FileInputStream(walletFile); try { Protos.Wallet proto = WalletProtobufSerializer.parseToProto(stream); System.out.println(proto.toString()); return; } finally { stream.close(); } } try { WalletProtobufSerializer loader = new WalletProtobufSerializer(); if (options.has("ignore-mandatory-extensions")) loader.setRequireMandatoryExtensions(false); wallet = loader.readWallet(new BufferedInputStream(new FileInputStream(walletFile))); if (!wallet.getParams().equals(params)) { System.err.println( "Wallet does not match requested network parameters: " + wallet.getParams().getId() + " vs " + params.getId()); return; } } catch (Exception e) { System.err.println("Failed to load wallet '" + walletFile + "': " + e.getMessage()); e.printStackTrace(); return; } // What should we do? switch (action) { case DUMP: dumpWallet(); break; case ADD_KEY: addKey(); break; case ADD_ADDR: addAddr(); break; case DELETE_KEY: deleteKey(); break; case RESET: reset(); break; case SYNC: syncChain(); break; case SEND: if (options.has(paymentRequestLocation) && options.has(outputFlag)) { System.err.println("--payment-request and --output cannot be used together."); return; } else if (options.has(outputFlag)) { BigInteger fee = BigInteger.ZERO; if (options.has("fee")) { fee = Utils.toNanoCoins((String) options.valueOf("fee")); } String lockTime = null; if (options.has("locktime")) { lockTime = (String) options.valueOf("locktime"); } boolean allowUnconfirmed = options.has("allow-unconfirmed"); send(outputFlag.values(options), fee, lockTime, allowUnconfirmed); } else if (options.has(paymentRequestLocation)) { sendPaymentRequest(paymentRequestLocation.value(options), !options.has("no-pki")); } else { System.err.println( "You must specify a --payment-request or at least one --output=addr:value."); return; } break; } if (!wallet.isConsistent()) { System.err.println("************** WALLET IS INCONSISTENT *****************"); return; } saveWallet(walletFile); if (options.has(waitForFlag)) { WaitForEnum value; try { value = waitForFlag.value(options); } catch (Exception e) { System.err.println( "Could not understand the --waitfor flag: Valid options are WALLET_TX, BLOCK, " + "BALANCE and EVER"); return; } wait(value); if (!wallet.isConsistent()) { System.err.println("************** WALLET IS INCONSISTENT *****************"); return; } saveWallet(walletFile); } shutdown(); }
public static void runSimulation() { /** Input network from a SNDLib file */ NetworkParameters parameters = new NetworkParameters(networkFile); /** Initialize the event handler specifying the simulation time */ EventHandler.initEventHandler(simulationTime); for (int i = 0; i < numberOfPortTypes; i++) parameters.setPorts( Integer.parseInt(numberOfPortsPerPortType[i]), i, Double.parseDouble(bandwidths[i])); parameters.setDecisionProbForKnownOrUnknown(probabilityOfUnknownCon); parameters.setGenerators(); switch (algorithm) { case "MAC": parameters.setAlgorithm(new MAC_Method()); break; case "MAL": parameters.setAlgorithm(new MAL_Method()); break; case "FF": parameters.setAlgorithm(new NoAlgorithm()); break; default: System.out.println("Wrong Algorithm"); System.exit(0); } parameters.setWithGuardBands(withGuardBands); try { parameters.readPathsFromFile(pathsFile); } catch (IOException e) { e.printStackTrace(); } /** specify the number of carriers per link and carrier bandwidth */ parameters.setNumberOfCarriersPerLink(numberOfCarriersPerLink); parameters.setMaxCarrierBW(carrierBandWidth); parameters.setCarriers(); /** Get up generators */ parameters.getUpGenerators(); /** Run the simulation */ EventHandler.runEventHandler(); }
public static PeerAddress localhost(NetworkParameters params) { return new PeerAddress(InetAddresses.forString("127.0.0.1"), params.getPort()); }