Beispiel #1
0
    def filterTX(self, typep, l):
        tx = []
        if len(l) < 3:
            return setOK(tx)
        query = [l[i:i + 3] for i in range(0, len(l), 3)]
        for addrx in query:
            resps = c_peer.sendGETToPeers("address/" + addrx[0] +
                                          "/transactions")
            # to keep it simple, just take first one valid reply
            code = 500
            text = {}
            for rsp in resps:
                if len(rsp) != 0:
                    (text, code) = rsp
                    break
            if code == 200:
                trxn = {}
                if typep < 2:
                    trxn = {'address': addrx[0]}
                elif typep < 4:
                    trxn = {'keyName': addrx[1] + "/" + addrx[0]}
                elif typep < 6:
                    trxn = {'publicKey': addrx[2] + "/" + addrx[0]}

                trxn['transactions'] = []
                for trx in text['transactions']:
                    if "minedInBlockIndex" in trx:
                        if (typep == 0) or (typep == 2) or (typep == 4):
                            trxn['transactions'].append(trx)
                    else:
                        if (typep == 1) or (typep == 3) or (typep == 5):
                            trxn['transactions'].append(trx)
                if len(trxn['transactions']) > 0:
                    tx.append(trxn)
        return setOK(tx)
Beispiel #2
0
    def getMinerCandidate(self, minerAddress):
        #TODO share same block for different miner later on to save memory
        if m_cfg['chainLoaded'] is False:
            sleep(1)
            return errMsg("No chain loaded yet, retry ....")
        err = verifyAddr(minerAddress)
        if len(err) > 0:
            return errMsg(err)
        if minerAddress in m_BufferMinerCandidates:
            cand = m_BufferMinerCandidates[minerAddress]['mineCandidate']
            if cand['index'] == m_candidateBlock['index']:
                if m_BufferMinerCandidates[minerAddress]['minerBlock']['blockDataHash'] == m_candidateBlock['blockDataHash']:
                    return setOK(cand)  # if nothing has changed, return same block
        # as candidate blocks change with every new TX and different miners might deal
        # with different blocks, we must keep the miner specific block in case a miner succeeds
        #if 'prevBlockHash' not in m_candidateBlock:
        self.c_blockchainHandler.prepareNewCandidateBlock()
        minerSpecificBlock = deepcopy(m_candidateBlock)
        # TODO need house-keeping if miners disappear and don't come back,
        # else we get a queue overflow attack by fake miners
        candidateMiner = deepcopy(m_candidateMiner)
        candidateMiner['rewardAddress'] = minerAddress
        minerSpecificBlock['minedBy'] = minerAddress
        fees = minBlockReward
        bindex = len(m_Blocks)
        for tx in m_candidateBlock['transactions']:
            if len(tx) > 0:    #otherwise it is empty coinbase
                fees = fees + tx['fee']
            else:
                if fees != minBlockReward:
                    return errMsg("Invalid minimum CoinBase fee TX in block", 404)
        coinBase = deepcopy(m_coinBase)
        candidateMiner['index'] = bindex
        coinBase['minedInBlockIndex'] = bindex
        minerSpecificBlock['index'] = candidateMiner['index']
        candidateMiner['expectedReward'] = fees
        coinBase['value'] = fees
        coinBase['to'] = minerAddress
        coinBase['dateCreated'] = getTime()
        coinBase['transactionDataHash'] = sha256ToHex(m_transaction_order, coinBase)
        minerSpecificBlock['transactions'].insert(0, coinBase)
        candidateMiner['transactionsIncluded'] = len(minerSpecificBlock['transactions']) #inlcudes coinbase

        # now the block is done, hash it for miner
        # need to calculate now the hash for this specific miner based candidateBlock
        # the hash for the miner has to be in specific order of data
        candidateMiner['blockDataHash'] = makeBlockDataHash(m_candidateBlock, False)
        print("Generate new candidate for miner: " + minerAddress + " with Hash: " + candidateMiner['blockDataHash'] + " reward: " + str(fees))
        m_BufferMinerCandidates[minerAddress] = {}
        m_BufferMinerCandidates[minerAddress]['mineCandidate'] = deepcopy(candidateMiner)
        m_BufferMinerCandidates[minerAddress]['minerBlock'] = minerSpecificBlock
        return setOK(candidateMiner)
