Bitcoin Forum
May 27, 2024, 05:54:02 PM *
News: Latest Bitcoin Core release: 27.0 [Torrent]
 
  Home Help Search Login Register More  
  Show Posts
Pages: « 1 ... 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 [123] 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 »
2441  Alternate cryptocurrencies / Altcoin Discussion / Re: PPCoin Criticism / Security / etc on: November 27, 2012, 07:12:53 PM
Relevant code changes to main.cpp

Code:
// ppcoin: miner's coin stake is rewarded based on coin age spent (coin-days)
int64 GetProofOfStakeReward(int64 nCoinAge)
{
    static int64 nRewardCoinYear = CENT;  // creation amount per coin-year
    int64 nSubsidy = nCoinAge * 33 / (365 * 33 + 8) * nRewardCoinYear;
    if (fDebug && GetBoolArg("-printcreation"))
        printf("GetProofOfStakeReward(): create=%s nCoinAge=%"PRI64d"\n", FormatMoney(nSubsidy).c_str(), nCoinAge);
    return nSubsidy;
}

static const int64 nTargetTimespan = 7 * 24 * 60 * 60;  // one week
static const int64 nTargetSpacingStake = 10 * 60;       // ten minutes
static const int64 nTargetSpacingWorkMax = 2 * 60 * 60; // two hours

Code:
unsigned int static GetNextTargetRequired(const CBlockIndex* pindexLast, bool fProofOfStake)
{
    if (pindexLast == NULL)
        return bnProofOfWorkLimit.GetCompact(); // genesis block

    const CBlockIndex* pindexPrev = GetLastBlockIndex(pindexLast, fProofOfStake);
    if (pindexPrev->pprev == NULL)
        return bnInitialHashTarget.GetCompact(); // first block
    const CBlockIndex* pindexPrevPrev = GetLastBlockIndex(pindexPrev->pprev, fProofOfStake);
    if (pindexPrevPrev->pprev == NULL)
        return bnInitialHashTarget.GetCompact(); // second block

    int64 nActualSpacing = pindexPrev->GetBlockTime() - pindexPrevPrev->GetBlockTime();

    // ppcoin: target change every block
    // ppcoin: retarget with exponential moving toward target spacing
    CBigNum bnNew;
    bnNew.SetCompact(pindexPrev->nBits);
    int64 nTargetSpacing = fProofOfStake? nTargetSpacingStake : min(nTargetSpacingWorkMax, nTargetSpacingStake * (1 + pindexLast->nHeight - pindexPrev->nHeight));
    int64 nInterval = nTargetTimespan / nTargetSpacing;
    bnNew *= ((nInterval - 1) * nTargetSpacing + nActualSpacing + nActualSpacing);
    bnNew /= ((nInterval + 1) * nTargetSpacing);

    if (bnNew > bnProofOfWorkLimit)
        bnNew = bnProofOfWorkLimit;

    return bnNew.GetCompact();
}

Code:
bool CTransaction::ConnectInputs(CTxDB& txdb, MapPrevTx inputs,
                                 map<uint256, CTxIndex>& mapTestPool, const CDiskTxPos& posThisTx,
                                 const CBlockIndex* pindexBlock, bool fBlock, bool fMiner, bool fStrictPayToScriptHash)
{
         ...
        if (IsCoinStake())
        {
            // ppcoin: coin stake tx earns reward instead of paying fee
            uint64 nCoinAge;
            if (!GetCoinAge(txdb, nCoinAge))
                return error("ConnectInputs() : %s unable to get coin age for coinstake", GetHash().ToString().substr(0,10).c_str());
            int64 nStakeReward = GetValueOut() - nValueIn;
            if (nStakeReward > GetProofOfStakeReward(nCoinAge) - GetMinFee() + MIN_TX_FEE)
                return DoS(100, error("ConnectInputs() : %s stake reward exceeded", GetHash().ToString().substr(0,10).c_str()));
        }
        else
        {
            if (nValueIn < GetValueOut())
                return DoS(100, error("ConnectInputs() : %s value in < value out", GetHash().ToString().substr(0,10).c_str()));

            // Tally transaction fees
            int64 nTxFee = nValueIn - GetValueOut();
            if (nTxFee < 0)
                return DoS(100, error("ConnectInputs() : %s nTxFee < 0", GetHash().ToString().substr(0,10).c_str()));
            // ppcoin: enforce transaction fees for every block
            if (nTxFee < GetMinFee())
                return fBlock? DoS(100, error("ConnectInputs() : %s not paying required fee=%s, paid=%s", GetHash().ToString().substr(0,10).c_str(), FormatMoney(GetMinFee()).c_str(), FormatMoney(nTxFee).c_str())) : false;
            nFees += nTxFee;
            if (!MoneyRange(nFees))
                return DoS(100, error("ConnectInputs() : nFees out of range"));
        }
    }

    return true;
}

Code:
// ppcoin: coinstake must meet hash target according to the protocol:
// kernel (input 0) must meet the formula
//     hash(nBits + txPrev.block.nTime + txPrev.offset + txPrev.nTime + txPrev.vout.n + nTime) < bnTarget * nCoinDay
// this ensures that the chance of getting a coinstake is proportional to the
// amount of coin age one owns.
// The reason this hash is chosen is the following:
//   nBits: encodes all past block timestamps, making computing hash in advance
//          more difficult
//   txPrev.block.nTime: prevent nodes from guessing a good timestamp to
//                       generate transaction for future advantage
//   txPrev.offset: offset of txPrev inside block, to reduce the chance of
//                  nodes generating coinstake at the same time
//   txPrev.nTime: reduce the chance of nodes generating coinstake at the same
//                 time
//   txPrev.vout.n: output number of txPrev, to reduce the chance of nodes
//                  generating coinstake at the same time
//   block/tx hash should not be used here as they can be generated in vast
//   quantities so as to generate blocks faster, degrading the system back into
//   a proof-of-work situation.
//
bool CTransaction::CheckProofOfStake(unsigned int nBits) const
{
    CBigNum bnTargetPerCoinDay;
    bnTargetPerCoinDay.SetCompact(nBits);
 
    if (!IsCoinStake())
        return true;

    // Kernel (input 0) must match the stake hash target per coin age (nBits)
    const CTxIn& txin = vin[0];

    // First try finding the previous transaction in database
    CTxDB txdb("r");
    CTransaction txPrev;
    CTxIndex txindex;
    if (!txPrev.ReadFromDisk(txdb, txin.prevout, txindex))
        return false;  // previous transaction not in main chain
    txdb.Close();
    if (nTime < txPrev.nTime)
        return false;  // Transaction timestamp violation

    // Verify signature
    if (!VerifySignature(txPrev, *this, 0, true, 0))
        return DoS(100, error("CheckProofOfStake() : VerifySignature failed on coinstake %s", GetHash().ToString().c_str()));

    // Read block header
    CBlock block;
    if (!block.ReadFromDisk(txindex.pos.nFile, txindex.pos.nBlockPos, false))
        return false; // unable to read block of previous transaction
    if (block.GetBlockTime() + nStakeMinAge > nTime)
        return false; // only count coins meeting min age requirement

    int64 nValueIn = txPrev.vout[txin.prevout.n].nValue;
    CBigNum bnCoinDay = CBigNum(nValueIn) * min(nTime-txPrev.nTime, (unsigned int)STAKE_MAX_AGE) / COIN / (24 * 60 * 60);
    // Calculate hash
    CDataStream ss(SER_GETHASH, 0);
    ss << nBits << block.nTime << (txindex.pos.nTxPos - txindex.pos.nBlockPos) << txPrev.nTime << txin.prevout.n << nTime;
    if (CBigNum(Hash(ss.begin(), ss.end())) <= bnCoinDay * bnTargetPerCoinDay)
        return true;
    else
        return DoS(100, error("CheckProofOfStake() : check target failed on coinstake %s", GetHash().ToString().c_str()));
}

