Exemplo n.º 1
0
 def setUpClass(self):
     # Handle both calling the this test from the context of the test directory
     # and calling this test from the context of the main directory.
     # The latter happens if you run all of the tests in the directory
     if os.path.exists(TIAB_ZIPFILE_NAME):
         tiabZipPath = TIAB_ZIPFILE_NAME
     elif os.path.exists(os.path.join('pytest', TIAB_ZIPFILE_NAME)):
         tiabZipPath = (os.path.join('pytest', TIAB_ZIPFILE_NAME))
     else:
         self.fail(NEED_TIAB_MSG)
     self.tiab = TiabSession(tiabZipPath=tiabZipPath)
     # Need to destroy whatever BDM may have been created automatically
     CppBlockUtils.BlockDataManager().DestroyBDM()
     newTheBDM()
     TheBDM.setDaemon(True)
     TheBDM.start()
     TheBDM.setSatoshiDir(
         os.path.join(self.tiab.tiabDirectory, 'tiab', '1', 'testnet3'))
     self.armoryHomeDir = os.path.join(self.tiab.tiabDirectory, 'tiab',
                                       'armory')
     TheBDM.setLevelDBDir(
         os.path.join(self.tiab.tiabDirectory, 'tiab', 'armory',
                      'databases'))
     TheBDM.setBlocking(True)
     TheBDM.setOnlineMode(wait=True)
     i = 0
     while not TheBDM.getBDMState() == 'BlockchainReady' and i < 10:
         time.sleep(2)
         i += 1
     if i >= 10:
         raise RuntimeError(
             "Timeout waiting for TheBDM to get into BlockchainReady state."
         )
Exemplo n.º 2
0
    def __init__(self, isOffline=False):
        super(BlockDataManager, self).__init__()

        #register callbacks
        self.callback = PySide_CallBack(self).__disown__()
        self.inject = BDM_Inject().__disown__()

        self.armoryDBDir = ""

        #dbType
        self.dbType = Cpp.ARMORY_DB_BARE
        if ENABLE_SUPERNODE:
            self.dbType = Cpp.ARMORY_DB_SUPER

        self.bdmThread = Cpp.BlockDataManagerThread(
            self.bdmConfig(forInit=True))

        # Flags
        self.aboutToRescan = False
        self.errorOut = 0

        self.currentActivity = 'None'
        self.walletsToRegister = []

        if isOffline == True: self.bdmState = BDM_OFFLINE
        else: self.bdmState = BDM_UNINITIALIZED

        self.btcdir = BTC_HOME_DIR
        self.armoryDBDir = ARMORY_DB_DIR
        self.lastPctLoad = 0

        self.topBlockHeight = 0
        self.cppNotificationListenerList = []
Exemplo n.º 3
0
    def instantiateBDV(self, port):
        if self.bdmState == BDM_OFFLINE:
            return

        socketType = Cpp.SocketFcgi
        if self.remoteDB:
            socketType = Cpp.SocketHttp

        self.bdv_ = Cpp.BlockDataViewer_getNewBDV(\
                       str(ARMORYDB_IP), str(port), socketType)
Exemplo n.º 4
0
    def run(self, action, arg, block):
        try:
            act = ''
            arglist = []

            # AOTODO replace with constants

            if action == Cpp.BDMAction_Ready:
                print 'BDM is ready!'
                act = FINISH_LOAD_BLOCKCHAIN_ACTION
                TheBDM.topBlockHeight = block
                TheBDM.setState(BDM_BLOCKCHAIN_READY)
            elif action == Cpp.BDMAction_ZC:
                act = NEW_ZC_ACTION
                castArg = Cpp.BtcUtils_cast_to_LedgerVector(arg)
                arglist = castArg
            elif action == Cpp.BDMAction_NewBlock:
                act = NEW_BLOCK_ACTION
                castArg = Cpp.BtcUtils_cast_to_int(arg)
                arglist.append(castArg)
                TheBDM.topBlockHeight = block
            elif action == Cpp.BDMAction_Refresh:
                act = REFRESH_ACTION
                castArg = Cpp.BtcUtils_cast_to_BinaryDataVector(arg)
                arglist = castArg
            elif action == Cpp.BDMAction_Exited:
                act = STOPPED_ACTION
            elif action == Cpp.BDMAction_ErrorMsg:
                act = WARNING_ACTION
                argstr = Cpp.BtcUtils_cast_to_string(arg)
                arglist.append(argstr)
            elif action == Cpp.BDMAction_StartedWalletScan:
                act = SCAN_ACTION
                argstr = Cpp.BtcUtils_cast_to_string_vec(arg)
                arglist.append(argstr)

            listenerList = TheBDM.getListenerList()
            for cppNotificationListener in listenerList:
                cppNotificationListener(act, arglist)
        except:
            LOGEXCEPT('Error in running callback')
            print sys.exc_info()
            raise