Beispiel #3
0
def visualCfg():
    try:
        values = request.get_json()
        if values['active'] is True:
            pattern = re.compile(values['pattern'])
            m_visualCFG['active'] = True
            m_visualCFG['pattern'] = pattern
            return setOK(values)
        m_visualCFG['active'] = False
        m_Delay.clear()
        return setOK("Tracking switched off")
    except Exception:
        return errMsg("JSON not decodeable or missing item")
Beispiel #4
0
 def listPeers(self):
     response = {}
     for peer in m_cfg['activePeers']:
         response.update({m_cfg['activePeers'][peer]['nodeId']: peer})
     for peer in m_cfg['shareToPeers']:
         response.update({m_cfg['shareToPeers'][peer]['nodeId']: peer})
     return setOK(response)
Beispiel #5
0
    def getAllKeys(self, params):
        wal = 'unidentified'
        try:
            wal = params['wallet']
            pattern = re.compile(regexWallet)
            if not pattern.match(wal):
                return errMsg("Invalid wallet name.")

            cmd = "SELECT"
            sel = False
            if "py" in params['sel']:
                cmd = cmd + " 'pubkey:' || pubKey,"
                sel = True

            if "ay" in params['sel']:
                cmd = cmd + " 'addr:' || address,"
                sel = True

            if "ny" in params['sel']:
                cmd = cmd + " 'name:' || KName"
                sel = True

            if sel is False:
                cmd = cmd + " pubKey, address, KName"
            else:
                if cmd.endswith(","):
                    cmd = cmd[0:-1]

            cmd = cmd + " FROM Wallet WHERE WName='" + wal + "'"
            return setOK({"keyList": self.doSelect(cmd)})

        except Exception:
            return errMsg("Collecting keys for wallet " + wal + " failed.")
Beispiel #6
0
    def nodeSpecificGETNow(self, url, linkInfo):
        urlID = url[1:5]
        #if (urlID == 'send'):
        #    return send()
        if urlID == 'info':
            infow = {
                'about': m_info['about'],
                'database': m_db['DATABASE'],
                'chainID': m_info['chainId'],
                'nodeUrl': m_info['nodeUrl'],
                'nodeId': m_info['nodeId']
            }
            return setOK(infow)

        if urlID == 'wall':
            if url.startswith("/wallet/list/wallet"):
                return c_walletInterface.getAllWallets(linkInfo['user'])
            elif url.startswith("/wallet/list/keys/s"):
                return c_walletInterface.getAllKeys(linkInfo)
            elif url.startswith("/wallet/list/balance"):
                return c_walletInterface.getKeyBalance(linkInfo)
            elif url.startswith("/wallet/list/allbalances"):
                return c_walletInterface.getAllBalance(linkInfo)
            elif url.startswith("/wallet/list/allbalance"):
                return c_walletInterface.getWalletBalance(linkInfo)
            elif url.startswith("/wallet/list/allkeybalance"):
                return c_walletInterface.getWalletKeyBalance(linkInfo)
            elif url.startswith("/wallet/list/allTXs/"):
                return c_walletInterface.getAllTX(linkInfo)
            elif url.startswith("/wallet/list/allTX/"):
                return c_walletInterface.getWalletTX(linkInfo)

        if urlID == 'addr':
            return setOK(linkInfo)

            #return send()
        # identify your url and then proceed
        #linkInfo is a json object containing the information from the URL
        response = {
            'NodeType': m_info['type'],
            'info': "This API is not yet implemented....",
            'requestedUrl': url,
            'linkInfo': linkInfo
        }
        ## put your logic here and create the reply as next line
        return errMsg(response)
Beispiel #7
0
 def genTX(self, data):
     ret = self.checkTX(data)
     if len(ret) > 0:
         return errMsg(ret)
     m_data['TXList'].append(data)
     return setOK(
         str(len(m_data['TXList'])) +
         " TXs registered. Most recent type: creating TX")
Beispiel #8
0
def getAllBalances():
    ret = {}
    for balAddr in m_AllBalances:
        bal = m_AllBalances[balAddr]['curBalance']
        if bal != 0:
            ret.update({balAddr: bal})
    # no need to sort by address or so
    return setOK(ret)