// ppcoin: total coin age spent in transaction, in the unit of coin-days.
// Only those coins meeting minimum age requirement counts. As those
// transactions not in main chain are not currently indexed so we
// might not find out about their coin age. Older transactions are
// guaranteed to be in main chain by sync-checkpoint. This rule is
// introduced to help nodes establish a consistent view of the coin
// age (trust score) of competing branches.
bool CTransaction::GetCoinAge(CTxDB& txdb, uint64& nCoinAge) const
{
    CBigNum bnCentSecond = 0;  // coin age in the unit of cent-seconds
    nCoinAge = 0;

    if (IsCoinBase())
        return true;

    BOOST_FOREACH(const CTxIn& txin, vin)
    {
        // First try finding the previous transaction in database
        CTransaction txPrev;
        CTxIndex txindex;
        if (!txPrev.ReadFromDisk(txdb, txin.prevout, txindex))
            continue;  // previous transaction not in main chain
        if (nTime < txPrev.nTime)
            return false;  // Transaction timestamp violation

        // Read block header
        CBlock block;
        if (!block.ReadFromDisk(txindex.pos.nFile, txindex.pos.nBlockPos, false))
            return false; // unable to read block of previous transaction
        if (block.GetBlockTime() + nStakeMinAge > nTime)
            continue; // only count coins meeting min age requirement

        int64 nValueIn = txPrev.vout[txin.prevout.n].nValue;
        bnCentSecond += CBigNum(nValueIn) * (nTime-txPrev.nTime) / CENT;

        if (fDebug && GetBoolArg("-printcoinage"))
            printf("coin age nValueIn=%-12I64d nTimeDiff=%d bnCentSecond=%s\n", nValueIn, nTime - txPrev.nTime, bnCentSecond.ToString().c_str());
    }

    CBigNum bnCoinDay = bnCentSecond * CENT / COIN / (24 * 60 * 60);
    if (fDebug && GetBoolArg("-printcoinage"))
        printf("coin age bnCoinDay=%s\n", bnCoinDay.ToString().c_str());
    nCoinAge = bnCoinDay.getuint64();
    return true;
}

// ppcoin: total coin age spent in block, in the unit of coin-days.
bool CBlock::GetCoinAge(uint64& nCoinAge) const
{
    nCoinAge = 0;

    CTxDB txdb("r");
    BOOST_FOREACH(const CTransaction& tx, vtx)
    {
        uint64 nTxCoinAge;
        if (tx.GetCoinAge(txdb, nTxCoinAge))
            nCoinAge += nTxCoinAge;
        else
            return false;
    }

    if (nCoinAge == 0) // block coin age minimum 1 coin-day
        nCoinAge = 1;
    if (fDebug && GetBoolArg("-printcoinage"))
        printf("block coin age total nCoinDays=%"PRI64d"\n", nCoinAge);
    return true;
}


bool CBlock::AddToBlockIndex(unsigned int nFile, unsigned int nBlockPos)
{
    // Check for duplicate
    uint256 hash = GetHash();
    if (mapBlockIndex.count(hash))
        return error("AddToBlockIndex() : %s already exists", hash.ToString().substr(0,20).c_str());

    // Construct new block index object
    CBlockIndex* pindexNew = new CBlockIndex(nFile, nBlockPos, *this);
    if (!pindexNew)
        return error("AddToBlockIndex() : new CBlockIndex failed");
    map<uint256, CBlockIndex*>::iterator mi = mapBlockIndex.insert(make_pair(hash, pindexNew)).first;
    if (pindexNew->fProofOfStake)
        setStakeSeen.insert(make_pair(pindexNew->prevoutStake, pindexNew->nStakeTime));

    pindexNew->phashBlock = &((*mi).first);
    map<uint256, CBlockIndex*>::iterator miPrev = mapBlockIndex.find(hashPrevBlock);
    if (miPrev != mapBlockIndex.end())
    {
        pindexNew->pprev = (*miPrev).second;
        pindexNew->nHeight = pindexNew->pprev->nHeight + 1;
    }

    // ppcoin: compute chain trust score
    pindexNew->bnChainTrust = (pindexNew->pprev ? pindexNew->pprev->bnChainTrust : 0) + pindexNew->GetBlockTrust();

    CTxDB txdb;
    if (!txdb.TxnBegin())
        return false;
    txdb.WriteBlockIndex(CDiskBlockIndex(pindexNew));
    if (!txdb.TxnCommit())
        return false;

    // New best
    if (pindexNew->bnChainTrust > bnBestChainTrust)
        if (!SetBestChain(txdb, pindexNew))
            return false;

    txdb.Close();

    if (pindexNew == pindexBest)
    {
        // Notify UI to display prev block's coinbase if it was ours
        static uint256 hashPrevBestCoinBase;
        UpdatedTransaction(hashPrevBestCoinBase);
        hashPrevBestCoinBase = vtx[0].GetHash();
    }

    MainFrameRepaint();
    return true;
}




