diff --git a/armoryengine.py b/armoryengine.py index 3ef438378..357846f65 100644 --- a/armoryengine.py +++ b/armoryengine.py @@ -54,7 +54,7 @@ # Use CLI args to determine testnet or not -USE_TESTNET = not ('--mainnet' in argv) +USE_TESTNET = ('--testnet' in argv) diff --git a/cppForSwig/BlockUtils.cpp b/cppForSwig/BlockUtils.cpp index 30cb72b96..14dc3c2e2 100644 --- a/cppForSwig/BlockUtils.cpp +++ b/cppForSwig/BlockUtils.cpp @@ -63,7 +63,7 @@ TxIOPair::TxIOPair(TxRef* txPtrO, uint32_t txoutIndex, TxRef* txPtrI, uint32_t txinIndex) : - amount_(0) + amount_(0), txPtrOfOutputZC_(NULL), indexOfOutputZC_(0), txPtrOfInputZC_(NULL), @@ -95,11 +95,10 @@ BinaryData TxIOPair::getTxHashOfInput(void) ////////////////////////////////////////////////////////////////////////////// bool TxIOPair::setTxInRef(TxRef* txref, uint32_t index, bool isZeroConf) { - bool success=true; if(isZeroConf) { if(hasTxIn() || hasTxInZC()) - success=false; + return false; else { txPtrOfInputZC_ = txref; @@ -112,17 +111,16 @@ bool TxIOPair::setTxInRef(TxRef* txref, uint32_t index, bool isZeroConf) indexOfInput_ = index; } - return success; + return true; } ////////////////////////////////////////////////////////////////////////////// -void TxIOPair::setTxOutRef(TxRef* txref, uint32_t index, bool isZeroConf) +bool TxIOPair::setTxOutRef(TxRef* txref, uint32_t index, bool isZeroConf) { - bool success=true; if(isZeroConf) { if(hasTxOut() || hasTxOutZC()) - success=false; + return false; else { txPtrOfOutputZC_ = txref; @@ -138,7 +136,7 @@ void TxIOPair::setTxOutRef(TxRef* txref, uint32_t index, bool isZeroConf) if(hasTxOut()) amount_ = getTxOutRef().getValue(); } - return success; + return true; } ////////////////////////////////////////////////////////////////////////////// @@ -149,6 +147,7 @@ bool TxIOPair::isStandardTxOutScript(void) return false; } +////////////////////////////////////////////////////////////////////////////// pair TxIOPair::reassessValidity(void) { pair result; @@ -157,6 +156,61 @@ pair TxIOPair::reassessValidity(void) return result; } + +bool TxIOPair::isSpent(void) +{ + // Not sure whether we should verify hasTxOut. It wouldn't make much + // sense to have TxIn but not TxOut, but there might be a preferred + // behavior in such awkward circumstances + return (hasTxIn() || hasTxInZC()); +} + + +bool TxIOPair::isUnspent(void) +{ + return ( (hasTxOut() || hasTxOutZC()) && !isSpent()); + +} + +////////////////////////////////////////////////////////////////////////////// +bool TxIOPair::isSpendable(void) +{ + // Spendable TxOuts are ones with at least 1 confirmation, or zero-conf + // TxOuts that were sent-to-self. Obviously, they should be unspent, too + if( (hasTxIn() && txPtrOfInput_->isMainBranch()) || hasTxInZC() ) + return false; + + if( hasTxOut() && txPtrOfOutput_->isMainBranch()) + return true; + + if( hasTxOutZC() && isSentToSelf() ) + return true; + + return false; +} + +////////////////////////////////////////////////////////////////////////////// +bool TxIOPair::isMineButUnconfirmed(uint32_t currBlk, uint32_t minConf) +{ + // Only zero-conf Tx can be unconfirmed + if( (hasTxIn() && txPtrOfInput_->isMainBranch()) || hasTxInZC() ) + return false; + + if( hasTxOut() && txPtrOfOutput_->isMainBranch() ) + { + uint32_t nConf = currBlk - txPtrOfOutput_->getBlockHeight() + 1; + if(nConf const * lockedOPs) +uint64_t BtcAddress::getSpendableBalance(void) { uint64_t balance = 0; for(uint32_t i=0; iisSpendable()) + balance += relevantTxIOPtrs_[i]->getValue(); + } + return balance; +} - // If this TxOut is locked, skip it - if(lockedOPs != NULL && - lockedOPs->find(txio.getOutPoint()) != lockedOPs->end()) - continue; +//////////////////////////////////////////////////////////////////////////////// +uint64_t BtcAddress::getUnconfirmedBalance(uint32_t currBlk) +{ + uint64_t balance = 0; + for(uint32_t i=0; iisMineButUnconfirmed(currBlk)) + balance += relevantTxIOPtrs_[i]->getValue(); + } + return balance; +} - if(txio.isUnspent() && txio.getTxRefOfOutput().isMainBranch()) +//////////////////////////////////////////////////////////////////////////////// +uint64_t BtcAddress::getUltimateBalance(void) +{ + uint64_t balance = 0; + for(uint32_t i=0; i BtcAddress::getSpendableTxOutList(uint32_t blkNum) +{ + vector utxoList(0); + for(uint32_t i=0; isecond; if(insResult.second == true) { - //unspentOutPoints_.insert(outpt); + unspentOutPoints_.insert(outpt); anyTxOutIsOurs = true; thisTxOutIsOurs[iout] = true; @@ -583,9 +672,9 @@ void BtcWallet::scanTx(TxRef & tx, isChangeBack); if(isZeroConf) - ledgerAllAddrZC_.push_back(le) + ledgerAllAddrZC_.push_back(le); else - ledgerAllAddr_.push_back(le) + ledgerAllAddr_.push_back(le); } } @@ -630,6 +719,7 @@ vector BtcWallet::getLedgerEntriesForZeroConfTxList( // addresses with pointers to the new TxIO objects, not the old ones. This // allows us to scan new transactions in a temporary wallet, without affecting // the original wallet +/* void BtcWallet::makeTempCopyForZcScan(BtcWallet & tempWlt) { @@ -708,6 +798,7 @@ vector BtcWallet::getAddrLedgerEntriesForTx(BinaryData const & zcBi return leVect; } +*/ //////////////////////////////////////////////////////////////////////////////// // Make a separate method here so we can get creative with how to handle these @@ -763,42 +854,90 @@ void BtcWallet::scanNonStdTx(uint32_t blknum, } //////////////////////////////////////////////////////////////////////////////// -uint64_t BtcWallet::getBalance(bool blockchainOnly) +//uint64_t BtcWallet::getBalance(bool blockchainOnly) + +//////////////////////////////////////////////////////////////////////////////// +uint64_t BtcWallet::getSpendableBalance(void) { - /* uint64_t balance = 0; - set::iterator unspentIter; - for( unspentIter = unspentOutPoints_.begin(); - unspentIter != unspentOutPoints_.end(); - unspentIter++) - { - TxIOPair & txio = txioMap_[*unspentIter]; - if(txio.getTxRefOfOutput().isMainBranch() && - (!isTxOutLocked(*unspentIter) || blockchainOnly)) - { - balance += txioMap_[*unspentIter].getValue(); - } + map::iterator iter; + for(iter = txioMap_.begin(); + iter != txioMap_.end(); + iter++) + { + if(iter->second.isSpendable()) + balance += iter->second.getValue(); } + return balance; +} - +//////////////////////////////////////////////////////////////////////////////// +uint64_t BtcWallet::getUnconfirmedBalance(uint32_t currBlk) +{ + uint64_t balance = 0; + map::iterator iter; + for(iter = txioMap_.begin(); + iter != txioMap_.end(); + iter++) + { + if(iter->second.isMineButUnconfirmed(currBlk)) + balance += iter->second.getValue(); + } return balance; - */ } - //////////////////////////////////////////////////////////////////////////////// -uint64_t BtcWallet::getBalance(uint32_t i) +uint64_t BtcWallet::getUltimateBalance(void) { - return addrPtrVect_[i]->getBalance(&lockedTxOuts_); + uint64_t balance = 0; + map::iterator iter; + for(iter = txioMap_.begin(); + iter != txioMap_.end(); + iter++) + { + if(iter->second.isUnspent()) + balance += iter->second.getValue(); + } + return balance; } //////////////////////////////////////////////////////////////////////////////// -uint64_t BtcWallet::getBalance(BinaryData const & addr20) +vector BtcWallet::getSpendableTxOutList(uint32_t blkNum) { - assert(hasAddr(addr20)); - return addrMap_[addr20].getBalance(&lockedTxOuts_); + vector utxoList(0); + map::iterator iter; + for(iter = txioMap_.begin(); + iter != txioMap_.end(); + iter++) + { + TxIOPair & txio = iter->second; + if(txio.isSpendable()) + { + TxOutRef txoutref = txio.getTxOutRef(); + utxoList.push_back(UnspentTxOut(txoutref, blkNum) ); + } + } + return utxoList; } + + + + + +//////////////////////////////////////////////////////////////////////////////// +//uint64_t BtcWallet::getBalance(uint32_t i) +//{ + //return addrPtrVect_[i]->getBalance(); +//} + +////////////////////////////////////////////////////////////////////////////////// +//uint64_t BtcWallet::getBalance(BinaryData const & addr20) +//{ + //assert(hasAddr(addr20)); + //return addrMap_[addr20].getBalance(); +//} + //////////////////////////////////////////////////////////////////////////////// uint32_t BtcWallet::removeInvalidEntries(void) { @@ -823,65 +962,7 @@ void BtcWallet::sortLedger(void) sort(ledgerAllAddr_.begin(), ledgerAllAddr_.end()); } -//////////////////////////////////////////////////////////////////////////////// -bool BtcWallet::lockTxOut(OutPoint const & op) -{ - bool newLocked = false; - set & unspentOps = getUnspentOutPoints(); - if(unspentOps.find(op)!=unspentOps.end()) - { - lockedTxOuts_.insert(op); - newLocked = true; - } - return newLocked; -} -//////////////////////////////////////////////////////////////////////////////// -bool BtcWallet::unlockTxOut(OutPoint const & op) -{ - bool newUnlocked = false; - set & unspentOps = getUnspentOutPoints(); - if(unspentOps.find(op)!=unspentOps.end()) - { - if(lockedTxOuts_.find(op)!=lockedTxOuts_.end()) - { - lockedTxOuts_.erase(op); - newUnlocked = true; - } - } - return newUnlocked; -} - - -void BtcWallet::lockTxOutSwig(BinaryData const & hash, uint32_t idx) -{ - OutPoint op(hash, idx); - lockTxOut(op); -} -void BtcWallet::unlockTxOutSwig(BinaryData const & hash, uint32_t idx) -{ - OutPoint op(hash, idx); - unlockTxOut(op); -} - -bool BtcWallet::isTxOutLocked(OutPoint const & op) -{ - return (lockedTxOuts_.find(op)!=lockedTxOuts_.end()); -} - - -vector BtcWallet::getLockedTxOutList(void) -{ - vector out(0); - set::iterator unspentIter; - for( unspentIter = lockedTxOuts_.begin(); - unspentIter != lockedTxOuts_.end(); - unspentIter++) - { - out.push_back(*unspentIter); - } - return out; -} bool BtcWallet::isOutPointMine(BinaryData const & hsh, uint32_t idx) { @@ -1186,6 +1267,21 @@ void BlockDataManager_FullRAM::scanBlockchainForTx(BtcWallet & myWallet, myWallet.scanTx(tx, itx, bhr.getTimestamp(), bhr.getBlockHeight()); } } + + + if(zcEnabled_) + { + myWallet.clearZeroConfPool(); + map::iterator iter; + for(iter = zeroConfMap_.begin(); + iter != zeroConfMap_.end(); + iter++) + { + myWallet.scanTx(iter->second.txref_, 0, UINT32_MAX, UINT32_MAX); + } + } + + myWallet.sortLedger(); // removes invalid tx and sorts PDEBUG("Done scanning blockchain for tx"); } @@ -1574,6 +1670,12 @@ void BlockDataManager_FullRAM::updateWalletAfterReorg(BtcWallet & wlt) } + // UPDATE JAN 2012: I don't think this part is necessary anymore. + // The decision was made not to bother with maintaining + // an unspent list anymore, since it can be done on the + // fly from the txioMap. And unspent doesn't imply whether + // it's actually spendable or "confirmed." + /* // Need to fix the TxIO pairs, and recompute unspentTxOuts // All addresses point to the wallet's TxIOPairs, so we only need // to do this check on the wallet -- no need on the individual addrs @@ -1601,6 +1703,7 @@ void BlockDataManager_FullRAM::updateWalletAfterReorg(BtcWallet & wlt) wlt.getUnspentOutPoints().erase(txioIter->first); } } + */ // Now fix the individual address ledgers for(uint32_t a=0; a BlockDataManager_FullRAM::getUnspentTxOutsForWallet( BtcWallet & wlt, int sortType, @@ -2219,6 +2323,7 @@ BlockDataManager_FullRAM::getNonStdUnspentTxOutsForWallet( BtcWallet & wlt) cout << "Not implemented yet to retrieve non-std TxOuts..."<< endl; return vector(0); } +*/ @@ -2236,7 +2341,7 @@ void BlockDataManager_FullRAM::enableZeroConf(string zcFilename) //////////////////////////////////////////////////////////////////////////////// void BlockDataManager_FullRAM::readZeroConfFile(string zcFilename) { - ifstream zcFile(zcFilename_, ios::in | ios::binary); + ifstream zcFile(zcFilename_.c_str(), ios::in | ios::binary); if(zcFile) { zcFile.seekg(0, ios::end); @@ -2275,24 +2380,24 @@ void BlockDataManager_FullRAM::addNewZeroConfTx(BinaryData const & rawTx, if(txtime==0) txtime = time(NULL); - BinaryData txHash = BtcUtils::getHash256(rawTx) + BinaryData txHash = BtcUtils::getHash256(rawTx); if(zeroConfMap_.find(txHash) != zeroConfMap_.end()) return; zeroConfMap_[txHash] = ZeroConfData(); ZeroConfData & zc = zeroConfMap_[txHash]; - zc.iter_ = zeroConfTxList_.insert(rawTx); - zc.txref_.unserialize(*newTxData); + zc.iter_ = zeroConfTxList_.insert(zeroConfTxList_.end(), rawTx); + zc.txref_.unserialize(rawTx); zc.txtime_ = txtime; // Record time. Write to file if(writeToFile) { - ofstream zcFile(zcFilename_, ios::app | ios::binary); + ofstream zcFile(zcFilename_.c_str(), ios::app | ios::binary); zcFile.write( (char*)(&zc.txtime_), sizeof(uint64_t) ); - zcFile.write( (char*)(&zc.txref_.getPtr()), zc.txref_.getSize()) + zcFile.write( (char*)zc.txref_.getPtr(), zc.txref_.getSize()); zcFile.close(); } } @@ -2318,20 +2423,13 @@ void BlockDataManager_FullRAM::purgeZeroConfPool(void) // We've made a list of the zc tx to remove, now let's remove them // I decided this was safer than erasing the data as we were iterating // over it in the previous loop - list< map::iterator >::iterator iter; - for(iter = mapRmList.begin(); - iter != mapRmList.end(); - iter++) + list< map::iterator >::iterator rmIter; + for(rmIter = mapRmList.begin(); + rmIter != mapRmList.end(); + rmIter++) { - // Remove from the zero-conf txOuts map - for(uint32_t iin=0; iinsecond.iter_ ); - zeroConfMap_.erase( *iter ) + zeroConfTxList_.erase( (*rmIter)->second.iter_ ); + zeroConfMap_.erase( *rmIter ); } // Rewrite the zero-conf pool file @@ -2342,15 +2440,16 @@ void BlockDataManager_FullRAM::purgeZeroConfPool(void) //////////////////////////////////////////////////////////////////////////////// void BlockDataManager_FullRAM::rewriteZeroConfFile(void) { - ofstream zcFile(zcFilename_, ios::out | ios::binary); + ofstream zcFile(zcFilename_.c_str(), ios::out | ios::binary); map::iterator iter; for(iter = zeroConfMap_.begin(); iter != zeroConfMap_.end(); iter++) { + ZeroConfData & zc = iter->second; zcFile.write( (char*)(&zc.txtime_), sizeof(uint64_t) ); - zcFile.write( (char*)(&zc.txref_.getPtr()), zc.txref_.getSize()) + zcFile.write( (char*)(zc.txref_.getPtr()), zc.txref_.getSize()); } zcFile.close(); @@ -2358,7 +2457,7 @@ void BlockDataManager_FullRAM::rewriteZeroConfFile(void) //////////////////////////////////////////////////////////////////////////////// -void BlockDataManager_FullRAM::updateWalletWithZeroConf(BtcWallet & wlt) +void BlockDataManager_FullRAM::rebuildZeroConfLedgers(BtcWallet & wlt) { // Clear the whole list, rebuild // Inefficient but also irrelevant unless we have millions of @@ -2370,66 +2469,49 @@ void BlockDataManager_FullRAM::updateWalletWithZeroConf(BtcWallet & wlt) iter != zeroConfMap_.end(); iter++) { - TxRef & txref = iter->second.txref_; - - // (Re-)lock any TxOuts spent - bool anyInputsMine = false; - for(uint32_t iin=0; iinsecond.txref_, 0, UINT32_MAX, UINT32_MAX); + } +} - // Add new TxOuts to a temporary pool - for(uint32_t iout=0; iout BtcAddress::getZeroConfLedger(void) +{ + return ledgerZC_; +} //////////////////////////////////////////////////////////////////////////////// void BtcWallet::clearZeroConfPool(void) { - lockedTxOuts_.clear(); - myZeroConfTxOuts_.clear(); - myZeroConfOutPointsToSelf_.clear(); + ledgerAllAddrZC_.clear(); + for(uint32_t i=0; iclearZeroConfPool(); } - //////////////////////////////////////////////////////////////////////////////// -vector BtcWallet::getZeroConfLedger(void) +vector BtcWallet::getZeroConfLedger(BinaryData const * addr160) { - + // Make sure to rebuild the ZC ledgers before calling this method + if(addr160==NULL) + return ledgerAllAddrZC_; + else + { + if(addrMap_.find(*addr160) == addrMap_.end()) + return vector(0); + else + return addrMap_[*addr160].getZeroConfLedger(); + } } -vector BtcWallet::getZeroConfLedgerForAddr(BinaryData const & addr160) -{ - -} + diff --git a/cppForSwig/BlockUtils.h b/cppForSwig/BlockUtils.h index 2654f2831..0a77eac9f 100644 --- a/cppForSwig/BlockUtils.h +++ b/cppForSwig/BlockUtils.h @@ -97,22 +97,22 @@ class TxIOPair bool isSentToSelf(void) { return isSentToSelf_; } bool setSentToSelf(bool isTrue=true) { isSentToSelf_ = isTrue; } + ////////////////////////////////////////////////////////////////////////////// BinaryData getTxHashOfInput(void); BinaryData getTxHashOfOutput(void); - void setTxInRef (TxRef* txref, uint32_t index, bool isZeroConf=false); - void setTxOutRef (TxRef* txref, uint32_t index, bool isZeroConf=false); + bool setTxInRef (TxRef* txref, uint32_t index, bool isZeroConf=false); + bool setTxOutRef(TxRef* txref, uint32_t index, bool isZeroConf=false); ////////////////////////////////////////////////////////////////////////////// - bool isSpent(void) { return ( hasTxOut() && hasTxIn() ); } - bool isUnspent(void) { return ( hasTxOut() && !hasTxIn() ); } bool isSourceUnknown(void) { return ( !hasTxOut() && hasTxIn() ); } bool isStandardTxOutScript(void); - bool isSpentZC(void) { return ( hasTxOut() && hasTxIn() ); } - bool isUnspentZC(void) { return ( hasTxOut() && !hasTxIn() ); } + bool isSpent(void); + bool isUnspent(void); bool isSpendable(void); + bool isMineButUnconfirmed(uint32_t currBlk, uint32_t minConf=6); private: uint64_t amount_; @@ -270,7 +270,18 @@ class BtcAddress void sortLedger(void); uint32_t removeInvalidEntries(void); - uint64_t getBalance(set const * lockedList=NULL); + // BlkNum is necessary for "unconfirmed" list, since it is dependent + // on number of confirmations. But for "spendable" TxOut list, it is + // only a convenience, if you want to be able to calculate numConf from + // the Utxos in the list. If you don't care (i.e. you only want to + // know what TxOuts are available to spend, you can pass in 0 for currBlk + uint64_t getUltimateBalance(void); + uint64_t getSpendableBalance(void); + uint64_t getUnconfirmedBalance(uint32_t currBlk); + vector getSpendableTxOutList(uint32_t currBlk); + void clearZeroConfPool(void); + vector getZeroConfLedger(void); + vector & getTxLedger(void) { return ledger_; } vector & getTxIOList(void) { return relevantTxIOPtrs_; } @@ -354,10 +365,18 @@ class BtcWallet uint32_t txoutidx, BtcAddress& addr); - uint64_t getBalance(void); - uint64_t getBalance(uint32_t i); - uint64_t getBalance(BinaryData const & addr20); + // BlkNum is necessary for "unconfirmed" list, since it is dependent + // on number of confirmations. But for "spendable" TxOut list, it is + // only a convenience, if you want to be able to calculate numConf from + // the Utxos in the list. If you don't care (i.e. you only want to + // know what TxOuts are available to spend, you can pass in 0 for currBlk + uint64_t getUltimateBalance(void); + uint64_t getSpendableBalance(void); + uint64_t getUnconfirmedBalance(uint32_t currBlk); + vector getSpendableTxOutList(uint32_t currBlk=0); + void clearZeroConfPool(void); + vector getZeroConfLedger(BinaryData const * addr160=NULL); uint32_t getNumAddr(void) {return addrMap_.size();} @@ -371,40 +390,17 @@ class BtcWallet map & getTxIOMap(void) {return txioMap_;} map & getNonStdTxIO(void) {return nonStdTxioMap_;} - // NOTE: These methods return raw OutPoint objects, which have to be - // queried through txHashMap_ to get info about the TxOuts - // Use this only if you have some reason to get the minimal - // set of information representing all TxOuts - set & getUnspentOutPoints(void) {return unspentOutPoints_;} - set & getNonStdUnspentOutPoints(void){return nonStdUnspentOutPoints_;} - - // If we have spent TxOuts but the tx haven't made it into the blockchain - // we need to lock them to make sure we have a record of which ones are - // available to sign more Txs - bool lockTxOut(OutPoint const & op); - bool unlockTxOut(OutPoint const & op); - void clearZeroConfPool(void); {lockedTxOuts_.clear(); } - - void lockTxOutSwig(BinaryData const & hash, uint32_t idx); - void unlockTxOutSwig(BinaryData const & hash, uint32_t idx); - - bool isTxOutLocked(OutPoint const & op); - vector getLockedTxOutList(void); - bool isOutPointMine(BinaryData const & hsh, uint32_t idx); - map & getMyZeroConfTxOuts(void) {return myZeroConfTxOuts_;} - set & getMyZeroConfOutPointsToSelf(void) {return myZeroConfOutPointsToSelf_;} + //map & getMyZeroConfTxOuts(void) {return myZeroConfTxOuts_;} + //set & getMyZeroConfOutPointsToSelf(void) {return myZeroConfOutPointsToSelf_;} private: vector addrPtrVect_; map addrMap_; map txioMap_; - map myZeroConfTxOuts_; - set myZeroConfOutPointsToSelf_; - vector ledgerAllAddr_; vector ledgerAllAddrZC_; @@ -648,6 +644,16 @@ class BlockDataManager_FullRAM vector findAllNonStdTx(void); + // For zero-confirmation tx-handling + void enableZeroConf(string); + void disableZeroConf(string); + void readZeroConfFile(string); + void addNewZeroConfTx(BinaryData const & rawTx, uint64_t txtime, bool writeToFile=true); + void purgeZeroConfPool(void); + void rewriteZeroConfFile(void); + void rebuildZeroConfLedgers(BtcWallet & wlt); + + // After reading in all headers, find the longest chain and set nextHash vals // TODO: Figure out if there is an elegant way to deal with a forked // blockchain containing two equal-length chains @@ -661,8 +667,8 @@ class BlockDataManager_FullRAM void updateWalletsAfterReorg(vector wlt); // Use these two methods to get ALL information about your unused TxOuts - vector getUnspentTxOutsForWallet(BtcWallet & wlt, int sortType=-1); - vector getNonStdUnspentTxOutsForWallet(BtcWallet & wlt); + //vector getUnspentTxOutsForWallet(BtcWallet & wlt, int sortType=-1); + //vector getNonStdUnspentTxOutsForWallet(BtcWallet & wlt); //////////////////////////////////////////////////////////////////////////////// // We're going to need the BDM's help to get the sender for a TxIn since it diff --git a/cppForSwig/BlockUtilsTest.cpp b/cppForSwig/BlockUtilsTest.cpp index c39044ce5..0c8fc713d 100644 --- a/cppForSwig/BlockUtilsTest.cpp +++ b/cppForSwig/BlockUtilsTest.cpp @@ -140,25 +140,26 @@ void TestScanForWalletTx(string blkfile) BinaryData myAddress; BtcWallet wlt; -#ifndef TEST_NETWORK // Main-network addresses myAddress.createFromHex("604875c897a079f4db88e5d71145be2093cae194"); wlt.addAddress(myAddress); myAddress.createFromHex("8996182392d6f05e732410de4fc3fa273bac7ee6"); wlt.addAddress(myAddress); myAddress.createFromHex("b5e2331304bc6c541ffe81a66ab664159979125b"); wlt.addAddress(myAddress); myAddress.createFromHex("ebbfaaeedd97bc30df0d6887fd62021d768f5cb8"); wlt.addAddress(myAddress); myAddress.createFromHex("11b366edfc0a8b66feebae5c2e25a7b6a5d1cf31"); wlt.addAddress(myAddress); -#else // Test-network addresses - myAddress.createFromHex("5aa2b7e93537198ef969ad5fb63bea5e098ab0cc"); wlt.addAddress(myAddress); - myAddress.createFromHex("28b2eb2dc53cd15ab3dc6abf6c8ea3978523f948"); wlt.addAddress(myAddress); - myAddress.createFromHex("720fbde315f371f62c158b7353b3629e7fb071a8"); wlt.addAddress(myAddress); - myAddress.createFromHex("0cc51a562976a075b984c7215968d41af43be98f"); wlt.addAddress(myAddress); - myAddress.createFromHex("57ac7bfb77b1f678043ac6ea0fa67b4686c271e5"); wlt.addAddress(myAddress); - myAddress.createFromHex("b11bdcd6371e5b567b439cd95d928e869d1f546a"); wlt.addAddress(myAddress); - myAddress.createFromHex("2bb0974f6d43e3baa03d82610aac2b6ed017967d"); wlt.addAddress(myAddress); - myAddress.createFromHex("61d62799e52bc8ee514976a19d67478f25df2bb1"); wlt.addAddress(myAddress); -#endif - + //myAddress.createFromHex("5aa2b7e93537198ef969ad5fb63bea5e098ab0cc"); wlt.addAddress(myAddress); + //myAddress.createFromHex("28b2eb2dc53cd15ab3dc6abf6c8ea3978523f948"); wlt.addAddress(myAddress); + //myAddress.createFromHex("720fbde315f371f62c158b7353b3629e7fb071a8"); wlt.addAddress(myAddress); + //myAddress.createFromHex("0cc51a562976a075b984c7215968d41af43be98f"); wlt.addAddress(myAddress); + //myAddress.createFromHex("57ac7bfb77b1f678043ac6ea0fa67b4686c271e5"); wlt.addAddress(myAddress); + //myAddress.createFromHex("b11bdcd6371e5b567b439cd95d928e869d1f546a"); wlt.addAddress(myAddress); + //myAddress.createFromHex("2bb0974f6d43e3baa03d82610aac2b6ed017967d"); wlt.addAddress(myAddress); + //myAddress.createFromHex("61d62799e52bc8ee514976a19d67478f25df2bb1"); wlt.addAddress(myAddress); + + // More testnet addresses, with only a few transactions + myAddress.createFromHex("0c6b92101c7025643c346d9c3e23034a8a843e21"); wlt.addAddress(myAddress); + myAddress.createFromHex("34c9f8dc91dfe1ae1c59e76cbe1aa39d0b7fc041"); wlt.addAddress(myAddress); + myAddress.createFromHex("d77561813ca968270d5f63794ddb6aab3493605e"); wlt.addAddress(myAddress); myAddress.createFromHex("0e0aec36fe2545fb31a41164fb6954adcd96b342"); wlt.addAddress(myAddress); TIMER_WRAP(bdm.scanBlockchainForTx(wlt)); @@ -169,8 +170,8 @@ void TestScanForWalletTx(string blkfile) for(uint32_t i=0; i const & ledger = wlt.getAddrByIndex(i).getTxLedger(); for(uint32_t j=0; j sortedUTOs = bdm.getUnspentTxOutsForWallet(myWallet, 1); + //vector sortedUTOs = bdm.getUnspentTxOutsForWallet(myWallet, 1); + vector sortedUTOs = myWallet.getSpendableTxOutList(); int i=1; cout << " Sorting Method: " << i << endl; @@ -257,16 +259,16 @@ void TestScanForWalletTx(string blkfile) bdm.scanBlockchainForTx(zcWlt); // Test the zero-conf ledger-entry detection - BinaryData txSelf = BinaryData::CreateFromHex("010000000158e7e1c2414ac51b3a6fd24bd5df2ccebf09db5fa5803f124ae8e65c05b50fb2010000008c4930460221001332f6fecbd40e0ac6ca570468863b1ce7b8061e82fab8d6eaa3810b75a4588c022100102ded6875cb317464f8d6af40337a0932cbb350aec5f3290d02209d1a46324c0141047737e67302d8a47e496bd5030b14964c9330e3be73f9fd90edc405064149c17eaffaaa71488853e60365487fc7bf281635bda43d7763764ecce91edcf2ca02aeffffffff048058840c000000001976a91457ac7bfb77b1f678043ac6ea0fa67b4686c271e588ac80969800000000001976a914b11bdcd6371e5b567b439cd95d928e869d1f546a88ac80778e06000000001976a914b11bdcd6371e5b567b439cd95d928e869d1f546a88ac70032d00000000001976a914b11bdcd6371e5b567b439cd95d928e869d1f546a88ac00000000"); + //BinaryData txSelf = BinaryData::CreateFromHex("010000000158e7e1c2414ac51b3a6fd24bd5df2ccebf09db5fa5803f124ae8e65c05b50fb2010000008c4930460221001332f6fecbd40e0ac6ca570468863b1ce7b8061e82fab8d6eaa3810b75a4588c022100102ded6875cb317464f8d6af40337a0932cbb350aec5f3290d02209d1a46324c0141047737e67302d8a47e496bd5030b14964c9330e3be73f9fd90edc405064149c17eaffaaa71488853e60365487fc7bf281635bda43d7763764ecce91edcf2ca02aeffffffff048058840c000000001976a91457ac7bfb77b1f678043ac6ea0fa67b4686c271e588ac80969800000000001976a914b11bdcd6371e5b567b439cd95d928e869d1f546a88ac80778e06000000001976a914b11bdcd6371e5b567b439cd95d928e869d1f546a88ac70032d00000000001976a914b11bdcd6371e5b567b439cd95d928e869d1f546a88ac00000000"); - LedgerEntry le = zcWlt.getWalletLedgerEntryForTx(txSelf); - le.pprint(); + //LedgerEntry le = zcWlt.getWalletLedgerEntryForTx(txSelf); + //le.pprint(); - vector levect = zcWlt.getAddrLedgerEntriesForTx(txSelf); - for(int i=0; i levect = zcWlt.getAddrLedgerEntriesForTx(txSelf); + //for(int i=0; i const & ledger = wlt2.getAddrByIndex(i).getTxLedger(); for(uint32_t j=0; j const & ledgerAll3 = wlt2.getTxLedger(); for(uint32_t j=0; j const & ledger = wlt2.getAddrByIndex(i).getTxLedger(); for(uint32_t j=0; j #include #include +#include #include "BinaryData.h" #include "cryptlib.h" @@ -880,6 +881,40 @@ class BtcUtils for(uint32_t i=0; i ' - exit(0) - -# Process CLI arguments -recipAddr = PyBtcAddress().createFromAddrStr(argv[1]) -recipValue = long(float(argv[2]) * COIN) -fee = 0 - -# Load the blockchain -loadBlockchainFile() - -# Create a wallet, which for now will only contain one key -pywlt = PyBtcWallet() - -# This private key corresponds to: -# addrStr = '12HFYcL3Gj8EPhgeXk5689z8Wcc7x7FsNx' -# addr160 = '0e0aec36fe2545fb31a41164fb6954adcd96b342' -# pubKeyHex = ('04' '8d103d81ac9691cf13f3fc94e44968ef67b27f58b27372c13108552d24a6ee04' -# '785838f34624b294afee83749b64478bb8480c20b242c376e77eea2b3dc48b4b') -privKeyHex = 'a5001fd8d7103877f577aa176926b18b1e004195644abb7f7dc19e3f267e7aa4' -pywlt.addAddress(hex_to_binary(privKeyHex)) -utxoList = pywlt.getUnspentTxOutList() - -# Let's display all available TxOuts -pprintUnspentTxOutList(utxoList, 'All unspent coins:') - - -# Figure out a *good* selection of TxOuts to use -prelimSelection = PySelectCoins(utxoList, recipValue, fee) -feeRecommended = calcMinSuggestedFees(prelimSelection, recipValue, fee) -pprintUnspentTxOutList(prelimSelection, 'Selected TxOuts for (tgt,fee)=(%s,%s)' % \ - (coin2str(recipValue), coin2str(fee))) -print 'Recommended fees: AbsMin=%s, Suggest=%s' % tuple([coin2str(f) for f in feeRecommended]) - - -# Construct the output addresses, with a random order -recipPairs = [] -recipPairs.append(['1PymCiNzubeTtJt47dqFdi31Zy9MAM1YZk', long(recipValue/3)]) -recipPairs.append([recipAddr, long(recipValue/3)]) -recipPairs.append(['1JiLbGTrVNmk6BsePVQWmBiD7DFUDmMYXw', long(recipValue/3)]) -#pair1 = [recipAddr, recipValue] -#pair2 = [pywlt.getAddrByIndex(0), sumTxOutList(prelimSelection)-(recipValue+fee)] -#if random.uniform(0,1) < 0.5: - #recipPairs = [pair1, pair2] -#else: - #recipPairs = [pair2, pair1] - -print '\n\nCreating TxDistProposal:' -txdp = PyTxDistProposal().createFromTxOutSelection(prelimSelection, recipPairs) -txdp.pprint() - -print '\n\nSigning the TxDP:' -signedTxDP = pywlt.signTxDistProposal(txdp) -txToBroadcast = signedTxDP.getFinalPyTx() -txToBroadcast.pprint() - -print binary_to_hex(txToBroadcast.serialize()) -pprintHex(binary_to_hex(txToBroadcast.serialize())) diff --git a/qlabelbutton.py b/qlabelbutton.py deleted file mode 100644 index 6faa528eb..000000000 --- a/qlabelbutton.py +++ /dev/null @@ -1,9 +0,0 @@ -import sys -from PyQt4.QtCore import * -from PyQt4.QtGui import * -from qtdefines import * - -from armoryengine import * -from armorymodels import * - - diff --git a/qtdialogs.py b/qtdialogs.py index 085fc0e6d..474d3010a 100755 --- a/qtdialogs.py +++ b/qtdialogs.py @@ -1665,7 +1665,7 @@ def __init__(self, inputStr, outputStr, outVal, fee, parent=None, main=None): #frmLayout.addWidget(QRichLabel('Funds will be swept...'), 0,0, 1,2) frmLayout.addWidget(QRichLabel(' From ' + inputStr, doWrap=False), 1,0, 1,2) frmLayout.addWidget(QRichLabel(' To ' + outputStr, doWrap=False), 2,0, 1,2) - frmLayout.addWidget(QRichLabel(' Total %s BTC %s'%(outStr,feeStr), doWrap=False), 3,0, 1,2) + frmLayout.addWidget(QRichLabel(' Total %s BTC %s'%(outStr,feeStr), doWrap=False), 3,0, 1,2) frm.setLayout(frmLayout) lblFinalConfirm = QLabel('Are you sure you want to execute this transaction?') @@ -4754,7 +4754,7 @@ def saveTx(self): if not self.fileLoaded==None and self.enoughSigs and self.sigsValid: reply = QMessageBox.question(self,'Overwrite?', \ 'The signed transaction you are saving was originally loaded ' - 'from:\n\n%s\n\nWould you like to overwrite write it with this ' + 'from:\n\n%s\n\nWould you like to overwrite it with this ' 'signed transaction?' % self.fileLoaded, QMessageBox.Yes | QMessageBox.No) if reply==QMessageBox.Yes: newSaveFile = self.fileLoaded.replace('unsigned', 'signed') @@ -5561,8 +5561,8 @@ def __init__(self, pytx, wlt=None, parent=None, main=None, mode=None, \ self.txInView.verticalHeader().setDefaultSectionSize(20) self.txInView.verticalHeader().hide() w,h = tightSizeNChar(self.txInView, 1) - self.txInView.setMinimumHeight(2*(1.3*h)) - self.txInView.setMaximumHeight(5*(1.3*h)) + self.txInView.setMinimumHeight(2*(1.4*h)) + self.txInView.setMaximumHeight(5*(1.4*h)) self.txInView.hideColumn(TXINCOLS.OutPt) self.txInView.hideColumn(TXINCOLS.OutIdx) self.txInView.hideColumn(TXINCOLS.Script)