Beispiel #9
0
def debug():
    m_ret = {"cfg": deepcopy(m_cfg)}
    addCfg(m_ret)
    if isBCNode():
        m_ret.update({"TX": deepcopy(m_pendingTX)})
        m_ret.update({"minerCandidates": deepcopy(m_BufferMinerCandidates)})
        m_ret.update({"balances": deepcopy(m_AllBalances)})
        m_ret.update({"blocks": deepcopy(m_Blocks)})
    return setOK(m_ret)
Beispiel #10
0
 def getKeyBalance(self, params):
     keys = self.getDataFor([params['sel'], params['key']],
                            params['wallet'], "", params['user'])
     if len(keys) > 4:
         respText, respCode = self.collectKeyBalance(keys[4])
         if respCode == 200:
             return setOK(respText)
         else:
             return errMsg(respText['errorMsg'], respCode)
     return errMsg("Invalid parameters provided")
Beispiel #11
0
    def getTXForHash(self, hash):
        if (len(hash) != len(defHash)):
            return errMsg("Invalid Hash Len")
        response = self.getPendTXByHash(hash)
        # if a given hash is found already, no other exists, else keep searching
        if (len(hash) == 0) or (len(response) == 0):
            response.extend(self.getConfirmedTXByHash(hash))
        if (len(response) > 0):
            return setOK(response)

        return errMsg("No transactions found for: " + hash, 404)
Beispiel #12
0
    def peersConnect(self, source, values, isConnect):
        m, l, f = checkRequiredFields(['peerUrl'], values, [], False)
        if len(m) > 0:
            return errMsg("Missing field 'peerUrl' ")
        url = values['peerUrl']
        newURL = getValidURL(url, True)
        if newURL == "":
            return errMsg("Invalid URL: " + url)

        if isConnect:
            err = self.addPeerOption(url, source)
            if len(err) == 0:
                return setOK("Connection to peer registered")
            if err.startswith("Already connected"):
                return errMsg("Already connected to peer: " + url, 409)
        else:
            err = self.removePeerOption(url)
            if len(err) == 0:
                return setOK("Connection to peer removed")

        return errMsg(err)
Beispiel #13
0
    def setID(self, data):
        if m_data['chainRef'] != "":
            return errMsg("Current chainRef set: " + m_data['chainRef'])

        if project.classes.c_walletInterface.hasWallet(
                'genesis' + data['chainRef']) is True:
            return errMsg("Wallet reference already exists")

        m_data.clear()
        m_data.update(deepcopy(m_dataInit))
        m_data['chainRef'] = data['chainRef']
        return setOK("chain ID set to: " + data['chainRef'])
Beispiel #14
0
 def updGX(self, data):
     if m_data['chainRef'] == "":
         return errMsg("Missing chainRef ")
     if data['chainRef'] != m_data['chainRef']:
         return errMsg("Current chainRef not matching: " +
                       m_data['chainRef'])
     for jtx in data['TXList']:
         if jtx['chainRef'] != m_data['chainRef']:
             return errMsg("One of the TX has invalid chainRef: " +
                           jtx['chainRef'])
     m_data.clear()
     m_data.update(data)
     return setOK("Data updated without major verifications")
Beispiel #15
0
 def getAllBalance(self, params):
     try:
         user = params['user']
         bal = deepcopy(m_balanceData)
         for key in self.doSelect(
                 "SELECT DISTINCT address FROM Wallet WHERE User='******'"):
             val, respCode = self.collectKeyBalance(key)
             if respCode == 200:
                 self.sumBalance(bal, val)
             else:
                 return errMsg(val, respCode)
         return setOK(bal)
     except Exception:
         return errMsg("Seems to have peer issues....")
Beispiel #16
0
 def getWalletBalance(self, params):
     try:
         wal = params['wallet']
         user = params['user']
         bal = deepcopy(m_balanceData)
         for key in self.doSelect(
                 "SELECT address FROM Wallet WHERE WName='" + wal +
                 "' AND User='******'"):
             val, respCode = self.collectKeyBalance(key)
             if respCode == 200:
                 self.sumBalance(bal, val)
         w_cfg["lastBal"] = "" + str(bal['confirmedBalance']) + "/ " + str(
             bal['pendingBalance'])
         return setOK(bal)
     except Exception:
         return errMsg("Seems to have peer issues....")