bool CBlock::CheckBlock() const
{
    // These are checks that are independent of context
    // that can be verified before saving an orphan block.

    // Size limits
    if (vtx.empty() || vtx.size() > MAX_BLOCK_SIZE || ::GetSerializeSize(*this, SER_NETWORK, PROTOCOL_VERSION) > MAX_BLOCK_SIZE)
        return DoS(100, error("CheckBlock() : size limits failed"));

    // Check proof of work matches claimed amount
    if (IsProofOfWork() && !CheckProofOfWork(GetHash(), nBits))
        return DoS(50, error("CheckBlock() : proof of work failed"));

    // Check timestamp
    if (GetBlockTime() > GetAdjustedTime() + nMaxClockDrift)
        return error("CheckBlock() : block timestamp too far in the future");

    // First transaction must be coinbase, the rest must not be
    if (vtx.empty() || !vtx[0].IsCoinBase())
        return DoS(100, error("CheckBlock() : first tx is not coinbase"));
    for (unsigned int i = 1; i < vtx.size(); i++)
        if (vtx[i].IsCoinBase())
            return DoS(100, error("CheckBlock() : more than one coinbase"));

    // ppcoin: only the second transaction can be the optional coinstake
    for (int i = 2; i < vtx.size(); i++)
        if (vtx[i].IsCoinStake())
            return DoS(100, error("CheckBlock() : coinstake in wrong position"));

    // ppcoin: coinbase output should be empty if proof-of-stake block
    if (IsProofOfStake() && (vtx[0].vout.size() != 1 || !vtx[0].vout[0].IsEmpty()))
        return error("CheckBlock() : coinbase output not empty for proof-of-stake block");

    // Check coinbase timestamp
    if (GetBlockTime() > (int64)vtx[0].nTime + nMaxClockDrift)
        return DoS(50, error("CheckBlock() : coinbase timestamp is too early"));

    // Check coinstake timestamp
    if (IsProofOfStake() && GetBlockTime() > (int64)vtx[1].nTime + nMaxClockDrift)
        return DoS(50, error("CheckBlock() : coinstake timestamp is too early"));

    // Check coinbase reward
    if (vtx[0].GetValueOut() > (IsProofOfWork()? (GetProofOfWorkReward(nBits) - vtx[0].GetMinFee() + MIN_TX_FEE) : 0))
        return DoS(50, error("CheckBlock() : coinbase reward exceeded %s > %s",
                   FormatMoney(vtx[0].GetValueOut()).c_str(),
                   FormatMoney(IsProofOfWork()? GetProofOfWorkReward(nBits) : 0).c_str()));

    // Check transactions
    BOOST_FOREACH(const CTransaction& tx, vtx)
    {
        if (!tx.CheckTransaction())
            return DoS(tx.nDoS, error("CheckBlock() : CheckTransaction failed"));
        // ppcoin: check transaction timestamp
        if (GetBlockTime() < (int64)tx.nTime)
            return DoS(50, error("CheckBlock() : block timestamp earlier than transaction timestamp"));
    }

    // Check for duplicate txids. This is caught by ConnectInputs(),
    // but catching it earlier avoids a potential DoS attack:
    set<uint256> uniqueTx;
    BOOST_FOREACH(const CTransaction& tx, vtx)
    {
        uniqueTx.insert(tx.GetHash());
    }
    if (uniqueTx.size() != vtx.size())
        return DoS(100, error("CheckBlock() : duplicate transaction"));

    unsigned int nSigOps = 0;
    BOOST_FOREACH(const CTransaction& tx, vtx)
    {
        nSigOps += tx.GetLegacySigOpCount();
    }
    if (nSigOps > MAX_BLOCK_SIGOPS)
        return DoS(100, error("CheckBlock() : out-of-bounds SigOpCount"));

    // Check merkleroot
    if (hashMerkleRoot != BuildMerkleTree())
        return DoS(100, error("CheckBlock() : hashMerkleRoot mismatch"));

    // ppcoin: check block signature
    if (!CheckBlockSignature())
        return DoS(100, error("CheckBlock() : bad block signature"));

    return true;
}

bool CBlock::AcceptBlock()
{
    // Check for duplicate
    uint256 hash = GetHash();
    if (mapBlockIndex.count(hash))
        return error("AcceptBlock() : block already in mapBlockIndex");

    // Get prev block index
    map<uint256, CBlockIndex*>::iterator mi = mapBlockIndex.find(hashPrevBlock);
    if (mi == mapBlockIndex.end())
        return DoS(10, error("AcceptBlock() : prev block not found"));
    CBlockIndex* pindexPrev = (*mi).second;
    int nHeight = pindexPrev->nHeight+1;

    // Check proof-of-work or proof-of-stake
    if (nBits != GetNextTargetRequired(pindexPrev, IsProofOfStake()))
        return DoS(100, error("AcceptBlock() : incorrect proof-of-work/proof-of-stake"));

    // Check timestamp against prev
    if (GetBlockTime() <= pindexPrev->GetMedianTimePast() || GetBlockTime() + nMaxClockDrift < pindexPrev->GetBlockTime())
        return error("AcceptBlock() : block's timestamp is too early");

    // Check that all transactions are finalized
    BOOST_FOREACH(const CTransaction& tx, vtx)
        if (!tx.IsFinal(nHeight, GetBlockTime()))
            return DoS(10, error("AcceptBlock() : contains a non-final transaction"));

    // Check that the block chain matches the known block chain up to a hardened checkpoint
    if (!Checkpoints::CheckHardened(nHeight, hash))
        return DoS(100, error("AcceptBlock() : rejected by hardened checkpoint lockin at %d", nHeight));

    // ppcoin: check that the block satisfies synchronized checkpoint
    if (!Checkpoints::CheckSync(hash, pindexPrev))
        return error("AcceptBlock() : rejected by synchronized checkpoint");

    // Write block to history file
    if (!CheckDiskSpace(::GetSerializeSize(*this, SER_DISK, CLIENT_VERSION)))
        return error("AcceptBlock() : out of disk space");
    unsigned int nFile = -1;
    unsigned int nBlockPos = 0;
    if (!WriteToDisk(nFile, nBlockPos))
        return error("AcceptBlock() : WriteToDisk failed");
    if (!AddToBlockIndex(nFile, nBlockPos))
        return error("AcceptBlock() : AddToBlockIndex failed");

    // Relay inventory, but don't relay old inventory during initial block download
    int nBlockEstimate = Checkpoints::GetTotalBlocksEstimate();
    if (hashBestChain == hash)
    {
        LOCK(cs_vNodes);
        BOOST_FOREACH(CNode* pnode, vNodes)
            if (nBestHeight > (pnode->nStartingHeight != -1 ? pnode->nStartingHeight - 2000 : nBlockEstimate))
                pnode->PushInventory(CInv(MSG_BLOCK, hash));
    }

    // ppcoin: check pending sync-checkpoint
    Checkpoints::AcceptPendingSyncCheckpoint();

    return true;
}

