org.bitcoinj.core.StoredBlock Java Examples
The following examples show how to use
org.bitcoinj.core.StoredBlock.
You can vote up the ones you like or vote down the ones you don't like,
and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: SPVBlockStoreTest.java From bcm-android with GNU General Public License v3.0 | 6 votes |
@Test public void twoStores_sequentially_grow() throws Exception { Address to = LegacyAddress.fromKey(UNITTEST, new ECKey()); SPVBlockStore store = new SPVBlockStore(UNITTEST, blockStoreFile, 10, true); final StoredBlock block0 = store.getChainHead(); final StoredBlock block1 = block0.build(block0.getHeader().createNextBlock(to).cloneAsHeader()); store.put(block1); final StoredBlock block2 = block1.build(block1.getHeader().createNextBlock(to).cloneAsHeader()); store.put(block2); store.setChainHead(block2); store.close(); store = new SPVBlockStore(UNITTEST, blockStoreFile, 20, true); final StoredBlock read2 = store.getChainHead(); assertEquals(block2, read2); final StoredBlock read1 = read2.getPrev(store); assertEquals(block1, read1); final StoredBlock read0 = read1.getPrev(store); assertEquals(block0, read0); store.close(); assertEquals(SPVBlockStore.getFileSize(20), blockStoreFile.length()); }
Example #2
Source File: VersionTally.java From green_android with GNU General Public License v3.0 | 6 votes |
/** * Initialize the version tally from the block store. Note this does not * search backwards past the start of the block store, so if starting from * a checkpoint this may not fill the window. * * @param blockStore block store to load blocks from. * @param chainHead current chain tip. */ public void initialize(final BlockStore blockStore, final StoredBlock chainHead) throws BlockStoreException { StoredBlock versionBlock = chainHead; final Stack<Long> versions = new Stack<>(); // We don't know how many blocks back we can go, so load what we can first versions.push(versionBlock.getHeader().getVersion()); for (int headOffset = 0; headOffset < versionWindow.length; headOffset++) { versionBlock = versionBlock.getPrev(blockStore); if (null == versionBlock) { break; } versions.push(versionBlock.getHeader().getVersion()); } // Replay the versions into the tally while (!versions.isEmpty()) { add(versions.pop()); } }
Example #3
Source File: WalletAppKitService.java From consensusj with Apache License 2.0 | 6 votes |
/** * Get a BlockInfo for the specified hash * * @param blockChain The blockchain object to pull the data from * @param blockHash The hash of the desired block * @param includeTx whether to include transactions (currently must be false) * @return block information (currently incomplete and untested) * @throws BlockStoreException Something went wrong */ private static BlockInfo getBlockInfoByHash(AbstractBlockChain blockChain, Sha256Hash blockHash, BlockInfo.IncludeTxFlag includeTx) throws BlockStoreException { if (includeTx == BlockInfo.IncludeTxFlag.YES) { throw new IllegalArgumentException("Including transactions not supported yet"); } StoredBlock block = getStoredBlockByHash(blockChain, blockHash); Block header = block.getHeader(); int blockHeight = block.getHeight(); int confirmations = blockChain.getBestChainHeight() - blockHeight; log.trace("building BlockInfo for hash: {} height: {}", blockHash, blockHeight); return new BlockInfo(header.getHash(), confirmations, header.getMessageSize(), blockHeight, (int) header.getVersion(), header.getMerkleRoot(), -1, // Unknown number of Transactions (includeTx == BlockInfo.IncludeTxFlag.IDONLY) ? hashListFromTxList(header.getTransactions()) : null, (int) header.getTimeSeconds(), header.getNonce(), null, // TODO: Return "bits" here new BigDecimal(header.getDifficultyTargetAsInteger()), // TODO: Verify this is correct block.getChainWork().toString(), block.getPrev(blockChain.getBlockStore()).getHeader().getHash(), null); // TODO: Extend BlockStore to make this information retrievable }
Example #4
Source File: VersionTallyTest.java From bcm-android with GNU General Public License v3.0 | 6 votes |
@Test public void testInitialize() throws BlockStoreException { final BlockStore blockStore = new MemoryBlockStore(UNITTEST); final BlockChain chain = new BlockChain(UNITTEST, blockStore); // Build a historical chain of version 2 blocks long timeSeconds = 1231006505; StoredBlock chainHead = null; for (int height = 0; height < UNITTEST.getMajorityWindow(); height++) { chainHead = FakeTxBuilder.createFakeBlock(blockStore, 2, timeSeconds, height).storedBlock; assertEquals(2, chainHead.getHeader().getVersion()); timeSeconds += 60; } VersionTally instance = new VersionTally(UNITTEST); instance.initialize(blockStore, chainHead); assertEquals(UNITTEST.getMajorityWindow(), instance.getCountAtOrAbove(2).intValue()); }
Example #5
Source File: MapBlockStore.java From jelectrum with MIT License | 6 votes |
public void setChainHead(StoredBlock block) throws org.bitcoinj.store.BlockStoreException { Sha256Hash hash = block.getHeader().getHash(); //if (jelly.isUpToDate() || (block.getHeight() % 100 == 0)) { file_db.getSpecialBlockStoreMap().put("head", block); } if (jelly.getBlockChainCache() != null) { jelly.getBlockChainCache().update(jelly, block); } if (jelly.getHeaderChunkAgent()!=null) { jelly.getHeaderChunkAgent().poke(block.getHeight()); } }
Example #6
Source File: WalletTest.java From green_android with GNU General Public License v3.0 | 6 votes |
@Test public void testCategory2WithChange() throws Exception { // Specifically target case 2 with significant change // Generate a ton of small outputs StoredBlock block = new StoredBlock(makeSolvedTestBlock(blockStore, OTHER_ADDRESS), BigInteger.ONE, 1); int i = 0; while (i <= CENT.divide(Transaction.REFERENCE_DEFAULT_MIN_TX_FEE.multiply(10))) { Transaction tx = createFakeTxWithChangeAddress(PARAMS, Transaction.REFERENCE_DEFAULT_MIN_TX_FEE.multiply(10), myAddress, OTHER_ADDRESS); tx.getInput(0).setSequenceNumber(i++); // Keep every transaction unique wallet.receiveFromBlock(tx, block, AbstractBlockChain.NewBlockType.BEST_CHAIN, i); } // The selector will choose 2 with MIN_TX_FEE fee SendRequest request1 = SendRequest.to(OTHER_ADDRESS, CENT.add(SATOSHI)); request1.ensureMinRequiredFee = true; wallet.completeTx(request1); assertEquals(Transaction.REFERENCE_DEFAULT_MIN_TX_FEE, request1.tx.getFee()); assertEquals(request1.tx.getInputs().size(), i); // We should have spent all inputs assertEquals(2, request1.tx.getOutputs().size()); // and gotten change back }
Example #7
Source File: VersionTallyTest.java From GreenBits with GNU General Public License v3.0 | 6 votes |
@Test public void testInitialize() throws BlockStoreException { final BlockStore blockStore = new MemoryBlockStore(PARAMS); final BlockChain chain = new BlockChain(PARAMS, blockStore); // Build a historical chain of version 2 blocks long timeSeconds = 1231006505; StoredBlock chainHead = null; for (int height = 0; height < PARAMS.getMajorityWindow(); height++) { chainHead = FakeTxBuilder.createFakeBlock(blockStore, 2, timeSeconds, height).storedBlock; assertEquals(2, chainHead.getHeader().getVersion()); timeSeconds += 60; } VersionTally instance = new VersionTally(PARAMS); instance.initialize(blockStore, chainHead); assertEquals(PARAMS.getMajorityWindow(), instance.getCountAtOrAbove(2).intValue()); }
Example #8
Source File: WalletTest.java From GreenBits with GNU General Public License v3.0 | 6 votes |
@Test public void testCategory2WithChange() throws Exception { // Specifically target case 2 with significant change // Generate a ton of small outputs StoredBlock block = new StoredBlock(makeSolvedTestBlock(blockStore, OTHER_ADDRESS), BigInteger.ONE, 1); int i = 0; while (i <= CENT.divide(Transaction.REFERENCE_DEFAULT_MIN_TX_FEE.multiply(10))) { Transaction tx = createFakeTxWithChangeAddress(PARAMS, Transaction.REFERENCE_DEFAULT_MIN_TX_FEE.multiply(10), myAddress, OTHER_ADDRESS); tx.getInput(0).setSequenceNumber(i++); // Keep every transaction unique wallet.receiveFromBlock(tx, block, AbstractBlockChain.NewBlockType.BEST_CHAIN, i); } // The selector will choose 2 with MIN_TX_FEE fee SendRequest request1 = SendRequest.to(OTHER_ADDRESS, CENT.add(SATOSHI)); request1.ensureMinRequiredFee = true; wallet.completeTx(request1); assertEquals(Transaction.REFERENCE_DEFAULT_MIN_TX_FEE, request1.tx.getFee()); assertEquals(request1.tx.getInputs().size(), i); // We should have spent all inputs assertEquals(2, request1.tx.getOutputs().size()); // and gotten change back }
Example #9
Source File: VersionTally.java From bcm-android with GNU General Public License v3.0 | 6 votes |
/** * Initialize the version tally from the block store. Note this does not * search backwards past the start of the block store, so if starting from * a checkpoint this may not fill the window. * * @param blockStore block store to load blocks from. * @param chainHead current chain tip. */ public void initialize(final BlockStore blockStore, final StoredBlock chainHead) throws BlockStoreException { StoredBlock versionBlock = chainHead; final Stack<Long> versions = new Stack<>(); // We don't know how many blocks back we can go, so load what we can first versions.push(versionBlock.getHeader().getVersion()); for (int headOffset = 0; headOffset < versionWindow.length; headOffset++) { versionBlock = versionBlock.getPrev(blockStore); if (null == versionBlock) { break; } versions.push(versionBlock.getHeader().getVersion()); } // Replay the versions into the tally while (!versions.isEmpty()) { add(versions.pop()); } }
Example #10
Source File: LevelDBFullPrunedBlockStore.java From GreenBits with GNU General Public License v3.0 | 6 votes |
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); beginDatabaseBatchWrite(); put(storedGenesisHeader, storedGenesis); setChainHead(storedGenesisHeader); setVerifiedChainHead(storedGenesisHeader); batchPut(getKey(KeyType.CREATED), bytes("done")); commitDatabaseBatchWrite(); } catch (VerificationException e) { throw new RuntimeException(e); // Cannot happen. } }
Example #11
Source File: MapBlockStore.java From jelectrum with MIT License | 6 votes |
public StoredBlock getChainHead() throws org.bitcoinj.store.BlockStoreException { StoredBlock head_blk = file_db.getSpecialBlockStoreMap().get("head"); StoredBlock curr = head_blk; int stepback=0; if (file_db.getBlockSavedMap()==null) throw new RuntimeException("BlockMap is null"); while((!file_db.getBlockSavedMap().containsKey(curr.getHeader().getHash())) && (curr.getHeight()>=1)) { int step_size=10; if (curr.getHeight() < 1000) step_size=1; for(int i=0; i<step_size; i++) { stepback++; curr = curr.getPrev(this); } } setChainHead(curr); jelly.getEventLog().alarm("Current Head: " + curr.getHeader().getHash().toString() + " - " + curr.getHeight() + " stepback " + stepback); return curr; }
Example #12
Source File: HeadersStore.java From java-stratum with Apache License 2.0 | 5 votes |
public HeadersStore(NetworkParameters params, File file, StoredBlock checkpoint, URL initialStore) { this.params = params; try { // Set up the backing file. if (initialStore != null && !file.exists()) { uncompressInitialStore(initialStore, file); } randomFile = new RandomAccessFile(file, "rw"); channel = randomFile.getChannel(); fileLock = channel.tryLock(); if (fileLock == null) throw new RuntimeException("Store file is already locked by another process"); if ((randomFile.length() % HEADER_SIZE) != 0) { log.warn("file length not round multiple of header size {}", randomFile.length()); channel.truncate(0); } if (channel.size() == 0) { // Write genesis anyway channel.write(ByteBuffer.wrap(params.getGenesisBlock().cloneAsHeader().bitcoinSerialize()), 0); if (checkpoint != null) { Block header = checkpoint.getHeader().cloneAsHeader(); channel.write(ByteBuffer.wrap(header.bitcoinSerialize()), checkpoint.getHeight() * HEADER_SIZE); } } } catch (IOException e) { if (randomFile != null) try { randomFile.close(); } catch (IOException e1) { propagate(e1); } propagate(e); } }
Example #13
Source File: LevelDBFullPrunedBlockStore.java From GreenBits with GNU General Public License v3.0 | 5 votes |
@Override public void setChainHead(StoredBlock chainHead) throws BlockStoreException { if (instrument) beginMethod("setChainHead"); Sha256Hash hash = chainHead.getHeader().getHash(); this.chainHeadHash = hash; this.chainHeadBlock = chainHead; batchPut(getKey(KeyType.CHAIN_HEAD_SETTING), hash.getBytes()); if (instrument) endMethod("setChainHead"); }
Example #14
Source File: WalletTest.java From GreenBits with GNU General Public License v3.0 | 5 votes |
@Test public void testEmptyRandomWallet() throws Exception { // Add a random set of outputs StoredBlock block = new StoredBlock(makeSolvedTestBlock(blockStore, OTHER_ADDRESS), BigInteger.ONE, 1); Random rng = new Random(); for (int i = 0; i < rng.nextInt(100) + 1; i++) { Transaction tx = createFakeTx(PARAMS, Coin.valueOf(rng.nextInt((int) COIN.value)), myAddress); wallet.receiveFromBlock(tx, block, AbstractBlockChain.NewBlockType.BEST_CHAIN, i); } SendRequest request = SendRequest.emptyWallet(OTHER_ADDRESS); wallet.completeTx(request); wallet.commitTx(request.tx); assertEquals(ZERO, wallet.getBalance()); }
Example #15
Source File: WalletTest.java From green_android with GNU General Public License v3.0 | 5 votes |
@Test public void duplicatedBlock() { final Transaction tx = createFakeTx(PARAMS, COIN, myAddress); StoredBlock block = createFakeBlock(blockStore, Block.BLOCK_HEIGHT_GENESIS, tx).storedBlock; wallet.notifyNewBestBlock(block); wallet.notifyNewBestBlock(block); }
Example #16
Source File: WalletTest.java From green_android with GNU General Public License v3.0 | 5 votes |
@Test public void transactionInBlockNotification() { final Transaction tx = createFakeTx(PARAMS, COIN, myAddress); StoredBlock block = createFakeBlock(blockStore, Block.BLOCK_HEIGHT_GENESIS, tx).storedBlock; wallet.receivePending(tx, null); boolean notification = wallet.notifyTransactionIsInBlock(tx.getHash(), block, AbstractBlockChain.NewBlockType.BEST_CHAIN, 1); assertTrue(notification); final Transaction tx2 = createFakeTx(PARAMS, COIN, OTHER_ADDRESS); wallet.receivePending(tx2, null); StoredBlock block2 = createFakeBlock(blockStore, Block.BLOCK_HEIGHT_GENESIS + 1, tx2).storedBlock; boolean notification2 = wallet.notifyTransactionIsInBlock(tx2.getHash(), block2, AbstractBlockChain.NewBlockType.BEST_CHAIN, 1); assertFalse(notification2); }
Example #17
Source File: ElectrumNotifier.java From jelectrum with MIT License | 5 votes |
private void blockNotify(Subscriber sub, StoredBlock blk) { try { JSONObject reply = new JSONObject(); JSONObject block_data = new JSONObject(); populateBlockData(blk, block_data); JSONArray crap = new JSONArray(); crap.put(block_data); reply.put("params", crap); reply.put("jsonrpc", "2.0"); reply.put("id", JSONObject.NULL); reply.put("method", "blockchain.headers.subscribe"); sub.sendReply(reply); } catch(org.json.JSONException e) { throw new RuntimeException(e); } }
Example #18
Source File: LevelDBFullPrunedBlockStore.java From green_android with GNU General Public License v3.0 | 5 votes |
@Override public void setVerifiedChainHead(StoredBlock chainHead) throws BlockStoreException { if (instrument) beginMethod("setVerifiedChainHead"); Sha256Hash hash = chainHead.getHeader().getHash(); this.verifiedChainHeadHash = hash; this.verifiedChainHeadBlock = chainHead; batchPut(getKey(KeyType.VERIFIED_CHAIN_HEAD_SETTING), hash.getBytes()); if (this.chainHeadBlock.getHeight() < chainHead.getHeight()) setChainHead(chainHead); removeUndoableBlocksWhereHeightIsLessThan(chainHead.getHeight() - fullStoreDepth); if (instrument) endMethod("setVerifiedChainHead"); }
Example #19
Source File: MapBlockStore.java From jelectrum with MIT License | 5 votes |
public void putAll(List<Block> blks) throws org.bitcoinj.store.BlockStoreException { HashMap<Sha256Hash, StoredBlock> insert_map = new HashMap<>(); StoredBlock last = null; for(Block b : blks) { Sha256Hash hash = b.getHash(); Sha256Hash prev = b.getPrevBlockHash(); if (!hash.equals(jelly.getNetworkParameters().getGenesisBlock().getHash())) { StoredBlock prev_sb = insert_map.get(prev); if (prev_sb == null) { prev_sb = file_db.getBlockStoreMap().get(prev); } Assert.assertNotNull(prev_sb); Block header = b.cloneAsHeader(); StoredBlock sb = prev_sb.build(header); last = sb; insert_map.put(hash, sb); } } file_db.getBlockStoreMap().putAll(insert_map); if (last != null) setChainHead(last); }
Example #20
Source File: SPV.java From GreenBits with GNU General Public License v3.0 | 5 votes |
@Override public void receiveFromBlock(final Transaction tx, final StoredBlock block, final BlockChain.NewBlockType blockType, final int relativityOffset) throws VerificationException { if (tx == null) throw new RuntimeException("receiveFromBlock got null tx"); getService().notifyObservers(tx.getHash()); }
Example #21
Source File: HeadersStore.java From java-stratum with Apache License 2.0 | 5 votes |
public void truncate(StoredBlock checkpoint) { int index = checkpoint.getHeight(); lock.lock(); try { Block block = get(index); if (block == null) channel.write(ByteBuffer.wrap(checkpoint.getHeader().cloneAsHeader().bitcoinSerialize()), index * HEADER_SIZE); channel.truncate((index + 1) * HEADER_SIZE); } catch (IOException e) { propagate(e); } finally { lock.unlock(); } }
Example #22
Source File: WalletTest.java From green_android with GNU General Public License v3.0 | 5 votes |
@Test public void testEmptyRandomWallet() throws Exception { // Add a random set of outputs StoredBlock block = new StoredBlock(makeSolvedTestBlock(blockStore, OTHER_ADDRESS), BigInteger.ONE, 1); Random rng = new Random(); for (int i = 0; i < rng.nextInt(100) + 1; i++) { Transaction tx = createFakeTx(PARAMS, Coin.valueOf(rng.nextInt((int) COIN.value)), myAddress); wallet.receiveFromBlock(tx, block, AbstractBlockChain.NewBlockType.BEST_CHAIN, i); } SendRequest request = SendRequest.emptyWallet(OTHER_ADDRESS); wallet.completeTx(request); wallet.commitTx(request.tx); assertEquals(ZERO, wallet.getBalance()); }
Example #23
Source File: LevelDBFullPrunedBlockStore.java From green_android with GNU General Public License v3.0 | 5 votes |
protected void putUpdateStoredBlock(StoredBlock storedBlock, boolean wasUndoable) { // We put as one record as then the get is much faster. if (instrument) beginMethod("putUpdateStoredBlock"); Sha256Hash hash = storedBlock.getHeader().getHash(); ByteBuffer bb = ByteBuffer.allocate(97); storedBlock.serializeCompact(bb); bb.put((byte) (wasUndoable ? 1 : 0)); batchPut(getKey(KeyType.HEADERS_ALL, hash), bb.array()); if (instrument) endMethod("putUpdateStoredBlock"); }
Example #24
Source File: SPVBlockStoreTest.java From GreenBits with GNU General Public License v3.0 | 5 votes |
@Test public void basics() throws Exception { NetworkParameters params = UnitTestParams.get(); File f = File.createTempFile("spvblockstore", null); f.delete(); f.deleteOnExit(); SPVBlockStore store = new SPVBlockStore(params, f); Address to = new ECKey().toAddress(params); // Check the first block in a new store is the genesis block. StoredBlock genesis = store.getChainHead(); assertEquals(params.getGenesisBlock(), genesis.getHeader()); assertEquals(0, genesis.getHeight()); // Build a new block. StoredBlock b1 = genesis.build(genesis.getHeader().createNextBlock(to).cloneAsHeader()); store.put(b1); store.setChainHead(b1); store.close(); // Check we can get it back out again if we rebuild the store object. store = new SPVBlockStore(params, f); StoredBlock b2 = store.get(b1.getHeader().getHash()); assertEquals(b1, b2); // Check the chain head was stored correctly also. StoredBlock chainHead = store.getChainHead(); assertEquals(b1, chainHead); }
Example #25
Source File: LevelDBFullPrunedBlockStore.java From green_android with GNU General Public License v3.0 | 5 votes |
@Override public void setChainHead(StoredBlock chainHead) throws BlockStoreException { if (instrument) beginMethod("setChainHead"); Sha256Hash hash = chainHead.getHeader().getHash(); this.chainHeadHash = hash; this.chainHeadBlock = chainHead; batchPut(getKey(KeyType.CHAIN_HEAD_SETTING), hash.getBytes()); if (instrument) endMethod("setChainHead"); }
Example #26
Source File: WalletTest.java From GreenBits with GNU General Public License v3.0 | 5 votes |
@Test public void transactionGetFeeTest() throws Exception { // Prepare wallet to spend StoredBlock block = new StoredBlock(makeSolvedTestBlock(blockStore, OTHER_ADDRESS), BigInteger.ONE, 1); Transaction tx = createFakeTx(PARAMS, COIN, myAddress); wallet.receiveFromBlock(tx, block, AbstractBlockChain.NewBlockType.BEST_CHAIN, 0); // Create a transaction SendRequest request = SendRequest.to(OTHER_ADDRESS, CENT); request.feePerKb = Transaction.DEFAULT_TX_FEE; wallet.completeTx(request); assertEquals(Coin.valueOf(11350), request.tx.getFee()); }
Example #27
Source File: SPV.java From green_android with GNU General Public License v3.0 | 5 votes |
@Override public boolean notifyTransactionIsInBlock(final Sha256Hash txHash, final StoredBlock block, final BlockChain.NewBlockType blockType, final int relativityOffset) throws VerificationException { Log.d(TAG, "notifyTransactionIsInBlock " + txHash.toString()); return isUnspentOutpoint(txHash); }
Example #28
Source File: SPV.java From green_android with GNU General Public License v3.0 | 5 votes |
@Override public void receiveFromBlock(final Transaction tx, final StoredBlock block, final BlockChain.NewBlockType blockType, final int relativityOffset) throws VerificationException { if (tx == null) throw new RuntimeException("receiveFromBlock got null tx"); Log.d(TAG, "receiveFromBlock " + tx.getHash().toString()); addUtxoToValues(tx.getHash(), true); }
Example #29
Source File: WalletTest.java From GreenBits with GNU General Public License v3.0 | 5 votes |
@Test public void duplicatedBlock() { final Transaction tx = createFakeTx(PARAMS, COIN, myAddress); StoredBlock block = createFakeBlock(blockStore, Block.BLOCK_HEIGHT_GENESIS, tx).storedBlock; wallet.notifyNewBestBlock(block); wallet.notifyNewBestBlock(block); }
Example #30
Source File: ElectrumNotifier.java From jelectrum with MIT License | 5 votes |
public void registerBlockCount(StratumConnection conn, Object request_id, boolean send_initial) { Subscriber sub = new Subscriber(conn, request_id); synchronized(blocknum_subscribers) { String conn_id = conn.getId(); blocknum_subscribers.put(conn_id, sub); } if (send_initial) { StoredBlock blk = chain_head; try { JSONObject reply = sub.startReply(); reply.put("result", blk.getHeight()); reply.put("jsonrpc", "2.0"); sub.sendReply(reply); } catch(org.json.JSONException e) { throw new RuntimeException(e); } } }