Beispiel #17
0
def clrNode():
    values = request.get_json()

    #Check that the required fields are in the POST'ed data.
    required = ['node']
    python_obj = json.loads(values)
    for k in required:
        if k not in python_obj:
            return 'Invalid param', 400

    #TODO what was clrNode and setNode() doing?
    oldNodes = setNode(python_obj['node'], m_info['nodeURL'])
    for oldNode in oldNodes:
        if oldNode in m_cfg['nodes']:
            m_cfg['nodes'].remove(oldNode)

    return setOK(m_cfg)
Beispiel #18
0
def visualGet():
    try:
        dat = {}
        for item in m_Delay:
            if 'delayID' in item:
                dat = deepcopy(item)
                item['releaseID'] = dat['delayID']
                del item['delayID']
                break
        dat['activePeers'] = m_cfg['activePeers']
        dat['shareToPeers'] = m_cfg['shareToPeers']
        dat['peerOption'] = m_cfg['peerOption']
        addCfg(dat)
        return setOK(dat)
    except Exception:
        print("visualGet Failed")
    return errMsg("Request failed")
Beispiel #19
0
 def getWalletKeyBalance(self, params):
     try:
         wal = params['wallet']
         user = params['user']
         bal = {}
         for addr in self.doSelect(
                 "SELECT address FROM Wallet WHERE WName='" + wal +
                 "' AND User='******'"):
             val, respCode = self.collectKeyBalance(addr)
             if respCode == 200:
                 bal2 = deepcopy(m_balanceData)
                 bal2['confirmedBalance'] = val['confirmedBalance']
                 bal2['pendingBalance'] = val['pendingBalance']
                 bal[addr] = bal2
         return setOK(bal)
     except Exception:
         return errMsg("Seems to have peer issues....")
Beispiel #20
0
def receivedNewTransaction(trans, share):
    # Checks for missing / invalid fields / invalid field values
    colErr = verifyBasicTX(
        trans, False, m_transaction)  # such can never be coinbase, so False!

    if colErr == "":
        trx = deepcopy(trans)
        passOn = deepcopy(trans)
        del trx["senderSignature"]  # this must be excluded from the hash
        hash = sha256ToHex(m_transaction_order, trx)

        #TODO Validates the transaction public key, validates the signature
        trans["transactionDataHash"] = hash

        # Checks for collisions -> duplicated transactions are skipped
        if hash in m_pendingTX:
            return errMsg("TX is duplicate of in pending TX")

        if isUniqueTXInBlocks(hash) is False:
            return errMsg("TX is duplicate of TX in existing block")
        if ('transferSuccessful'
                not in trans) or (trans['transferSuccessful'] is True):
            tmpBal = getBalance(trans['from'])
            if tmpBal['confirmedBalance'] + tmpBal['pendingBalance'] < trans[
                    'value'] + trans['fee']:
                return errMsg("Not enough balance")

        # Puts the transaction in the "pending transactions" pool
        m_pendingTX.update({trans['transactionDataHash']: deepcopy(trans)})
        if "transferSuccessful" not in trans:
            trans["transferSuccessful"] = True
        trans["minedInBlockIndex"] = len(m_Blocks)
        m_candidateBlock['transactions'].append(deepcopy(trans))
        m_info['pendingTransactions'] = len(m_pendingTX)
        response = {"transactionDataHash": hash}

        m_BufferMinerCandidates.clear()
        if share is True:
            # Sends the transaction to all peer nodes through the REST API
            # It goes from peer to peer until it reaches the entire network
            #TODO do we still need this 'fromPeer'?
            c_peer.sendAsynchPOSTToPeers("/transactions/send", passOn)
            return setOK(response, 201)  #201 as per slide 38
        return  # nothing returned, nothing sent
    return errMsg(colErr)
Beispiel #21
0
 def getBlockHash(self, params):
     try:
         hfrom = +params['from']
         hto = +params['to']
         hlength = +params['cnt']
         if (hfrom < 0) or (hfrom >= len(m_Blocks)) or (hto < hfrom) or \
                 (hlength < 0) or (hlength > len(defHash)):
             return errMsg("Inconsistent request")
         repl = []
         if hlength == 0:
             hlength = len(defHash)
         for x in range(hfrom, hto+1):
             if x >= len(m_Blocks):
                 break
             repl.append([x, m_Blocks[x]['blockHash'][0:hlength]])
         return setOK(repl)
     except Exception:
         return errMsg("Invalid parameters")