bool ProcessBlock(CNode* pfrom, CBlock* pblock)
{
    // Check for duplicate
    uint256 hash = pblock->GetHash();
    if (mapBlockIndex.count(hash))
        return error("ProcessBlock() : already have block %d %s", mapBlockIndex[hash]->nHeight, hash.ToString().substr(0,20).c_str());
    if (mapOrphanBlocks.count(hash))
        return error("ProcessBlock() : already have block (orphan) %s", hash.ToString().substr(0,20).c_str());

    // ppcoin: check proof-of-stake
    // Limited duplicity on stake: prevents block flood attack
    // Duplicate stake allowed only when there is orphan child block
    if (pblock->IsProofOfStake() && setStakeSeen.count(pblock->GetProofOfStake()) && !mapOrphanBlocksByPrev.count(hash) && !Checkpoints::WantedByPendingSyncCheckpoint(hash))
        return error("ProcessBlock() : duplicate proof-of-stake (%s, %d) for block %s", pblock->GetProofOfStake().first.ToString().c_str(), pblock->GetProofOfStake().second, hash.ToString().c_str());

    // Preliminary checks
    if (!pblock->CheckBlock())
        return error("ProcessBlock() : CheckBlock FAILED");

    // ppcoin: verify hash target and signature of coinstake tx
    if (pblock->IsProofOfStake() && !pblock->vtx[1].CheckProofOfStake(pblock->nBits))
    {
        printf("WARNING: ProcessBlock(): check proof-of-stake failed for block %s\n", hash.ToString().c_str());
        return false; // do not error here as we expect this during initial block download
    }

    CBlockIndex* pcheckpoint = Checkpoints::GetLastSyncCheckpoint();
    if (pcheckpoint && pblock->hashPrevBlock != hashBestChain && !Checkpoints::WantedByPendingSyncCheckpoint(hash))
    {
        // Extra checks to prevent "fill up memory by spamming with bogus blocks"
        int64 deltaTime = pblock->GetBlockTime() - pcheckpoint->nTime;
        CBigNum bnNewBlock;
        bnNewBlock.SetCompact(pblock->nBits);
        CBigNum bnRequired;
        bnRequired.SetCompact(ComputeMinWork(GetLastBlockIndex(pcheckpoint, pblock->IsProofOfStake())->nBits, deltaTime));

        if (bnNewBlock > bnRequired)
        {
            if (pfrom)
                pfrom->Misbehaving(100);
            return error("ProcessBlock() : block with too little %s", pblock->IsProofOfStake()? "proof-of-stake" : "proof-of-work");
        }
    }

    // ppcoin: ask for pending sync-checkpoint if any
    if (!IsInitialBlockDownload())
        Checkpoints::AskForPendingSyncCheckpoint(pfrom);

    // If don't already have its previous block, shunt it off to holding area until we get it
    if (!mapBlockIndex.count(pblock->hashPrevBlock))
    {
        printf("ProcessBlock: ORPHAN BLOCK, prev=%s\n", pblock->hashPrevBlock.ToString().substr(0,20).c_str());
        CBlock* pblock2 = new CBlock(*pblock);
        // ppcoin: check proof-of-stake
        if (pblock2->IsProofOfStake())
        {
            // Limited duplicity on stake: prevents block flood attack
            // Duplicate stake allowed only when there is orphan child block
            if (setStakeSeenOrphan.count(pblock2->GetProofOfStake()) && !mapOrphanBlocksByPrev.count(hash) && !Checkpoints::WantedByPendingSyncCheckpoint(hash))
                return error("ProcessBlock() : duplicate proof-of-stake (%s, %d) for orphan block %s", pblock2->GetProofOfStake().first.ToString().c_str(), pblock2->GetProofOfStake().second, hash.ToString().c_str());
            else
                setStakeSeenOrphan.insert(pblock2->GetProofOfStake());
        }
        mapOrphanBlocks.insert(make_pair(hash, pblock2));
        mapOrphanBlocksByPrev.insert(make_pair(pblock2->hashPrevBlock, pblock2));

        // Ask this guy to fill in what we're missing
        if (pfrom)
        {
            pfrom->PushGetBlocks(pindexBest, GetOrphanRoot(pblock2));
            // ppcoin: getblocks may not obtain the ancestor block rejected
            // earlier by duplicate-stake check so we ask for it again directly
            if (!IsInitialBlockDownload())
                pfrom->AskFor(CInv(MSG_BLOCK, WantedByOrphan(pblock2)));
        }
        return true;
    }

    // Store to disk
    if (!pblock->AcceptBlock())
        return error("ProcessBlock() : AcceptBlock FAILED");

    // Recursively process any orphan blocks that depended on this one
    vector<uint256> vWorkQueue;
    vWorkQueue.push_back(hash);
    for (unsigned int i = 0; i < vWorkQueue.size(); i++)
    {
        uint256 hashPrev = vWorkQueue[i];
        for (multimap<uint256, CBlock*>::iterator mi = mapOrphanBlocksByPrev.lower_bound(hashPrev);
             mi != mapOrphanBlocksByPrev.upper_bound(hashPrev);
             ++mi)
        {
            CBlock* pblockOrphan = (*mi).second;
            if (pblockOrphan->AcceptBlock())
                vWorkQueue.push_back(pblockOrphan->GetHash());
            mapOrphanBlocks.erase(pblockOrphan->GetHash());
            setStakeSeenOrphan.erase(pblockOrphan->GetProofOfStake());
            delete pblockOrphan;
        }
        mapOrphanBlocksByPrev.erase(hashPrev);
    }

    printf("ProcessBlock: ACCEPTED\n");

    // ppcoin: if responsible for sync-checkpoint send it
    if (pfrom && !CSyncCheckpoint::strMasterPrivKey.empty())
        Checkpoints::SendSyncCheckpoint(Checkpoints::AutoSelectSyncCheckpoint());

    return true;
}

// ppcoin: sign block
bool CBlock::SignBlock(const CKeyStore& keystore)
{
    vector<valtype> vSolutions;
    txnouttype whichType;
    const CTxOut& txout = IsProofOfStake()? vtx[1].vout[1] : vtx[0].vout[0];

    if (!Solver(txout.scriptPubKey, whichType, vSolutions))
        return false;
    if (whichType == TX_PUBKEY)
    {
        // Sign
        const valtype& vchPubKey = vSolutions[0];
        CKey key;
        if (!keystore.GetKey(Hash160(vchPubKey), key))
            return false;
        if (key.GetPubKey() != vchPubKey)
            return false;
        return key.Sign(GetHash(), vchBlockSig);
    }
    return false;
}

// ppcoin: check block signature
bool CBlock::CheckBlockSignature() const
{
    if (GetHash() == hashGenesisBlock)
        return vchBlockSig.empty();

    vector<valtype> vSolutions;
    txnouttype whichType;
    const CTxOut& txout = IsProofOfStake()? vtx[1].vout[1] : vtx[0].vout[0];

    if (!Solver(txout.scriptPubKey, whichType, vSolutions))
        return false;
    if (whichType == TX_PUBKEY)
    {
        const valtype& vchPubKey = vSolutions[0];
        CKey key;
        if (!key.SetPubKey(vchPubKey))
            return false;
        if (vchBlockSig.empty())
            return false;
        return key.Verify(GetHash(), vchBlockSig);
    }
    return false;
}