Exemplo n.º 5
0
    def instantiateBDV(self):
        if self.bdmState == BDM_OFFLINE:
            return

        socketType = Cpp.SocketFcgi
        if ARMORYDB_IP != ARMORYDB_DEFAULT_IP or ARMORYDB_PORT != ARMORYDB_DEFAULT_PORT:
            socketType = Cpp.SocketHttp
            self.remoteDB = True

        self.bdv_ = Cpp.BlockDataViewer_getNewBDV(ARMORYDB_IP, ARMORYDB_PORT,
                                                  socketType)
Exemplo n.º 6
0
    def bdmConfig(self, forInit=False):

        blkdir = ""

        if forInit == False:
            # Check for the existence of the Bitcoin-Qt directory
            if not os.path.exists(self.btcdir):
                raise FileExistsError, ('Directory does not exist: %s' %
                                        self.btcdir)

            blkdir = os.path.join(self.btcdir, 'blocks')
            blk1st = os.path.join(blkdir, 'blk00000.dat')

            # ... and its blk000X.dat files
            if not os.path.exists(blk1st):
                LOGERROR('Blockchain data not available: %s', blk1st)
                raise FileExistsError, ('Blockchain data not available: %s' %
                                        blk1st)

        blockdir = blkdir
        armoryDBDir = self.armoryDBDir

        if OS_WINDOWS:
            if isinstance(blkdir, unicode):
                blockdir = blkdir.encode('utf8')
            if isinstance(self.armoryDBDir, unicode):
                armoryDBDir = self.armoryDBDir.encode('utf8')

        bdmConfig = Cpp.BlockDataManagerConfig()
        bdmConfig.armoryDbType = self.dbType
        bdmConfig.pruneType = Cpp.DB_PRUNE_NONE
        bdmConfig.blkFileLocation = blockdir
        bdmConfig.levelDBLocation = armoryDBDir
        bdmConfig.setGenesisBlockHash(GENESIS_BLOCK_HASH)
        bdmConfig.setGenesisTxHash(GENESIS_TX_HASH)
        bdmConfig.setMagicBytes(MAGIC_BYTES)

        return bdmConfig
Exemplo n.º 7
0
 def getCookie(self):
     if self.cookie == None:
         self.cookie = Cpp.BlockDataManagerConfig_getCookie(
             str(self.datadir))
     return self.cookie
Exemplo n.º 8
0
    # NOTE:  "TheBDM" is sometimes used in the C++ code to reference the
    #        singleton BlockDataManager_LevelDB class object.  Here,
    #        "TheBDM" refers to a python BlockDataManagerThead class
    #        object that wraps the C++ version.  It implements some of
    #        it's own methods, and then passes through anything it
    #        doesn't recognize to the C++ object.
    LOGINFO('Using the asynchronous/multi-threaded BlockDataManager.')
    LOGINFO('Blockchain operations will happen in the background.  ')
    LOGINFO('Devs: check TheBDM.getState() before asking for data.')
    LOGINFO('Registering addresses during rescans will queue them for ')
    LOGINFO('inclusion after the current scan is completed.')
    TheBDM = BlockDataManager(isOffline=False)

    cppLogFile = os.path.join(ARMORY_HOME_DIR, 'armorycpplog.txt')
    cpplf = cppLogFile
    if OS_WINDOWS and isinstance(cppLogFile, unicode):
        cpplf = cppLogFile.encode('utf8')
    Cpp.StartCppLogging(cpplf, 4)
    Cpp.EnableCppLogStdOut()

    #LOGINFO('LevelDB max-open-files is %d', TheBDM.getMaxOpenFiles())

    # Also load the might-be-needed SatoshiDaemonManager
    TheSDM = SatoshiDaemonManager()

# Put the import at the end to avoid circular reference problem
from armoryengine.MultiSigUtils import MultiSigLockbox
from armoryengine.Transaction import PyTx

# kate: indent-width 3; replace-tabs on;
Exemplo n.º 9
0
def randomk():
    # Using Crypto++ CSPRNG instead of python's
    sbdRandK = CppBlockUtils.SecureBinaryData().GenerateRandom(32)
    hexRandK = sbdRandK.toBinStr().encode('hex_codec')
    return int(hexRandK, 16)
Exemplo n.º 10
0
    blkfile = os.path.expanduser(
        '~/Library/Application Support/Bitcoin/blk0001.dat')