Beispiel #22
0
    def getAllKeys(self, params):
        wal = 'unidentified'
        try:
            wal = params['wallet']
            pattern = re.compile(regexWallet)
            if not pattern.match(wal):
                return errMsg("Invalid wallet name.")

            cmd = "SELECT"
            sel = False
            if "py" in params['sel']:
                cmd = cmd + " 'pubkey:' || pubKey,"
                sel = True

            if "ay" in params['sel']:
                cmd = cmd + " 'addr:' || address,"
                sel = True

            if "ny" in params['sel']:
                cmd = cmd + " 'name:' || KName"
                sel = True

            if sel is False:
                cmd = cmd + " pubKey, address, KName"
            else:
                if cmd.endswith(","):
                    cmd = cmd[0:-1]

            cmd = cmd + " FROM Wallet WHERE WName='" + wal + "'"
            ret = project.classes.c_walletInterface.doSelect(cmd)
            repl = []
            for k in ret:
                if k.startswith("addr"):
                    repl.append(k)
                else:
                    if k[-1] == "#":
                        repl.append(k + "no")
                    else:
                        repl.append(k[0:k.rindex("#")] + "#yes")

            return setOK({"keyList": repl})

        except Exception:
            return errMsg("Collecting keys for wallet " + wal + " failed.")
Beispiel #23
0
def visualRelease(idx):
    try:
        found = False
        rel = {}
        for item in m_Delay:
            if ('releaseID' in item) and (item['releaseID'] == idx):
                rel = item
                found = True
                break
        if found is True:
            m_Delay.remove(rel)
            if rel['asynchPOST'] is True:
                requests.post(url=rel['url'],
                              json=rel['json'],
                              headers={'accept': 'application/json'})
            return setOK(rel)
        return errMsg("Unexpected Release for " + str(id))
    except Exception:
        print("visualRelease Failed")
    return errMsg("Request failed")
Beispiel #24
0
    def getTXForAddress(self, address):
        #TODO move to models
        reply = {"address": "undefined", "transactions": []}
        if (len(address) != len(defAdr)):
            errMsg("Inavlid Address Len")
        response = self.getPendTXByAddress(
            address
        )  #order not clearly defined in slide29, pending more important
        # if a given hash is found already, no other exists, else keep searching
        #there is no pending, so return all
        # if (len(hash) == 0) or (len(response) == 0):
        response.extend(self.getConfirmedTXByAddress(address))

        if (len(response) > 0):
            reply['address'] = address
            #we must sort the list by date time in ascending order
            reply['transactions'] = sorted(response,
                                           key=lambda k: k['dateCreated'])
            return setOK(reply)

        return errMsg("No transactions found for: " + address, 404)
Beispiel #25
0
    def nodeSpecificPOST(self, url, linkInfo, json, request):
        ret = {
            'NodeType': m_info['type'],
            'info': "This URL/API is not available/broken"
        }

        try:
            for x in json:
                if not re.match("[0-9a-zA-Z]+", x):
                    return errMsg("Invalid JSON key: " + str(x))
                if isinstance(json[x], str):
                    if not re.match("[0-9a-zA-Z \.%!@#$\-_+=;:,/?<>]*",
                                    json[x]):
                        return errMsg("Invalid character in JSON data: " +
                                      str(x))
                elif isinstance(json[x], list):
                    for xx in json[x]:
                        if isinstance(xx, str):
                            if not re.match("[0-9a-zA-Z \.%!@#$\-_+=;:,/?<>]*",
                                            xx):
                                return errMsg(
                                    "Invalid character in JSON data: " +
                                    str(xx))
                elif not isinstance(json[x], int):
                    return errMsg("Invalid character in JSON data: " +
                                  str(json[x]))

            # This is only applicable to POST, and is a shortcut to stop endless broadcast
            # of the same message
            for urlJson in m_peerSkip:
                if urlJson['url'] == url:
                    m, l, f = checkRequiredFields(json, urlJson['json'],
                                                  urlJson['json'], True)
                    if len(m) + len(f) == 0:
                        #TODO what text here?
                        return setOK("Acknowledge... ")
            # for bigger network, make this bigger as well?
            if len(m_peerSkip) > 10:
                del m_peerSkip[0]

            if self.permittedURLPOST(url) is False:
                return errMsg("This URL/API is invalid or not available. " +
                              url)

            d("Add delay url: '" + url + "' before we had " +
              str(len(m_isPOST)))
            m_isPOST.append(url)

            while (len(m_isPOST) > 1) or (m_cfg['chainInit'] is True):
                if self.delay(url, 2) is False:
                    break  # for some reason we decide to ignore the loop
            while len(m_simpleLock) > 0:
                if self.delay(url, 3) is False:
                    break  # for some reason we decide to ignore the loop

            self.release = False
            if isBCNode():
                ret = self.c_blockInterface.nodeSpecificPOSTNow(
                    url, linkInfo, json, request)
            elif isWallet():
                ret = self.c_walletInterface.nodeSpecificPOSTNow(
                    url, linkInfo, json, request)
            elif isFaucet():
                ret = self.c_faucetInterface.nodeSpecificPOSTNow(
                    url, linkInfo, json, request)
            elif isGenesis():
                ret = self.c_genesisInterface.nodeSpecificPOSTNow(
                    url, linkInfo, json, request)
        except Exception:
            d("*********************************************")
            d("*********************************************")
            print("POST exception caught, isPoststack " + str(len(m_isPOST)))
            d("*********************************************")
            d("*********************************************")

        if url in m_isPOST:
            m_isPOST.remove(url)
            d("Removed delay url: '" + url + "' back to " + str(len(m_isPOST)))
        self.release = True
        return ret