Code:
// CreateNewBlock:
//   fProofOfStake: try (best effort) to make a proof-of-stake block
CBlock* CreateNewBlock(CWallet* pwallet, bool fProofOfStake)
{
    CReserveKey reservekey(pwallet);

    // Create new block
    auto_ptr<CBlock> pblock(new CBlock());
    if (!pblock.get())
        return NULL;

    // Create coinbase tx
    CTransaction txNew;
    txNew.vin.resize(1);
    txNew.vin[0].prevout.SetNull();
    txNew.vout.resize(1);
    txNew.vout[0].scriptPubKey << reservekey.GetReservedKey() << OP_CHECKSIG;

    // Add our coinbase tx as first transaction
    pblock->vtx.push_back(txNew);

    // ppcoin: if coinstake available add coinstake tx
    static int64 nLastCoinStakeSearchTime = GetAdjustedTime();  // only initialized at startup
    CBlockIndex* pindexPrev = pindexBest;

    if (fProofOfStake)  // attemp to find a coinstake
    {
        pblock->nBits = GetNextTargetRequired(pindexPrev, true);
        CTransaction txCoinStake;
        int64 nSearchTime = GetAdjustedTime();
        if (nSearchTime > nLastCoinStakeSearchTime)
        {
            if (pwallet->CreateCoinStake(*pwallet, pblock->nBits, nSearchTime-nLastCoinStakeSearchTime, txCoinStake))
            {
                pblock->vtx.push_back(txCoinStake);
                pblock->vtx[0].vout[0].SetEmpty();
            }
            nLastCoinStakeSearchInterval = nSearchTime - nLastCoinStakeSearchTime;
            nLastCoinStakeSearchTime = nSearchTime;
        }
    }

    pblock->nBits = GetNextTargetRequired(pindexPrev, pblock->IsProofOfStake());

    // Collect memory pool transactions into the block
    int64 nFees = 0;
    {
        LOCK2(cs_main, mempool.cs);
        CTxDB txdb("r");

        // Priority order to process transactions
        list<COrphan> vOrphan; // list memory doesn't move
        map<uint256, vector<COrphan*> > mapDependers;
        multimap<double, CTransaction*> mapPriority;
        for (map<uint256, CTransaction>::iterator mi = mempool.mapTx.begin(); mi != mempool.mapTx.end(); ++mi)
        {
            CTransaction& tx = (*mi).second;
            if (tx.IsCoinBase() || tx.IsCoinStake() || !tx.IsFinal())
                continue;

            COrphan* porphan = NULL;
            double dPriority = 0;
            BOOST_FOREACH(const CTxIn& txin, tx.vin)
            {
                // Read prev transaction
                CTransaction txPrev;
                CTxIndex txindex;
                if (!txPrev.ReadFromDisk(txdb, txin.prevout, txindex))
                {
                    // Has to wait for dependencies
                    if (!porphan)
                    {
                        // Use list for automatic deletion
                        vOrphan.push_back(COrphan(&tx));
                        porphan = &vOrphan.back();
                    }
                    mapDependers[txin.prevout.hash].push_back(porphan);
                    porphan->setDependsOn.insert(txin.prevout.hash);
                    continue;
                }
                int64 nValueIn = txPrev.vout[txin.prevout.n].nValue;

                // Read block header
                int nConf = txindex.GetDepthInMainChain();

                dPriority += (double)nValueIn * nConf;

                if (fDebug && GetBoolArg("-printpriority"))
                    printf("priority     nValueIn=%-12"PRI64d" nConf=%-5d dPriority=%-20.1f\n", nValueIn, nConf, dPriority);
            }

            // Priority is sum(valuein * age) / txsize
            dPriority /= ::GetSerializeSize(tx, SER_NETWORK, PROTOCOL_VERSION);

            if (porphan)
                porphan->dPriority = dPriority;
            else
                mapPriority.insert(make_pair(-dPriority, &(*mi).second));

            if (fDebug && GetBoolArg("-printpriority"))
            {
                printf("priority %-20.1f %s\n%s", dPriority, tx.GetHash().ToString().substr(0,10).c_str(), tx.ToString().c_str());
                if (porphan)
                    porphan->print();
                printf("\n");
            }
        }

        // Collect transactions into block
        map<uint256, CTxIndex> mapTestPool;
        uint64 nBlockSize = 1000;
        uint64 nBlockTx = 0;
        int nBlockSigOps = 100;
        while (!mapPriority.empty())
        {
            // Take highest priority transaction off priority queue
            CTransaction& tx = *(*mapPriority.begin()).second;
            mapPriority.erase(mapPriority.begin());

            // Size limits
            unsigned int nTxSize = ::GetSerializeSize(tx, SER_NETWORK, PROTOCOL_VERSION);
            if (nBlockSize + nTxSize >= MAX_BLOCK_SIZE_GEN)
                continue;

            // Legacy limits on sigOps:
            unsigned int nTxSigOps = tx.GetLegacySigOpCount();
            if (nBlockSigOps + nTxSigOps >= MAX_BLOCK_SIGOPS)
                continue;

            // Timestamp limit
            if (tx.nTime > GetAdjustedTime())
                continue;

            // ppcoin: simplify transaction fee - allow free = false
            int64 nMinFee = tx.GetMinFee(nBlockSize, false, GMF_BLOCK);

            // Connecting shouldn't fail due to dependency on other memory pool transactions
            // because we're already processing them in order of dependency
            map<uint256, CTxIndex> mapTestPoolTmp(mapTestPool);
            MapPrevTx mapInputs;
            bool fInvalid;
            if (!tx.FetchInputs(txdb, mapTestPoolTmp, false, true, mapInputs, fInvalid))
                continue;

            int64 nTxFees = tx.GetValueIn(mapInputs)-tx.GetValueOut();
            if (nTxFees < nMinFee)
                continue;

            nTxSigOps += tx.GetP2SHSigOpCount(mapInputs);
            if (nBlockSigOps + nTxSigOps >= MAX_BLOCK_SIGOPS)
                continue;

            if (!tx.ConnectInputs(txdb, mapInputs, mapTestPoolTmp, CDiskTxPos(1,1,1), pindexPrev, false, true))
                continue;
            mapTestPoolTmp[tx.GetHash()] = CTxIndex(CDiskTxPos(1,1,1), tx.vout.size());
            swap(mapTestPool, mapTestPoolTmp);

            // Added
            pblock->vtx.push_back(tx);
            nBlockSize += nTxSize;
            ++nBlockTx;
            nBlockSigOps += nTxSigOps;
            nFees += nTxFees;

            // Add transactions that depend on this one to the priority queue
            uint256 hash = tx.GetHash();
            if (mapDependers.count(hash))
            {
                BOOST_FOREACH(COrphan* porphan, mapDependers[hash])
                {
                    if (!porphan->setDependsOn.empty())
                    {
                        porphan->setDependsOn.erase(hash);
                        if (porphan->setDependsOn.empty())
                            mapPriority.insert(make_pair(-porphan->dPriority, porphan->ptx));
                    }
                }
            }
        }

        nLastBlockTx = nBlockTx;
        nLastBlockSize = nBlockSize;
        if (fDebug && GetBoolArg("-printpriority"))
            printf("CreateNewBlock(): total size %lu\n", nBlockSize);

    }
    if (pblock->IsProofOfWork())
        pblock->vtx[0].vout[0].nValue = GetProofOfWorkReward(pblock->nBits);

    // Fill in header
    pblock->hashPrevBlock  = pindexPrev->GetBlockHash();
    pblock->hashMerkleRoot = pblock->BuildMerkleTree();
    pblock->nTime          = max(pindexPrev->GetMedianTimePast()+1, pblock->GetMaxTransactionTime());
    pblock->nTime          = max(pblock->GetBlockTime(), pindexPrev->GetBlockTime() - nMaxClockDrift);
    pblock->UpdateTime(pindexPrev);
    pblock->nNonce         = 0;

    return pblock.release();
}


