# Path: coloredcoinlib/blockchain.py
# class BlockchainState(BlockchainStateBase):
#     """ Represents a blockchain state, using bitcoin-RPC to
#     obtain information of transactions, addresses, and blocks. """
#     def __init__(self, bitcoind):
#         self.bitcoind = bitcoind
# 
#     def publish_tx(self, txdata):
#         return self.bitcoind.sendrawtransaction(txdata)
# 
#     @classmethod
#     def from_url(cls, url, testnet=False):
#         if testnet:
#             bitcoind = bitcoin.rpc.RawProxy(
#                 service_url=url, service_port=18332)
#         else:
#             bitcoind = bitcoin.rpc.RawProxy(  # pragma: no cover
#                 service_url=url)              # pragma: no cover
#         return cls(bitcoind)
# 
#     def get_block_height(self, blockhash):
#         block = self.bitcoind.getblock(blockhash)
#         return block['height']
# 
#     def get_block_count(self):
#         return self.bitcoind.getblockcount()
# 
#     def get_block_hash(self, index):
#         return self.bitcoind.getblockhash(index)
# 
#     def get_block(self, blockhash):
#         return self.bitcoind.getblock(blockhash)
# 
#     def get_blockhash_at_height(self, height):
#         return self.bitcoind.getblockhash(height)
# 
#     def get_previous_blockinfo(self, blockhash):
#         block_data = self.bitcoind.getblock(blockhash)
#         return block_data['previousblockhash'], block_data['height']
# 
#     def get_tx_blockhash(self, txhash):
#         try:
#             raw = self.bitcoind.getrawtransaction(txhash, 1)
#         except Exception, e:
#             # print txhash, e
#             return None, False
#         return raw.get('blockhash', None), True
# 
#     def get_raw(self, txhash):
#         return self.bitcoind.getrawtransaction(txhash, 0)
# 
#     def get_tx(self, txhash):
#         txhex = self.bitcoind.getrawtransaction(txhash, 0)
#         txbin = bitcoin.core.x(txhex)
#         tx = bitcoin.core.CTransaction.deserialize(txbin)
#         return CTransaction.from_bitcoincore(txhash, tx, self)
# 
#     def get_best_blockhash(self):
#         try:
#             return self.bitcoin.getbestblockhash()
#         except:
#             # warning: not atomic!
#             # remove once bitcoin 0.9 becomes commonplace
#             count = self.bitcoind.getblockcount()
#             return self.bitcoind.getblockhash(count)
# 
#     def iter_block_txs(self, blockhash):
#         block_hex = None
#         try:
#             block_hex = self.bitcoind.getblock(blockhash, False)
#         except bitcoin.rpc.JSONRPCException:
#             pass
# 
#         if block_hex:
#             # block at once
#             block = bitcoin.core.CBlock.deserialize(bitcoin.core.x(block_hex))
#             block_hex = None
#             for tx in block.vtx:
#                 txhash = bitcoin.core.b2lx(
#                     bitcoin.core.serialize.Hash(tx.serialize()))
#                 yield CTransaction.from_bitcoincore(txhash, tx, self)
#         else:
#             txhashes = self.bitcoind.getblock(blockhash)['tx']
#             for txhash in txhashes:
#                 yield self.get_tx(txhash)
# 
#     def sort_txs(self, tx_list):
#         block_txs = {h:self.get_tx(h) for h in tx_list}
# 
#         def get_dependent_txs(tx):
#             """all transactions from current block this transaction
#             directly depends on"""
#             dependent_txs = []
#             for inp in tx.inputs:
#                 if inp.prevout.hash in block_txs:
#                     dependent_txs.append(block_txs[inp.prevout.hash])
#             return dependent_txs
# 
#         return toposorted(block_txs.values(), get_dependent_txs)
# 
#     def get_mempool_txs(self):
#         return self.sort_txs(self.bitcoind.getrawmempool())
# 
# def script_to_raw_address(script):
#     # extract the destination address from the scriptPubkey
#     if script[:3] == "\x76\xa9\x14":
#         return script[3:23]
#     else:
#         return None


import unittest
from bitcoin.rpc import RawProxy
from coloredcoinlib.blockchain import BlockchainState, script_to_raw_address
                         self.previous_blockhash)
        
    def test_ensure(self):
        self.tx.ensure_input_values()
        self.assertTrue(self.tx.have_input_values)
        self.tx.ensure_input_values()
        self.assertTrue(self.tx.have_input_values)
        self.coinbasetx.ensure_input_values()
        self.assertTrue(self.coinbasetx.have_input_values)

    def test_get_best(self):
        self.assertTrue(self.bs.get_best_blockhash())
        
    def test_iter_block_txs(self):
        i = 0
        txs = []
        for tx in self.bs.iter_block_txs(self.blockhash):
            i += 1
            tx.ensure_input_values()
            txs.append(tx.hash)
        self.assertEqual(i, 12)
        sorted_txs = [tx.hash for tx in self.bs.sort_txs(txs)]
        self.assertEqual(len(sorted_txs), 12)
        # a should be before b
        a = '5e9762b340e2f72a66dabe16d738a8ae89d71843286e7c9354eaf299d906845c'
        b = '264b174948d0be47d7661b60ecc88b575ab1216617f5298a230c27f7a34f2e40'
        self.assertTrue(a in sorted_txs)
        self.assertTrue(b in sorted_txs)
        self.assertTrue(sorted_txs.index(a) < sorted_txs.index(b))


