Author

Topic: how fix diff adjustment attack ? (Read 905 times)

newbie
Activity: 14
Merit: 0
July 27, 2017, 10:53:48 AM
#25
I understand all , but coin's how dash end other try fix this problem end they fix it.

Required a more flexible algorithm of complexity, understand there is a difference when the algorithm is sharpened for recounting complexity once in a long period and when it is necessary to recalculate the complexity of each block.

The problem is that initially when creating a coin about this one did not think, and now I'm trying to fix it. And yes, I'm not the creator of the coin, I've made it to the developers that would not let the coin die.

I created this topic only to help me with finding solutions, those who have already encountered this, that would not look for it in tons of source codes of other coins to understand the principle. And they will repulse already from the ready decision, but instead of an answer I got some kind of nonsense that this is not possible.


If such intelligent people were all listening, we would still be running with sticks in the re-lanes.
newbie
Activity: 14
Merit: 0
July 26, 2017, 03:22:16 PM
#22
sorry i do not see what you say , you ignored. I think again some offtop.

no mater i find worked solution.
newbie
Activity: 14
Merit: 0
July 26, 2017, 02:51:20 PM
#20
if for some reason even 30% hash rate off any coin go away the transaction stop. Cataclysm, war with china etc... Quantum computer from NSA runed for 5 second end leave network.
This problem exist , it's problem not crypto algorithm - it's problem diff algorithm !

Ok use new algoritm how you say ? but if miner's left coin ? what to do ? You dont know ? whay you write on this topic ? Test net hv function for drop diff whay it not secure  end use ?

Those are unforeseeable, end of days style events. What you have done was entirely predictable and frankly stupid. I feel sorry for the people who hold whatever coin it is you have created.

Are you idiot ? I not do anything yet i ask for solution for prevent this. It's you stupid, please go away from this topic if you do not understand what i asked, end do not have brain for think.

I think you have more important things to do, for example, doing school homework ...

I understand you IQ is <10% but i try again explain - the problem is not in crypto algo , the problem is on retarget system. End yes my dear friend , many coin's change it for fix this, end i asked for some solution , that would not revise tons of altcoin code in search of a solution.  But simple change algorithm not fix problem. End if you do not know diff can to decress , not only incress how you say . You say stupid think end it's make you idiot. The retarget diff system created for bitcoin/coin with xxx block retarget is not compatible with 5 minute  block's end retarget every block. End it need change for it work with no bug's how this.

Need some like this, but maked for lite time retarget

Code:
// This is MIDAS (Multi Interval Difficulty Adjustment System), a novel getnextwork algorithm.  It responds quickly to
// huge changes in hashing power, is resistant to time warp attacks, and regulates the block rate to keep the block height
// close to the block height expected given the nominal block interval and the elapsed time.  How close the
// correspondence between block height and wall clock time is, depends on how stable the hashing power has been.  Maybe
// Bitcoin can wait 2 weeks between updates but no altcoin can.

// It is important that none of these intervals (5, 7, 9, 17) have any common divisor; eliminating the existence of
// harmonics is an important part of eliminating the effectiveness of timewarp attacks.
void avgRecentTimestamps(const CBlockIndex* pindexLast, int64_t *avgOf5, int64_t *avgOf7, int64_t *avgOf9, int64_t *avgOf17)
{
  int blockoffset = 0;
  int64_t oldblocktime;
  int64_t blocktime;

  *avgOf5 = *avgOf7 = *avgOf9 = *avgOf17 = 0;
  if (pindexLast)
    blocktime = pindexLast->GetBlockTime();
  else blocktime = 0;

  for (blockoffset = 0; blockoffset < 18; blockoffset++)
  {
    oldblocktime = blocktime;
    if (pindexLast)
    {
      pindexLast = pindexLast->pprev;
      blocktime = pindexLast->GetBlockTime();
    }
    else
    { // genesis block or previous
blocktime -= Params().TargetSpacing();
    }
    // for each block, add interval.
    if (blockoffset < 5) *avgOf5 += (oldblocktime - blocktime);
    if (blockoffset < 7) *avgOf7 += (oldblocktime - blocktime);
    if (blockoffset < 9) *avgOf9 += (oldblocktime - blocktime);
    *avgOf17 += (oldblocktime - blocktime);   
  }
  // now we have the sums of the block intervals. Division gets us the averages.
  *avgOf5 /= 5;
  *avgOf7 /= 7;
  *avgOf9 /= 9;
  *avgOf17 /= 17;
}