void IncrementExtraNonce(CBlock* pblock, CBlockIndex* pindexPrev, unsigned int& nExtraNonce)
{
    // Update nExtraNonce
    static uint256 hashPrevBlock;
    if (hashPrevBlock != pblock->hashPrevBlock)
    {
        nExtraNonce = 0;
        hashPrevBlock = pblock->hashPrevBlock;
    }
    ++nExtraNonce;
    pblock->vtx[0].vin[0].scriptSig = (CScript() << pblock->nTime << CBigNum(nExtraNonce)) + COINBASE_FLAGS;
    assert(pblock->vtx[0].vin[0].scriptSig.size() <= 100);

    pblock->hashMerkleRoot = pblock->BuildMerkleTree();
}
Code:
void BitcoinMiner(CWallet *pwallet, bool fProofOfStake)
{
    printf("CPUMiner started for proof-of-%s\n", fProofOfStake? "stake" : "work");
    SetThreadPriority(THREAD_PRIORITY_LOWEST);

    // Each thread has its own key and counter
    CReserveKey reservekey(pwallet);
    unsigned int nExtraNonce = 0;

    while (fGenerateBitcoins || fProofOfStake)
    {
        if (fShutdown)
            return;
        while (vNodes.empty() || IsInitialBlockDownload())
        {
            Sleep(1000);
            if (fShutdown)
                return;
            if ((!fGenerateBitcoins) && !fProofOfStake)
                return;
        }

        while (pwallet->IsLocked())
        {
            strMintWarning = strMintMessage;
            Sleep(1000);
        }
        strMintWarning = "";

        //
        // Create new block
        //
        unsigned int nTransactionsUpdatedLast = nTransactionsUpdated;
        CBlockIndex* pindexPrev = pindexBest;

        auto_ptr<CBlock> pblock(CreateNewBlock(pwallet, fProofOfStake));
        if (!pblock.get())
            return;

        IncrementExtraNonce(pblock.get(), pindexPrev, nExtraNonce);

        if (fProofOfStake)
        {
            // ppcoin: if proof-of-stake block found then process block
            if (pblock->IsProofOfStake())
            {
                if (!pblock->SignBlock(*pwalletMain))
                {
                    strMintWarning = strMintMessage;
                    continue;
                }
                strMintWarning = "";
                printf("CPUMiner : proof-of-stake block found %s\n", pblock->GetHash().ToString().c_str());
                SetThreadPriority(THREAD_PRIORITY_NORMAL);
                CheckWork(pblock.get(), *pwalletMain, reservekey);
                SetThreadPriority(THREAD_PRIORITY_LOWEST);
            }
            Sleep(500);
            continue;
        }

        printf("Running BitcoinMiner with %d transactions in block\n", pblock->vtx.size());


        //
        // Prebuild hash buffers
        //
        char pmidstatebuf[32+16]; char* pmidstate = alignup<16>(pmidstatebuf);
        char pdatabuf[128+16];    char* pdata     = alignup<16>(pdatabuf);
        char phash1buf[64+16];    char* phash1    = alignup<16>(phash1buf);

        FormatHashBuffers(pblock.get(), pmidstate, pdata, phash1);

        unsigned int& nBlockTime = *(unsigned int*)(pdata + 64 + 4);
        unsigned int& nBlockNonce = *(unsigned int*)(pdata + 64 + 12);


        //
        // Search
        //
        int64 nStart = GetTime();
        uint256 hashTarget = CBigNum().SetCompact(pblock->nBits).getuint256();
        uint256 hashbuf[2];
        uint256& hash = *alignup<16>(hashbuf);
        loop
        {
            unsigned int nHashesDone = 0;
            unsigned int nNonceFound;

            // Crypto++ SHA-256
            nNonceFound = ScanHash_CryptoPP(pmidstate, pdata + 64, phash1,
                                            (char*)&hash, nHashesDone);

            // Check if something found
            if (nNonceFound != (unsigned int) -1)
            {
                for (unsigned int i = 0; i < sizeof(hash)/4; i++)
                    ((unsigned int*)&hash)[i] = ByteReverse(((unsigned int*)&hash)[i]);

                if (hash <= hashTarget)
                {
                    // Found a solution
                    pblock->nNonce = ByteReverse(nNonceFound);
                    assert(hash == pblock->GetHash());
                    if (!pblock->SignBlock(*pwalletMain))
                    {
                        strMintWarning = strMintMessage;
                        break;
                    }
                    strMintWarning = "";
                    SetThreadPriority(THREAD_PRIORITY_NORMAL);
                    CheckWork(pblock.get(), *pwalletMain, reservekey);
                    SetThreadPriority(THREAD_PRIORITY_LOWEST);
                    break;
                }
            }

            // Meter hashes/sec
            static int64 nHashCounter;
            if (nHPSTimerStart == 0)
            {
                nHPSTimerStart = GetTimeMillis();
                nHashCounter = 0;
            }
            else
                nHashCounter += nHashesDone;
            if (GetTimeMillis() - nHPSTimerStart > 4000)
            {
                static CCriticalSection cs;
                {
                    LOCK(cs);
                    if (GetTimeMillis() - nHPSTimerStart > 4000)
                    {
                        dHashesPerSec = 1000.0 * nHashCounter / (GetTimeMillis() - nHPSTimerStart);
                        nHPSTimerStart = GetTimeMillis();
                        nHashCounter = 0;
                        static int64 nLogTime;
                        if (GetTime() - nLogTime > 30 * 60)
                        {
                            nLogTime = GetTime();
                            printf("%s ", DateTimeStrFormat(GetTime()).c_str());
                            printf("hashmeter %3d CPUs %6.0f khash/s\n", vnThreadsRunning[THREAD_MINER], dHashesPerSec/1000.0);
                        }
                    }
                }
            }

            // Check for stop or if block needs to be rebuilt
            if (fShutdown)
                return;
            if (!fGenerateBitcoins)
                return;
            if (fLimitProcessors && vnThreadsRunning[THREAD_MINER] > nLimitProcessors)
                return;
            if (vNodes.empty())
                break;
            if (nBlockNonce >= 0xffff0000)
                break;
            if (nTransactionsUpdated != nTransactionsUpdatedLast && GetTime() - nStart > 60)
                break;
            if (pindexPrev != pindexBest)
                break;

            // Update nTime every few seconds
            pblock->nTime = max(pindexPrev->GetMedianTimePast()+1, pblock->GetMaxTransactionTime());
            pblock->nTime = max(pblock->GetBlockTime(), pindexPrev->GetBlockTime() - nMaxClockDrift);
            pblock->UpdateTime(pindexPrev);
            nBlockTime = ByteReverse(pblock->nTime);
            if (pblock->GetBlockTime() >= (int64)pblock->vtx[0].nTime + nMaxClockDrift)
                break;  // need to update coinbase timestamp
        }
    }
}