if len(sys.argv) > 1:
    blkfile = sys.argv[1]

print '*' * 80
print 'Importing BlockUtils module...',
#from CppBlockUtils import *
import CppBlockUtils as Cpp

print 'Done!'
print ''

print 'Constructing BlockDataManager... ',
bdm = Cpp.BlockDataManager().getBDM()
print 'Done!'
print ''

print 'Loading blk0001.dat...            '
bdm.readBlkFile_FromScratch(blkfile)
print 'Done!'
print ''

print 'Organizing the blockchain...      ',
bdm.organizeChain()
print 'Done!'
print ''

print '*' * 80
print 'Getting top block of the chain... ',
Exemplo n.º 11
0
 def tearDownClass(self):
     CppBlockUtils.BlockDataManager().DestroyBDM()
     self.tiab.clean()
Exemplo n.º 12
0
 def getPrivDataForKey(self, key):
    if key in self.privData:
       return self.privData[key]
    else:
       return Cpp.SecureBinaryData()
Exemplo n.º 13
0
    def addAddress(self,
                   addrData,
                   pubKeyStr='',
                   firstSeenData=[],
                   lastSeenData=[]):
        """
      There are a plethora of ways to add your key/address/wallet data to a
      PyBtcWallet object:
         - PubKeyHash160 (only the 20-byte address)
         - Public Key (which computes address)
         - Private Key (which computes public key and address)
         - Private and Public key (assumes they match, skips verification)
         - Existing PyBtcAddress object

      Scanning the blockchain for transactions is remarkably faster when you
      have information about the first and last time we've seen data in the
      blockchain.  That way, we can skip over parts of the chain where wallet
      data couldn't possibly exist.
      """
        print 'Adding new address to wallet: ',
        addr160 = None
        if isinstance(addrData, PyBtcAddress) and addrData.isInitialized():
            addr160 = addrData.getAddr160()
            self.addrMap[addr160] = addrData
        elif isinstance(addrData, str):
            if len(addrData) == 20:
                addr160 = addrData
                self.addrMap[addr160] = PyBtcAddress(
                ).createFromPublicKeyHash160(addr160)
            elif 64 <= len(addrData) <= 65:
                addr160 = hash160(addrData.rjust(65, '\x04'))
                self.addrMap[addr160] = PyBtcAddress().createFromPublicKey(
                    pubKeyStr)
            elif len(addrData) == 32:
                newPrivAddr = PyBtcAddress()
                if len(pubKeyStr) > 0:
                    newPrivAddr.createFromKeyData(addrData, pubKeyStr, False)
                else:
                    newPrivAddr.createFromPrivateKey(addrData)
                addr160 = newPrivAddr.getAddr160()
                self.addrMap[addr160] = newPrivAddr
        else:
            print '<ERROR>'
            raise BadAddressError, 'Improper address supplied to "addAddress()"'
        print binary_to_hex(addr160)

        # Now make sure the C++ wallet is sync'd
        addrObj = self.addrMap[addr160]
        cppAddr = Cpp.BtcAddress()
        cppAddr.setAddrStr20(addr160)
        if addrObj.hasPubKey():
            cppAddr.setPubKey65(addrObj.pubKey_serialize())
        if addrObj.hasPrivKey():
            cppAddr.setPrivKey32(addrObj.privKey_serialize())

        if len(firstSeenData) > 0: cppAddr.setFirstTimestamp(firstSeenData[0])
        if len(firstSeenData) > 1: cppAddr.setFirstBlockNum(firstSeenData[1])
        if len(lastSeenData) > 0: cppAddr.setLastTimestamp(lastSeenData[0])
        if len(lastSeenData) > 1: cppAddr.setLastBlockNum(lastSeenData[1])

        if not self.cppWallet:
            self.cppWallet = Cpp.BtcWallet()
        self.cppWallet.addAddress_BtcAddress_(cppAddr)
Exemplo n.º 14
0
#
################################################################################
from pybtcengine import *
import CppBlockUtils as Cpp
from datetime import datetime
from os import path
from sys import argv


class WalletLockError(Exception):
    pass


################################################################################
# Might as well create the BDM right here -- there will only ever be one, anyway
bdm = Cpp.BlockDataManager().getBDM()


################################################################################
def loadBlockchainFile(blkfile=None, testnet=False):
    """
   Looks for the blk0001.dat file in the default location for your operating
   system.  If it is found, it is loaded into RAM and the longest chain is
   computed.  Access to any information in the blockchain can be found via
   the bdm object.
   """
    import platform
    opsys = platform.system()
    if blkfile == None:
        if not testnet:
            if 'win' in opsys.lower():