unsigned int GetNextWorkRequired(const CBlockIndex *pindexLast, const CBlockHeader *pblock)
{
    int64_t avgOf5;
    int64_t avgOf9;
    int64_t avgOf7;
    int64_t avgOf17;
    int64_t toofast;
    int64_t tooslow;
    int64_t difficultyfactor = 10000;
    int64_t now;
    int64_t BlockHeightTime;

    int64_t nFastInterval = (Params().TargetSpacing() * 9 ) / 10; // seconds per block desired when far behind schedule
    int64_t nSlowInterval = (Params().TargetSpacing() * 11) / 10; // seconds per block desired when far ahead of schedule
    int64_t nIntervalDesired;

    unsigned int nProofOfWorkLimit = Params().ProofOfWorkLimit().GetCompact();

    if (pindexLast == NULL)
        // Genesis Block
        return nProofOfWorkLimit;

   
    if (Params().AllowMinDifficultyBlocks())
    {
        // Special difficulty rule for testnet: If the new block's timestamp is more than 2* TargetSpacing then allow
        // mining of a min-difficulty block.
        if (pblock->nTime > pindexLast->nTime + Params().TargetSpacing() * 2)
           return nProofOfWorkLimit;
        else
        {
            // Return the last non-special-min-difficulty-rules-block
           const CBlockIndex* pindex = pindexLast;
           while (pindex->pprev && pindex->nHeight % nIntervalDesired != 0 && pindex->nBits == nProofOfWorkLimit)
               pindex = pindex->pprev;
           return pindex->nBits;
        }
    }

    // Regulate block times so as to remain synchronized in the long run with the actual time.  The first step is to
    // calculate what interval we want to use as our regulatory goal.  It depends on how far ahead of (or behind)
    // schedule we are.  If we're more than an adjustment period ahead or behind, we use the maximum (nSlowInterval) or minimum
    // (nFastInterval) values; otherwise we calculate a weighted average somewhere in between them.  The closer we are
    // to being exactly on schedule the closer our selected interval will be to our nominal interval (TargetSpacing).

    now = pindexLast->GetBlockTime();
    BlockHeightTime = Params().GenesisBlock().nTime + pindexLast->nHeight * Params().TargetSpacing();
   
    if (now < BlockHeightTime + Params().AdjustmentInterval() && now > BlockHeightTime )
    // ahead of schedule by less than one interval.
nIntervalDesired = ((Params().AdjustmentInterval() - (now - BlockHeightTime)) * Params().TargetSpacing() + 
   (now - BlockHeightTime) * nFastInterval) / Params().AdjustmentInterval();
    else if (now + Params().AdjustmentInterval() > BlockHeightTime && now < BlockHeightTime)
    // behind schedule by less than one interval.
nIntervalDesired = ((Params().AdjustmentInterval() - (BlockHeightTime - now)) * Params().TargetSpacing() +
   (BlockHeightTime - now) * nSlowInterval) / Params().AdjustmentInterval();

    // ahead by more than one interval;
    else if (now < BlockHeightTime) nIntervalDesired = nSlowInterval;
   
    // behind by more than an interval.
    else  nIntervalDesired = nFastInterval;
   
    // find out what average intervals over last 5, 7, 9, and 17 blocks have been.
    avgRecentTimestamps(pindexLast, &avgOf5, &avgOf7, &avgOf9, &avgOf17);   

    // check for emergency adjustments. These are to bring the diff up or down FAST when a burst miner or multipool
    // jumps on or off.  Once they kick in they can adjust difficulty very rapidly, and they can kick in very rapidly
    // after massive hash power jumps on or off.
   
    // Important note: This is a self-damping adjustment because 8/5 and 5/8 are closer to 1 than 3/2 and 2/3.  Do not
    // screw with the constants in a way that breaks this relationship.  Even though self-damping, it will usually
    // overshoot slightly. But normal adjustment will handle damping without getting back to emergency.
    toofast = (nIntervalDesired * 2) / 3;
    tooslow = (nIntervalDesired * 3) / 2;

    // both of these check the shortest interval to quickly stop when overshot.  Otherwise first is longer and second shorter.
    if (avgOf5 < toofast && avgOf9 < toofast && avgOf17 < toofast)
    {  //emergency adjustment, slow down (longer intervals because shorter blocks)
      LogPrintf("GetNextWorkRequired EMERGENCY RETARGET\n");
      difficultyfactor *= 8;
      difficultyfactor /= 5;
    }
    else if (avgOf5 > tooslow && avgOf7 > tooslow && avgOf9 > tooslow)
    {  //emergency adjustment, speed up (shorter intervals because longer blocks)
      LogPrintf("GetNextWorkRequired EMERGENCY RETARGET\n");
      difficultyfactor *= 5;
      difficultyfactor /= 8;
    }

    // If no emergency adjustment, check for normal adjustment.
    else if (((avgOf5 > nIntervalDesired || avgOf7 > nIntervalDesired) && avgOf9 > nIntervalDesired && avgOf17 > nIntervalDesired) ||
    ((avgOf5 < nIntervalDesired || avgOf7 < nIntervalDesired) && avgOf9 < nIntervalDesired && avgOf17 < nIntervalDesired))
    { // At least 3 averages too high or at least 3 too low, including the two longest. This will be executed 3/16 of
      // the time on the basis of random variation, even if the settings are perfect. It regulates one-sixth of the way
      // to the calculated point.
      LogPrintf("GetNextWorkRequired RETARGET\n");
      difficultyfactor *= (6 * nIntervalDesired);
      difficultyfactor /= (avgOf17 + 5 * nIntervalDesired));
    }

    // limit to doubling or halving.  There are no conditions where this will make a difference unless there is an
    // unsuspected bug in the above code.
    if (difficultyfactor > 20000) difficultyfactor = 20000;
    if (difficultyfactor < 5000) difficultyfactor = 5000;

    uint256 bnNew;
    uint256 bnOld;

    bnOld.SetCompact(pindexLast->nBits);

    if (difficultyfactor == 10000) // no adjustment.
      return(bnOld.GetCompact());

    bnNew = bnOld / difficultyfactor;
    bnNew *= 10000;

    if (bnNew > Params().ProofOfWorkLimit())
      bnNew = Params().ProofOfWorkLimit();

    LogPrintf("Actual time %d, Scheduled time for this block height = %d\n", now, BlockHeightTime );
    LogPrintf("Nominal block interval = %d, regulating on interval %d to get back to schedule.\n",
     Params().TargetSpacing(), nIntervalDesired );
    LogPrintf("Intervals of last 5/7/9/17 blocks = %d / %d / %d.\n",
     Params().TargetSpacing(), avgOf5, avgOf7, avgOf9, avgOf17);
    LogPrintf("Difficulty Before Adjustment: %08x  %s\n", pindexLast->nBits, bnOld.ToString());
    LogPrintf("Difficulty After Adjustment:  %08x  %s\n", bnNew.GetCompact(), bnNew.ToString());

    return bnNew.GetCompact();
}
newbie
Activity: 14
Merit: 0
July 26, 2017, 12:08:18 PM
#18
the code is fine, not sure what you want to fix. if the diff too high that your network is blocked, just blacklist the last block and restart from there, it's easy.