There are also lots of curious "stake connection tests," which may or may not indicate the aforementioned centralized nature of this PoS method.

Stake blocks are always difficulty 1 and nonce zero.  Apparently the blockchain is programmed to always accept them as valid as long as a certain quantity of network time has passed and the quantity for which they are valid is predestined by the code included.

For whatever reason Sunny King decided not to bother publishing the pseudocode implementation of his algorithms in favour of the epic LaTeX narrative of his implementation, but if there are vulnerabilities you should be able to see them in the above code.
2442  Other / Off-topic / Re: Already delays in BFL shipment plans? on: November 27, 2012, 05:17:56 PM
Answer: a small boutique fab. You know, like the one Inaba boasted BFL was using because small boutique fabs supposedly offered a much better, more personal service than the mass-produced crap from companies like TSMC.

If they'd used TSMC or GF 5 months ago we'd already have ASICs from them by now
2443  Alternate cryptocurrencies / Mining (Altcoins) / Re: Consolidated Litecoin Mining Guide for 5xxx, 6xxx, and 7xxx GPUs on: November 26, 2012, 04:40:53 PM
I just tested it out on 3 5970s with 8Gb RAM on the mobo, windows 7:

When I used --shaders 1600, I got 10-15Kh each core.
When I used --thread-concurrency 7168, I got almost 300Kh each core!!

So maybe this was my problem earlier! Thanks a lot Tacotime... I should of payed more attention to your OP!

I am still testing things out, but I will ship that bounty your way if this keeps working as is.

According to my task manager, I am only using 1.32Gb RAM for 3 5970s + the operating system... this seems really low. I'm going to test out smaller RAM amounts.

EDIT: I'm getting the same speeds (~300 Kh per core) using only 2Gb RAM, hooray! It seems to be using under 1 Gb RAM now, so I could probably add another 5970 with no problems. I don't have time to test right now though. You tha man, tacotime, whats your BTC address?

17bmYcP6Vio6c1gnyPsaDSv4B11SLe81Ab

Thanks C:

You shouldn't need a lot of RAM for cgminer, it offloads it to the GPU unlike reaper which for some odd reason keeps it in the system RAM.  reaper is coded really sloppily while cgminer is pretty immaculate.

You can probably optimize it further by trying some thread concurrencies between 5000-8000, I'm not sure 100% what the fastest is for 5970s.  You should get ~350kh/s per core depending on your clocks.  Just make sure to have your memory speeds high enough, my 6970 prefers mem speeds 20-30% faster than core speeds.

You can also try -g 2, although threads_per_gpu never seems to make a difference for me
2444  Other / CPU/GPU Bitcoin mining hardware / Re: Lowest temperature for hard drives? on: November 26, 2012, 04:47:21 AM
I'm in North Alberta

Okay, thanks.  I guess I'll have to wrap some kind of insulating material around it to keep it warm.  Hopefully the motherboard won't cold bug at those temps either (right now the northbridge is 30C and the memory is 12C).
2445  Other / CPU/GPU Bitcoin mining hardware / Lowest temperature for hard drives? on: November 26, 2012, 04:29:32 AM
My rigs are outside here.  Right now it's -24C outside and my rig's hard drive is running at 16C (my CPU amazingly is at 12C).

My question whether or not the hard drive will stop working below a certain temperature?  It's get into -40 to -50C here and it's possible that the HDD temperature will go below 0C.

Also at what temperature do brushless fans (on the video cards/CPU) generally stop working?
2446  Alternate cryptocurrencies / Altcoin Discussion / Re: Test ASIC's on Terracoin? on: November 25, 2012, 07:00:13 PM
ASICs will work on both PPC and TRC, as they use the same algorithm (2x rounds of SHA256) as bitcoin.
2447  Alternate cryptocurrencies / Altcoin Discussion / Re: Litecoin price headed down on: November 25, 2012, 05:52:49 AM
Personally, I think things will be pretty fun when blockreward of bitcoin halves in a few days and blockreward of litecoin doesn't.
2448  Economy / Goods / Re: buprenorphine, testosterone, xanax, valium- no prescription no rx on: November 24, 2012, 05:10:55 PM
Oh, you're back.  What're your prices like for finasteride?

Flaxceed is legit.  Just ask CarrotTop.  Cheesy
2449  Alternate cryptocurrencies / Mining (Altcoins) / Re: [ANN][LTC][Pool][PPLNS] - ltc.kattare.com - burnside's Litecoin Mining Pool on: November 24, 2012, 06:20:31 AM
hi,

thread_concurrency or mem/gpu speed settings are wrong

follow the guide here: https://bitcointalk.org/index.php?topic=117221.0
2450  Alternate cryptocurrencies / Mining (Altcoins) / Re: Consolidated Litecoin Mining Guide for 5xxx, 6xxx, and 7xxx GPUs on: November 23, 2012, 10:42:29 PM
Use the command line I specified on the original post and thread-concurrency=7168 instead of shaders
2451  Alternate cryptocurrencies / Mining (Altcoins) / Re: Consolidated Litecoin Mining Guide for 5xxx, 6xxx, and 7xxx GPUs on: November 23, 2012, 06:44:59 PM
I've been having trouble getting cgminer to work... I can get reaper to mine LTC at faster speeds (still not as fast as it should be), however I prefer to use cgminer because it has many more features. Cgminer will mine bitcoins at proper speeds, getting over 2.5 Gh. However when I launch cgminer, I am stuck at really slow speeds (10-15Kh per core of a 5970).

5 BTC goes to anyone that can get me running at full speeds.

Specs:
Three 5970s & Two 5870s
Windows 7
Installed the latest version of AMD APP SDK & latest AMD drivers
Using 2 powered extenders and dummy plug resistors on all cards.
4Gb RAM (I tried up to 8Gb, but it made no difference)

What am I doing wrong? I've tried everything I can think of.