# Path: coloredcoinlib/blockchain.py
# class BlockchainState(BlockchainStateBase):
#     """ Represents a blockchain state, using bitcoin-RPC to
#     obtain information of transactions, addresses, and blocks. """
#     def __init__(self, bitcoind):
#         self.bitcoind = bitcoind
# 
#     def publish_tx(self, txdata):
#         return self.bitcoind.sendrawtransaction(txdata)
# 
#     @classmethod
#     def from_url(cls, url, testnet=False):
#         if testnet:
#             bitcoind = bitcoin.rpc.RawProxy(
#                 service_url=url, service_port=18332)
#         else:
#             bitcoind = bitcoin.rpc.RawProxy(  # pragma: no cover
#                 service_url=url)              # pragma: no cover
#         return cls(bitcoind)
# 
#     def get_block_height(self, blockhash):
#         block = self.bitcoind.getblock(blockhash)
#         return block['height']
# 
#     def get_block_count(self):
#         return self.bitcoind.getblockcount()
# 
#     def get_block_hash(self, index):
#         return self.bitcoind.getblockhash(index)
# 
#     def get_block(self, blockhash):
#         return self.bitcoind.getblock(blockhash)
# 
#     def get_blockhash_at_height(self, height):
#         return self.bitcoind.getblockhash(height)
# 
#     def get_previous_blockinfo(self, blockhash):
#         block_data = self.bitcoind.getblock(blockhash)
#         return block_data['previousblockhash'], block_data['height']
# 
#     def get_tx_blockhash(self, txhash):
#         try:
#             raw = self.bitcoind.getrawtransaction(txhash, 1)
#         except Exception, e:
#             # print txhash, e
#             return None, False
#         return raw.get('blockhash', None), True
# 
#     def get_raw(self, txhash):
#         return self.bitcoind.getrawtransaction(txhash, 0)
# 
#     def get_tx(self, txhash):
#         txhex = self.bitcoind.getrawtransaction(txhash, 0)
#         txbin = bitcoin.core.x(txhex)
#         tx = bitcoin.core.CTransaction.deserialize(txbin)
#         return CTransaction.from_bitcoincore(txhash, tx, self)
# 
#     def get_best_blockhash(self):
#         try:
#             return self.bitcoin.getbestblockhash()
#         except:
#             # warning: not atomic!
#             # remove once bitcoin 0.9 becomes commonplace
#             count = self.bitcoind.getblockcount()
#             return self.bitcoind.getblockhash(count)
# 
#     def iter_block_txs(self, blockhash):
#         block_hex = None
#         try:
#             block_hex = self.bitcoind.getblock(blockhash, False)
#         except bitcoin.rpc.JSONRPCException:
#             pass
# 
#         if block_hex:
#             # block at once
#             block = bitcoin.core.CBlock.deserialize(bitcoin.core.x(block_hex))
#             block_hex = None
#             for tx in block.vtx:
#                 txhash = bitcoin.core.b2lx(
#                     bitcoin.core.serialize.Hash(tx.serialize()))
#                 yield CTransaction.from_bitcoincore(txhash, tx, self)
#         else:
#             txhashes = self.bitcoind.getblock(blockhash)['tx']
#             for txhash in txhashes:
#                 yield self.get_tx(txhash)
# 
#     def sort_txs(self, tx_list):
#         block_txs = {h:self.get_tx(h) for h in tx_list}
# 
#         def get_dependent_txs(tx):
#             """all transactions from current block this transaction
#             directly depends on"""
#             dependent_txs = []
#             for inp in tx.inputs:
#                 if inp.prevout.hash in block_txs:
#                     dependent_txs.append(block_txs[inp.prevout.hash])
#             return dependent_txs
# 
#         return toposorted(block_txs.values(), get_dependent_txs)
# 
#     def get_mempool_txs(self):
#         return self.sort_txs(self.bitcoind.getrawmempool())
# 
# def script_to_raw_address(script):
#     # extract the destination address from the scriptPubkey
#     if script[:3] == "\x76\xa9\x14":
#         return script[3:23]
#     else:
#         return None


# Path: coloredcoinlib/tests/test_blockchain.py
import unittest
from bitcoin.rpc import RawProxy
from coloredcoinlib.blockchain import BlockchainState, script_to_raw_address

                         self.previous_blockhash)
        
    def test_ensure(self):
        self.tx.ensure_input_values()
        self.assertTrue(self.tx.have_input_values)
        self.tx.ensure_input_values()
        self.assertTrue(self.tx.have_input_values)
        self.coinbasetx.ensure_input_values()
        self.assertTrue(self.coinbasetx.have_input_values)

    def test_get_best(self):
        self.assertTrue(self.bs.get_best_blockhash())
        
    def test_iter_block_txs(self):
        i = 0
        txs = []
        for tx in self.bs.iter_block_txs(self.blockhash):
            i += 1
            tx.ensure_input_values()
            txs.append(tx.hash)
        self.assertEqual(i, 12)
        sorted_txs = [tx.hash for tx in self.bs.sort_txs(txs)]
        self.assertEqual(len(sorted_txs), 12)
        # a should be before b
        a = '5e9762b340e2f72a66dabe16d738a8ae89d71843286e7c9354eaf299d906845c'
        b = '264b174948d0be47d7661b60ecc88b575ab1216617f5298a230c27f7a34f2e40'
        self.assertTrue(a in sorted_txs)
        self.assertTrue(b in sorted_txs)
        self.assertTrue(sorted_txs.index(a) < sorted_txs.index(b))


    def test_mempool(self):