Ok where i can find info about how delete the latest block with huge diff
newbie
Activity: 14
Merit: 0
July 26, 2017, 11:24:12 AM
#17
The reason I'm answering the question the way I am, is because he used the word attack. I don't get the full gist of what you're asking here, but I'm going to take a shot in the dark and assume that you're looking at a single minor pushing the difficulty well above the mass majority of other minors. If that is the case, they are basically shooting themselves in the foot. Well they may be the only minors that is producing any coins. the difficulty is only going to stay at the higher number while that particular person Is mining.

but if miner's leave it's stay on huge diff  end blockchain not move transaction - what ever you say , i think it's bug end need to fix that any way .
newbie
Activity: 14
Merit: 0
July 26, 2017, 11:21:49 AM
#16
it's possible but it's not fix the problem, need control it automatic from code.
newbie
Activity: 14
Merit: 0
July 26, 2017, 10:59:46 AM
#13
if for some reason even 30% hash rate off any coin go away the transaction stop. Cataclysm, war with china etc... Quantum computer from NSA runed for 5 second end leave network.
This problem exist , it's problem not crypto algorithm - it's problem diff algorithm !

Ok use new algoritm how you say ? but if miner's left coin ? what to do ? You dont know ? whay you write on this topic ? Test net hv function for drop diff whay it not secure  end use ?
legendary
Activity: 1190
Merit: 1024
August 03, 2017, 12:39:32 PM
#12
The reason I'm answering the question the way I am, is because he used the word attack. I don't get the full gist of what you're asking here, but I'm going to take a shot in the dark and assume that you're looking at a single minor pushing the difficulty well above the mass majority of other minors. If that is the case, they are basically shooting themselves in the foot. Well they may be the only minors that is producing any coins. the difficulty is only going to stay at the higher number while that particular person Is mining.