8gb of ram is more than enough, cgminer barely uses any RAM.  The problem is probably your cgminer configuration; you should post it.
2452  Alternate cryptocurrencies / Mining (Altcoins) / Re: Consolidated Litecoin Mining Guide for 5xxx, 6xxx, and 7xxx GPUs on: November 23, 2012, 06:32:03 PM
How much ram are you running on that machine for the 3 cards?

8Gb
2453  Alternate cryptocurrencies / Mining (Altcoins) / Re: Consolidated Litecoin Mining Guide for 5xxx, 6xxx, and 7xxx GPUs on: November 23, 2012, 04:44:06 PM
I've finally figured out a way to deal with the temperatures, which is by putting my rig outside  Cheesy



3x 7950s.  These were running at 80C+ in the summer.  Power consumption seems to be down, too.
2454  Alternate cryptocurrencies / Mining (Altcoins) / Re: Consolidated Litecoin Mining Guide for 5xxx, 6xxx, and 7xxx GPUs on: November 22, 2012, 01:11:29 AM
I don't really have time to... it's probably better to know how to tweak it yourself anyway because LTC is so finicky.
2455  Other / Off-topic / Re: Should BFL get a scammer tag? on: November 21, 2012, 10:43:17 PM
The real question by now is: Should tacotime get a Troll tag?


(only if Inaba gets one too)

Quote from: Inaba
Regardless, for the rest of your post, everything you said, were it to be true, applies at least doubly to every other vendor, so you'd be absolutely insane to buy anything but BFL then (assuming you bought at all), if what you say is true.
2456  Other / Off-topic / Re: Should BFL get a scammer tag? on: November 21, 2012, 10:34:50 PM
Well, I guess I'm not the only one who has lost confidence lately, there's 5 ASIC preorders for sale in the buy/sell forum...  I wonder why they just don't ask BFL for a refund if it's so easy?

https://bitcointalk.org/index.php?topic=127177.0
https://bitcointalk.org/index.php?topic=127003.0
https://bitcointalk.org/index.php?topic=126695.0
https://bitcointalk.org/index.php?topic=124233.0
https://bitcointalk.org/index.php?topic=126764.0
2457  Other / Off-topic / Re: Should BFL get a scammer tag? on: November 21, 2012, 10:13:53 PM
If they did not allow refunds i might agree. But since they do, no scammer tag for them.

Pirate paid quite a lot of interest until his operations shut down, and everyone thought it was legitimate until they lost their money.  What happens if everyone wants a refund from BFL at the same time?
2458  Other / Off-topic / Re: Should BFL get a scammer tag? on: November 21, 2012, 08:42:45 PM
Here we can watch Inaba troll his own customer base!  What a guy!

Quote
Why don't you just shut up and deliver?

That's all we want from you/BFL.

Quote from: Inaba
Because you wouldn't have anything to bitch about then.  It's all about you, Frizz.



https://bitcointalk.org/index.php?topic=112700.msg1350101#msg1350101
2459  Other / Off-topic / Should BFL get a scammer tag? on: November 21, 2012, 06:50:13 PM
Statements from BFL Josh/Inaba/BFL themselves

Quote
So will the BitForce SC product line REALLY come out in October? This is a fair question.  Let's review our track record.  If you're not aware, our initial product, the BitForce Single had a slow delivery cycle.  This was initially due to a last minute design change before initial product release.  When we did release it, we weren't quite prepared for the explosive success we had.  After several rounds of scaling, single delivery is in sufficient volume to catch up quickly. The Mini Rig product release has followed it's development and release timeline pretty well.  Initial deliveries aren't far from estimates and the speed of production is on pace to ensure most customers will get their Mini Rigs ahead of schedule. The SC product line has been under development for quite some time and is not the result of an expedited development process.  Although there are always issues during development, our team is highly experienced in exactly this field and we're currently ahead of our original timeline.  Honest Abe, we're scheduling shipments for October of 2012.
http://www.butterflylabs.com/bitforce-sc-release-notes/

Quote
So, we've got he myriad distributors shipping thousands of little pieces to us, the PCB manufacturer sending us the bare PCBs, the HSF manufacturer sending the HSFs to us, the PSU manufacturer sending the PSU's to us, the case manufacturer sending the cases to us and most importantly, the fab sending the ASIC chips to us. All of these must arrive on time and as expected for everything to go off without a hitch. So far, so good.
October 10, 2012
https://forums.butterflylabs.com/showthread.php/104-Shipping-in-2-3-weeks?p=1461&viewfull=1#post1461

Quote
We wanted to cover the bases with the Bitcoin Mag article, so we pushed the shipment date out.

With regards to an updated shipping schedule, we are waiting on some information with regards to the bulk shipment of our ASIC chips. Once we get a confirmed date on the bulk shipment, I will have a pretty solid idea of exactly when we will start shipping, but until I have a more exact date with regards to the chips, I can't give a better estimate. Once we have the chips in hand it will take a couple days to get them pushed through our pick and place house and then ready to be shipped out. Chances are, either I or someone else from BFL will be going in person to be sure each step is executed as quickly as possible and to handle any unexpected contingencies that might crop up.

At this point, though, I very seriously doubt we'll make the end of October. How far into November that is pushed I should know sometime soon (this week, I hope).
https://forums.butterflylabs.com/showthread.php/188-Information-from-Bitcoin-Magazine?p=2636&viewfull=1#post2636

Quote
I would like to know what one or two individuals (in the US preferably, unless the non-US person wants to pony up a ticket) that Bitcoin Talk community would nominate and accept as credible, verifiable individuals to be flown here to KC sometime around the end of October/Beginning of November time frame to see our facility, inspect the manufacturing equipment and test out the devices.  We don't have an exact date yet as to when we would do this, but I would like to get the ball rolling as far as names in the hat and see if there's even a vague consensus on who the individual(s) might be.
https://bitcointalk.org/index.php?topic=112543.0

See further in this post: https://bitcointalk.org/index.php?topic=112700.msg1297999#msg1297999

Come on guys... if this was ANYONE else except for BFL they would have had scammer tags already!  The community has given them hundreds of thousands of their dollars, waited month upon month, and has not seen a word of honest discourse from them about the state of their products.

If you're waiting on something, why not tell us?  Why not tell us what it is?  Why not at least provide process details for your ASIC like Avalon?  Ridiculous.
2460  Economy / Goods / Re: Want to buy something from Japan? (xpost / PRODUCT UPDATE: 24/10) on: November 21, 2012, 03:20:28 AM
Got my stuff today and he even threw in free candy. Very nice man to work with and shipped expedited, only took 7 days to get to north America!!
Pages: « 1 ... 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 [123] 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 »
Powered by MySQL Powered by PHP Powered by SMF 1.1.19 | SMF © 2006-2009, Simple Machines Valid XHTML 1.0! Valid CSS!