Beispiel #26
0
 def addKeysToWallet(self, data, wal):
     mes, code = self.addKeysToWalletBasic(data, wal)
     if code == 200:
         return setOK(mes)
     return errMsg(mes, code)
Beispiel #27
0
    def checkChainSituation(self, source, blockInfo):
        #We arrive here either because a block notification was sent,
        #or because our peer got an info claiming the peer has longer chain.
        # here we decide on the situation of whether blocks are simply added on top
        # or if something more compliucated is needed, e.g. go back the stack to find
        # common block and then recover shared TXs etc. etc.
        #These are shared among info and block notification
        #   "nodeUrl": sender
        #   "blocksCount": 25, "cumulativeDifficulty": 127
        # added by PDPCOin : blockHash for notification
        #only in info:
        #   "confirmedTransactions": 208
        try:
            d("checking status due to " + source)
            peer = blockInfo['nodeUrl']
            if blockInfo['blocksCount'] < len(m_Blocks):
                d("stay with local chain anyway as it is longer than for " + peer)
                self.asynchNotifyPeers()
                return errMsg("Notified chain shorter than local current, current is:" + str(len(m_Blocks)))
            if source == "notification":
                if 'blockHash' in blockInfo: #PDPCCoin specific shortcut
                    if blockInfo['blockHash'] == m_Blocks[-1]['blockHash']:
                        d("is the same, probably rebound...")
                        return setOK("Thank you for the notification.")
            while m_cfg['checkingChain'] is True:
                d("Already checking chain status, so complete the first one")
                #return errMsg("Please wait for current synchronisation to complete...")
                sleep(1)
            m_cfg['checkingChain'] = True

            if blockInfo['blocksCount'] == len(m_Blocks):
                d("blocks on par, check next step with "+peer)
                #this means we have conflict on the same top block, probably parallel mined
                if blockInfo['cumulativeDifficulty'] < m_info['cumulativeDifficulty']:
                    self.asynchNotifyPeers()
                    m_cfg['checkingChain'] = False
                    d("local difficulty higher, no change")
                    return errMsg("Peers chain cumulativeDifficulty lower than local current, current is:" + str(m_info['cumulativeDifficulty']))
                else:
                    # we have same height and same or lower difficulty, so we need to roll the dice for now
                    # based on hash
                    #get the actual block from peer
                    res, stat = self.getNextBlock(peer, -1)
                    if stat == 200:
                        # yoursbetter must not be based on the claim but based
                        # on the block data and its difficulty versus my cumulative
                        # else an attacker might cheat with high claim but low delivery
                        # 0) we ignore your cumDiff
                        # a) myDiff versus your blockDifficulty
                        # b) mycum-myDiff+yourDiff == your claimed cumDif
                        d("got peer block as requested with OK")
                        # We repeat the check here in case we had info instead of notification!
                        if res['blockHash'] == m_Blocks[-1]['blockHash']:
                            d("anyway the same")
                            m_cfg['checkingChain'] = False
                            return setOK("Thank you for the notification.")
                        # need to include difficulty in this decision
                        yoursBetter = blockInfo['cumulativeDifficulty'] > m_info['cumulativeDifficulty']
                        if yoursBetter is False:
                            yoursBetter = res['difficulty'] > m_Blocks[-1]['difficulty']
                        if yoursBetter is False:
                            d("same block difficulty")
                            #we are confirmed same same in all, so lets roll the deterministic dice
                            #by crossing the two inputs instead of checking umber of TX or value etc.,
                            #all of which could lead to easier rigging than dice
                            lstDice = ""
                            indexMy=0
                            indexYou=0
                            dice = "x"
                            xst = [res['blockDataHash'], m_Blocks[-1]['blockHash'], m_Blocks[-1]['blockDataHash'], res['blockHash']]
                            xst.sort()
                            for lst in xst:
                                lstDice = lstDice + lst
                            while indexMy == indexYou:
                                lstDice = lstDice+dice
                                d("roll the dice...")
                                dice = sha256StrToHex(lstDice)[0]
                                d("Dice value:"+str(dice))
                                indexMy = m_Blocks[-1]['blockHash'].index(dice)
                                indexYou = res['blockHash'].index(dice)
                                d(str(indexMy) + " vs " + str(indexYou))
                                if (indexYou > indexMy):
                                    yoursBetter = True
                            d("dice said yoursBetter :" + str(yoursBetter))
                        if yoursBetter is True:
                            if res['prevBlockHash'] != m_Blocks[-1]['prevBlockHash']:
                                d("hashes different need to settle backtrack")
                                return self.handleChainBackTracking(peer)
                            d("!!!we conceeded, add peers block from "+peer)
                            restor = m_Blocks[-1]
                            confirmRevertBalances(restor['transactions'])
                            del m_Blocks[-1]
                            err = self.checkAndAddBlock(res, True)
                            if len(err) > 0:
                               d("something was wrong, restore own previous block")
                               self.checkAndAddBlock(restor, True)
                               m_cfg['checkingChain'] = False
                               return errMsg("Invalid block received")
                        else:
                            self.asynchNotifyPeers()
                            d("local copy maintained after all")
                            i=0
                        m_cfg['checkingChain'] = False
                        return setOK("Thank you for the notification.")
                    m_cfg['checkingChain'] = False
                    d("The reply did not have the correct fields")
                    return errMsg("No proper reply, ignored")
            else:
                d("local chain appears shorter anyway, so just ask for up to block "+str(blockInfo['blocksCount']))
                # the peer claims to be ahead of us with at leats one block, so catch up until something happens
                # easy case just add the new block on top, and each block is checked fully, no backtrack
                res, stat = self.getNextBlock(peer, 0)
                if stat == 200:
                    # backtrack into the stack!!!
                    if res['prevBlockHash'] != m_Blocks[-1]['blockHash']:
                        d("hashes different need to settle backtrack")
                        return self.handleChainBackTracking(peer)
                    if source == 'notification':
                        d("Sender want a reply, so process")
                        err = self.getMissingBlocksFromPeer(blockInfo['nodeUrl'], blockInfo['blocksCount'], True, res)
                        m_cfg['checkingChain'] = False
                        if len(err) > 0:
                            return errMsg(err)
                        return setOK("Thank you for the notification.")
                    else:
                        d("this is info internal, so create thread and don't care result")
                        threadx = Thread(target=self.getMissingBlocksFromPeer, args=(blockInfo['nodeUrl'], blockInfo['blocksCount'], False, res))
                        threadx.start()
                        return setOK("No one sees this answer anyway, but in case, we are processing blocks")
                m_cfg['checkingChain'] = False
                return errMsg("Invalid block received")  # for info this is ignored anyway
        except Exception:
            m_cfg['checkingChain'] = False
            return errMsg("Processing error occurred")
Beispiel #28
0
 def getJSONBlockByNumber(self, blockNr):
     blk = self.getBlockByNumber(blockNr)
     if len(blk) > 0:
         return setOK(blk)
     return errMsg('BlockNumber not valid or not existent: '+str(blockNr))
Beispiel #29
0
 def getBlockBalances(self, para):
     bal = {}
     err = self.getBalanceFromToBlock(0, para['to'], bal)
     if err != "":
         return errMsg(err)
     return setOK(bal)
Beispiel #30
0
 def getAllWallets(self, user):
     return setOK({"walletList": self.listAllWallets(user)})