but if miner's leave it's stay on huge diff  end blockchain not move transaction - what ever you say , i think it's bug end need to fix that any way .

While they might get a quick pump of money, they are quickly going to become the only bag holder, and hopefully no one's going to be buying the coin from them. The point is, if you think about a coin like Bitcoin, this technically happened with mining pools, Farms, and Asics. There were short periods of time when small isolated groups controlled most of the mining, but because of the popularity of the coin, everyone else caught up at the same technology. If this is not what you're referring to, then I really don't understand the question. but one last possible thought, let's say it's only you and a couple miners mining in your coin, and for whatever reason the difficulty has gotten much higher then the amount of effort resources anyone is putting into it.
legendary
Activity: 3136
Merit: 1172
Leading Crypto Sports Betting & Casino Platform
July 27, 2017, 09:16:23 AM
#11
Even if a single minor, with highly reduced resources, mine's that coin, if it eventually solves the block, then the fact that the block was solved by a minor at a smaller hashrate will eventually bring the difficulty back down. If you have any resources at all, then you can always consider renting some hash rate online, and slowly ramping it back down to where you wanted to be. If this is the case, then at least you're going to get some block rewards off of doing it.
full member
Activity: 351
Merit: 134
July 26, 2017, 03:52:21 PM
#10
For anyone wondering, the coin in question is LBTC.

https://bitcointalksearch.org/topic/m.20340189

Stay clear.
full member
Activity: 351
Merit: 134
July 26, 2017, 03:11:50 PM
#9
coin been adjustment do huge diff  with asic's end now i try to fix it , but cannot find any info how do this.

Ok. Kind of sounds like this has already happened from what you wrote. If it hasn't happened, you know what to do.
full member
Activity: 351
Merit: 134
July 26, 2017, 02:16:14 PM
#8
if for some reason even 30% hash rate off any coin go away the transaction stop. Cataclysm, war with china etc... Quantum computer from NSA runed for 5 second end leave network.
This problem exist , it's problem not crypto algorithm - it's problem diff algorithm !

Ok use new algoritm how you say ? but if miner's left coin ? what to do ? You dont know ? whay you write on this topic ? Test net hv function for drop diff whay it not secure  end use ?

Those are unforeseeable, end of days style events. What you have done was entirely predictable and frankly stupid. I feel sorry for the people who hold whatever coin it is you have created.
full member
Activity: 365
Merit: 100
July 26, 2017, 11:06:28 AM
#7
the code is fine, not sure what you want to fix. if the diff too high that your network is blocked, just blacklist the last block and restart from there, it's easy.
legendary
Activity: 1190
Merit: 1024
July 26, 2017, 11:03:26 AM
#6
The reason I'm answering the question the way I am, is because he used the word attack. I don't get the full gist of what you're asking here, but I'm going to take a shot in the dark and assume that you're looking at a single minor pushing the difficulty well above the mass majority of other minors. If that is the case, they are basically shooting themselves in the foot. Well they may be the only minors that is producing any coins. the difficulty is only going to stay at the higher number while that particular person Is mining.
full member
Activity: 351
Merit: 134
July 26, 2017, 09:37:18 AM
#5
If this can be done your coin is not secure. Move to a PoW Algorithm that is egalitarian.

any algorithm can be killed when for them create asic. It's not reason to mow to other algorithm need fix problem. If it's not fixed - even bitcoin can be killed with this.

You've created this problem for yourself by lack of understanding. Bitcoin cannot suffer from this problem, since the state of the art in ASICs is already mining on that chain.

You made the mistake of using a PoW which already had vastly accelerated mining technology on a brand new coin.
full member
Activity: 140
Merit: 101
July 26, 2017, 01:00:32 AM
#4
If this can be done your coin is not secure. Move to a PoW Algorithm that is egalitarian.
legendary
Activity: 2002
Merit: 1051
ICO? Not even once.
July 24, 2017, 10:21:03 PM
#3
i find info about

 bitcoins' testnet uses a rule where difficulty drops to 1 when no block has been found for 20 min.
i can be usual to fix this bug ? end how to secure this funcion if use it for main network

i say about this
Code:
  // Only change once per interval
    if ((pindexLast->nHeight+1) % nInterval != 0)
    {
        // Special difficulty rule for testnet:
        if (fTestNet)
        {
            // If the new block's timestamp is more than 2* 10 minutes
            // then allow mining of a min-difficulty block.
            if (pblock->nTime > pindexLast->nTime + nTargetSpacing*2)
                return nProofOfWorkLimit;
            else
            {
                // Return the last non-special-min-difficulty-rules-block
                const CBlockIndex* pindex = pindexLast;
                while (pindex->pprev && pindex->nHeight % nInterval != 0 && pindex->nBits == nProofOfWorkLimit)
                    pindex = pindex->pprev;
                return pindex->nBits;
            }
        }

        return pindexLast->nBits;
    }

I can't imagine that being secure. You can set your wallet 20 minutes in the future and mine a low diff block over and over so you'll have the longest chain. But I'm not a programmer.

Your best bet is probably renting hashrate to find the next block and hope for the difficulty retarget that it lowers the diff in just the next block.

Otherwise, you have to hardfork if you want to avoid ASICs kicking the diff into the moon.
legendary
Activity: 2002
Merit: 1051
ICO? Not even once.
July 24, 2017, 08:50:09 PM
#2
I can't help you with a stuck coin but here are some thoughts:

Since every difficulty retargeting logic can only change the difficulty when a block is found, they can all be "attacked" by getting them stuck with a lot of hashrate.

This is why coins like Digibyte have multiple PoW algorithms - if one algo is stuck in a high diff, the chain can move forward by finding block with other algos.

And if an algo's diff is stuck, it should be possible that whenever a block is found with another algo, the difficulty of the algo that is stucked could be lowered. I don't know if it's the case with Digibyite or similar coins (Joincoin, Myriad, Verge, Aurora, etc).
newbie
Activity: 14
Merit: 0
July 24, 2017, 08:44:05 PM
#1
How possible fix adjustment atack ?



the sample of pow code used on altcoin ( scrypt  coin based on old sources of litecoin)

main.cpp

Code:
int64 static GetBlockValue(int nHeight, int64 nFees)
{
    int64 nSubsidy = 500 * COIN;

            if(nHeight == 1)
            {
            nSubsidy = 160000000 * COIN;
            }

    // Subsidy is cut in half every 840000 blocks
    nSubsidy >>= (nHeight / 840000);

    return nSubsidy + nFees;
}

static const int64 nTargetTimespan = 10 * 60;
static const int64 nTargetSpacing = 5 * 60;
static const int64 nInterval = nTargetTimespan / nTargetSpacing;

//
// minimum amount of work that could possibly be required nTime after
// minimum work required was nBase
//
unsigned int ComputeMinWork(unsigned int nBase, int64 nTime)
{
    // Testnet has min-difficulty blocks
    // after nTargetSpacing*2 time between blocks:
    if (fTestNet && nTime > nTargetSpacing*2)
        return bnProofOfWorkLimit.GetCompact();

    CBigNum bnResult;
    bnResult.SetCompact(nBase);
    while (nTime > 0 && bnResult < bnProofOfWorkLimit)
    {
        // Maximum 400% adjustment...
        bnResult *= 4;
        // ... in best-case exactly 4-times-normal target time
        nTime -= nTargetTimespan*4;
    }
    if (bnResult > bnProofOfWorkLimit)
        bnResult = bnProofOfWorkLimit;
    return bnResult.GetCompact();
}

unsigned int static GetNextWorkRequired(const CBlockIndex* pindexLast, const CBlockHeader *pblock)
{
    unsigned int nProofOfWorkLimit = bnProofOfWorkLimit.GetCompact();

    // Genesis block
    if (pindexLast == NULL)
        return nProofOfWorkLimit;

    // Only change once per interval
    if ((pindexLast->nHeight+1) % nInterval != 0)
    {
        // Special difficulty rule for testnet:
        if (fTestNet)
        {
            // If the new block's timestamp is more than 2* 10 minutes
            // then allow mining of a min-difficulty block.
            if (pblock->nTime > pindexLast->nTime + nTargetSpacing*2)
                return nProofOfWorkLimit;
            else
            {
                // Return the last non-special-min-difficulty-rules-block
                const CBlockIndex* pindex = pindexLast;
                while (pindex->pprev && pindex->nHeight % nInterval != 0 && pindex->nBits == nProofOfWorkLimit)
                    pindex = pindex->pprev;
                return pindex->nBits;
            }
        }

        return pindexLast->nBits;
    }

    // LiteBitcoin: This fixes an issue where a 51% attack can change difficulty at will.
    // Go back the full period unless it's the first retarget after genesis. Code courtesy of Art Forz
    int blockstogoback = nInterval-1;
    if ((pindexLast->nHeight+1) != nInterval)
        blockstogoback = nInterval;

    // Go back by what we want to be 14 days worth of blocks
    const CBlockIndex* pindexFirst = pindexLast;
    for (int i = 0; pindexFirst && i < blockstogoback; i++)
        pindexFirst = pindexFirst->pprev;
    assert(pindexFirst);

    // Limit adjustment step
    int64 nActualTimespan = pindexLast->GetBlockTime() - pindexFirst->GetBlockTime();
    printf("  nActualTimespan = %"PRI64d"  before bounds\n", nActualTimespan);
    if (nActualTimespan < nTargetTimespan/4)
        nActualTimespan = nTargetTimespan/4;
    if (nActualTimespan > nTargetTimespan*4)
        nActualTimespan = nTargetTimespan*4;

    // Retarget
    CBigNum bnNew;
    bnNew.SetCompact(pindexLast->nBits);
    bnNew *= nActualTimespan;
    bnNew /= nTargetTimespan;

    if (bnNew > bnProofOfWorkLimit)
        bnNew = bnProofOfWorkLimit;

    /// debug print
    printf("GetNextWorkRequired RETARGET\n");
    printf("nTargetTimespan = %"PRI64d"    nActualTimespan = %"PRI64d"\n", nTargetTimespan, nActualTimespan);
    printf("Before: %08x  %s\n", pindexLast->nBits, CBigNum().SetCompact(pindexLast->nBits).getuint256().ToString().c_str());
    printf("After:  %08x  %s\n", bnNew.GetCompact(), bnNew.getuint256().ToString().c_str());

    return bnNew.GetCompact();
}

bool CheckProofOfWork(uint256 hash, unsigned int nBits)
{
    CBigNum bnTarget;
    bnTarget.SetCompact(nBits);

    // Check range
    if (bnTarget <= 0 || bnTarget > bnProofOfWorkLimit)
        return error("CheckProofOfWork() : nBits below minimum work");

    // Check proof of work matches claimed amount
    if (hash > bnTarget.getuint256())
        return error("CheckProofOfWork() : hash doesn't match nBits");

    return true;
}

// Return maximum amount of blocks that other nodes claim to have
int GetNumBlocksOfPeers()
{
    return std::max(cPeerBlockCounts.median(), Checkpoints::GetTotalBlocksEstimate());
}


Jump to: