Skip to content

Commit

Permalink
1.replay-protected
Browse files Browse the repository at this point in the history
 2.difficult to adjust(New Difficulty Adjustment Algorithm  DAA )
  • Loading branch information
rangershi committed Dec 3, 2017
1 parent 026713a commit 33c79d1
Show file tree
Hide file tree
Showing 18 changed files with 230 additions and 31 deletions.
24 changes: 15 additions & 9 deletions src/bitcoin-tx.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -490,17 +490,23 @@ static void MutateTxDelOutput(CMutableTransaction& tx, const std::string& strOut
tx.vout.erase(tx.vout.begin() + outIdx);
}

static const unsigned int N_SIGHASH_OPTS = 6;
static const unsigned int N_SIGHASH_OPTS = 12;
static const struct {
const char *flagStr;
int flags;
} sighashOptions[N_SIGHASH_OPTS] = {
{"ALL", SIGHASH_ALL},
{"NONE", SIGHASH_NONE},
{"SINGLE", SIGHASH_SINGLE},
{"ALL|ANYONECANPAY", SIGHASH_ALL|SIGHASH_ANYONECANPAY},
{"NONE|ANYONECANPAY", SIGHASH_NONE|SIGHASH_ANYONECANPAY},
{"SINGLE|ANYONECANPAY", SIGHASH_SINGLE|SIGHASH_ANYONECANPAY},
{"ALL", SIGHASH_ALL},
{"NONE", SIGHASH_NONE},
{"SINGLE", SIGHASH_SINGLE},
{"ALL|ANYONECANPAY", SIGHASH_ALL|SIGHASH_ANYONECANPAY},
{"NONE|ANYONECANPAY", SIGHASH_NONE|SIGHASH_ANYONECANPAY},
{"SINGLE|ANYONECANPAY", SIGHASH_SINGLE|SIGHASH_ANYONECANPAY},
{"ALL|SBTC_FORK", SIGHASH_ALL | SIGHASH_SBTC_FORK},
{"NONE|SBTC_FORK", SIGHASH_NONE | SIGHASH_SBTC_FORK},
{"SINGLE|SBTC_FORK", SIGHASH_SINGLE | SIGHASH_SBTC_FORK},
{"ALL|SBTC_FORK|ANYONECANPAY", SIGHASH_ALL | SIGHASH_SBTC_FORK | SIGHASH_ANYONECANPAY},
{"NONE|SBTC_FORK|ANYONECANPAY", SIGHASH_NONE | SIGHASH_SBTC_FORK | SIGHASH_ANYONECANPAY},
{"SINGLE|SBTC_FORK|ANYONECANPAY", SIGHASH_SINGLE | SIGHASH_SBTC_FORK | SIGHASH_ANYONECANPAY},
};

static bool findSighashFlags(int& flags, const std::string& flagStr)
Expand Down Expand Up @@ -531,7 +537,7 @@ static CAmount AmountFromValue(const UniValue& value)

static void MutateTxSign(CMutableTransaction& tx, const std::string& flagStr)
{
int nHashType = SIGHASH_ALL;
int nHashType = SIGHASH_ALL | SIGHASH_SBTC_FORK;

if (flagStr.size() > 0)
if (!findSighashFlags(nHashType, flagStr))
Expand Down Expand Up @@ -624,7 +630,7 @@ static void MutateTxSign(CMutableTransaction& tx, const std::string& flagStr)

const CKeyStore& keystore = tempKeystore;

bool fHashSingle = ((nHashType & ~SIGHASH_ANYONECANPAY) == SIGHASH_SINGLE);
bool fHashSingle = ((nHashType & ~(SIGHASH_ANYONECANPAY | SIGHASH_SBTC_FORK)) == SIGHASH_SINGLE);

// Sign what we can:
for (unsigned int i = 0; i < mergedTx.vin.size(); i++) {
Expand Down
13 changes: 12 additions & 1 deletion src/chainparams.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,9 @@ bool CChainParams::AddCheckPoint(int const hight, const uint256 hash) const{
return true;

}



/**
* Main network
*/
Expand Down Expand Up @@ -120,6 +123,9 @@ class CMainParams : public CChainParams {
// By default assume that the signatures in ancestors of this block are valid.
consensus.defaultAssumeValid = uint256S("0x0000000000000000003b9ce759c2a087d52abc4266f8f4ebd6d768b89defa50a"); //477890


consensus.SBTCForkHeight = 498888;

/**
* The message start string is designed to be unlikely to occur in normal data.
* The characters are rarely used upper ASCII, not valid as UTF-8, and produce
Expand Down Expand Up @@ -226,6 +232,8 @@ class CTestNetParams : public CChainParams {
// By default assume that the signatures in ancestors of this block are valid.
consensus.defaultAssumeValid = uint256S("0x0000000002e9e7b00e1f6dc5123a04aad68dd0f0968d8c7aa45f6640795c37b1"); //1135275

consensus.SBTCForkHeight = 0;

pchMessageStart[0] = 0x0b;
pchMessageStart[1] = 0x11;
pchMessageStart[2] = 0x09;
Expand Down Expand Up @@ -313,6 +321,8 @@ class CRegTestParams : public CChainParams {
// By default assume that the signatures in ancestors of this block are valid.
consensus.defaultAssumeValid = uint256S("0x00");

consensus.SBTCForkHeight = 1000;

pchMessageStart[0] = 0xfa;
pchMessageStart[1] = 0xbf;
pchMessageStart[2] = 0xb5;
Expand All @@ -331,9 +341,10 @@ class CRegTestParams : public CChainParams {
fDefaultConsistencyChecks = true;
fRequireStandard = false;
fMineBlocksOnDemand = true;
cCheckPointPubKey= CPubKey(ParseHex("02246a362f9f887db8d33185ad1f72512884618f6789e279c34a86e18590c78154"));
// address:mtkXqYXjPB3EChJcEq8bJJfeRrCsotFxhs
// private key:cQLJjWeqTCCLLrNTwbRAUG7Fcwvs4BNo5GGT6AdNWS82na3EzdNE
cCheckPointPubKey= CPubKey(ParseHex("02246a362f9f887db8d33185ad1f72512884618f6789e279c34a86e18590c78154"));

checkpointData = (CCheckpointData) {
{
{0, uint256S("0f9188f13cb7b2c71f2a335e3a4fc328bf5beb436012afca590b1a11466e2206")},
Expand Down
2 changes: 1 addition & 1 deletion src/chainparams.h
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ class CChainParams
const std::vector<unsigned char>& Base58Prefix(Base58Type type) const { return base58Prefixes[type]; }
const std::vector<SeedSpec6>& FixedSeeds() const { return vFixedSeeds; }
const CCheckpointData& Checkpoints() const { return checkpointData; }
bool AddCheckPoint(int const hight, const uint256 hash) const ;
bool AddCheckPoint(int const hight, const uint256 hash) const;
const ChainTxData& TxData() const { return chainTxData; }
void UpdateVersionBitsParameters(Consensus::DeploymentPos d, int64_t nStartTime, int64_t nTimeout);
const CPubKey& GetCheckPointPKey()const{ return std::move(cCheckPointPubKey);}
Expand Down
2 changes: 2 additions & 0 deletions src/consensus/params.h
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,8 @@ struct Params {
int BIP65Height;
/** Block height at which BIP66 becomes active */
int BIP66Height;
/*SBTC Fork active */
int SBTCForkHeight;
/**
* Minimum blocks including miner confirmation of the total of 2016 blocks in a retargeting period,
* (nPowTargetTimespan / nPowTargetSpacing) which is also used for BIP9 deployments.
Expand Down
18 changes: 14 additions & 4 deletions src/core_write.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -63,11 +63,14 @@ std::string FormatScript(const CScript& script)

const std::map<unsigned char, std::string> mapSigHashTypes = {
{static_cast<unsigned char>(SIGHASH_ALL), std::string("ALL")},
{static_cast<unsigned char>(SIGHASH_ALL|SIGHASH_ANYONECANPAY), std::string("ALL|ANYONECANPAY")},
{static_cast<unsigned char>(SIGHASH_ALL|SIGHASH_SBTC_FORK), std::string("ALL|SBTC_FORK")},
{static_cast<unsigned char>(SIGHASH_ALL|SIGHASH_SBTC_FORK|SIGHASH_ANYONECANPAY), std::string("ALL|SBTC_FORK|ANYONECANPAY")},
{static_cast<unsigned char>(SIGHASH_NONE), std::string("NONE")},
{static_cast<unsigned char>(SIGHASH_NONE|SIGHASH_ANYONECANPAY), std::string("NONE|ANYONECANPAY")},
{static_cast<unsigned char>(SIGHASH_NONE|SIGHASH_SBTC_FORK), std::string("NONE|SBTC_FORK|ANYONECANPAY")},
{static_cast<unsigned char>(SIGHASH_NONE|SIGHASH_SBTC_FORK|SIGHASH_ANYONECANPAY), std::string("NONE|SBTC_FORK|ANYONECANPAY")},
{static_cast<unsigned char>(SIGHASH_SINGLE), std::string("SINGLE")},
{static_cast<unsigned char>(SIGHASH_SINGLE|SIGHASH_ANYONECANPAY), std::string("SINGLE|ANYONECANPAY")},
{static_cast<unsigned char>(SIGHASH_SINGLE|SIGHASH_SBTC_FORK), std::string("SINGLE|SBTC_FORK")},
{static_cast<unsigned char>(SIGHASH_SINGLE|SIGHASH_SBTC_FORK|SIGHASH_ANYONECANPAY), std::string("SINGLE|SBTC_FORK|ANYONECANPAY")},
};

/**
Expand Down Expand Up @@ -102,7 +105,14 @@ std::string ScriptToAsmStr(const CScript& script, const bool fAttemptSighashDeco
// this won't decode correctly formatted public keys in Pubkey or Multisig scripts due to
// the restrictions on the pubkey formats (see IsCompressedOrUncompressedPubKey) being incongruous with the
// checks in CheckSignatureEncoding.
if (CheckSignatureEncoding(vch, SCRIPT_VERIFY_STRICTENC, nullptr)) {
uint32_t flags = SCRIPT_VERIFY_STRICTENC;
if (vch.back() & SIGHASH_SBTC_FORK) {
// If the transaction is using SIGHASH_FORKID, we need
// to set the apropriate flag.
// TODO: Remove after the Hard Fork.
flags |= SCRIPT_ENABLE_SIGHASH_SBTC_FORK;
}
if (CheckSignatureEncoding(vch,flags , nullptr)) {
const unsigned char chSigHashType = vch.back();
if (mapSigHashTypes.count(chSigHashType)) {
strSigHashDecode = "[" + mapSigHashTypes.find(chSigHashType)->second + "]";
Expand Down
2 changes: 1 addition & 1 deletion src/miner.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,7 @@ std::unique_ptr<CBlockTemplate> BlockAssembler::CreateNewBlock(const CScript& sc

int nPackagesSelected = 0;
int nDescendantsUpdated = 0;
addPackageTxs(nPackagesSelected, nDescendantsUpdated);
addPackageTxs(nPackagesSelected, nDescendantsUpdated);

int64_t nTime1 = GetTimeMicros();

Expand Down
3 changes: 2 additions & 1 deletion src/policy/policy.h
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,8 @@ static const unsigned int STANDARD_SCRIPT_VERIFY_FLAGS = MANDATORY_SCRIPT_VERIFY
SCRIPT_VERIFY_LOW_S |
SCRIPT_VERIFY_WITNESS |
SCRIPT_VERIFY_DISCOURAGE_UPGRADABLE_WITNESS_PROGRAM |
SCRIPT_VERIFY_WITNESS_PUBKEYTYPE;
SCRIPT_VERIFY_WITNESS_PUBKEYTYPE|
SCRIPT_ENABLE_SIGHASH_SBTC_FORK;

/** For convenience, standard but not mandatory verify flags. */
static const unsigned int STANDARD_NOT_MANDATORY_VERIFY_FLAGS = STANDARD_SCRIPT_VERIFY_FLAGS & ~MANDATORY_SCRIPT_VERIFY_FLAGS;
Expand Down
112 changes: 112 additions & 0 deletions src/pow.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,18 @@
#include "chain.h"
#include "primitives/block.h"
#include "uint256.h"
#include "validation.h"

unsigned int GetNextWorkRequired(const CBlockIndex* pindexLast, const CBlockHeader *pblock, const Consensus::Params& params)
{
assert(pindexLast != nullptr);
unsigned int nProofOfWorkLimit = UintToArith256(params.powLimit).GetCompact();

// active sbtc difficulty ajustment
if(IsSBTCForkEnabled(params, pindexLast)) {
return GetNextSBTCWorkRequired(pindexLast, pblock, params);
}

// Only change once per difficulty adjustment interval
if ((pindexLast->nHeight+1) % params.DifficultyAdjustmentInterval() != 0)
{
Expand Down Expand Up @@ -89,3 +95,109 @@ bool CheckProofOfWork(uint256 hash, unsigned int nBits, const Consensus::Params&

return true;
}


unsigned int GetNextSBTCWorkRequired(const CBlockIndex *pindexPrev,
const CBlockHeader *pblock,
const Consensus::Params& params) {
// This cannot handle the genesis block and early blocks in general.
assert(pindexPrev);

// Special difficulty rule for testnet:
// If the new block's timestamp is more than 2* 10 minutes then allow
// mining of a min-difficulty block.
if (params.fPowAllowMinDifficultyBlocks &&
(pblock->GetBlockTime() >
pindexPrev->GetBlockTime() + 2 * params.nPowTargetSpacing)) {
return UintToArith256(params.powLimit).GetCompact();
}

// Compute the difficulty based on the full adjustment interval.
const uint32_t nHeight = pindexPrev->nHeight;
assert(nHeight >= params.DifficultyAdjustmentInterval());

// Get the last suitable block of the difficulty interval.
const CBlockIndex *pindexLast = GetSuitableBlock(pindexPrev);
assert(pindexLast);

// Get the first suitable block of the difficulty interval.
uint32_t nHeightFirst = nHeight - 144;
const CBlockIndex *pindexFirst =
GetSuitableBlock(pindexPrev->GetAncestor(nHeightFirst));
assert(pindexFirst);

// Compute the target based on time and work done during the interval.
const arith_uint256 nextTarget =
ComputeTarget(pindexFirst, pindexLast, params);

const arith_uint256 powLimit = UintToArith256(params.powLimit);
if (nextTarget > powLimit) {
return powLimit.GetCompact();
}

return nextTarget.GetCompact();
}

const CBlockIndex *GetSuitableBlock(const CBlockIndex *pindex) {
assert(pindex->nHeight >= 3);

/**
* In order to avoid a block with a very skewed timestamp having too much
* influence, we select the median of the 3 top most blocks as a starting
* point.
*/
const CBlockIndex *blocks[3];
blocks[2] = pindex;
blocks[1] = pindex->pprev;
blocks[0] = blocks[1]->pprev;

// Sorting network.
if (blocks[0]->nTime > blocks[2]->nTime) {
std::swap(blocks[0], blocks[2]);
}

if (blocks[0]->nTime > blocks[1]->nTime) {
std::swap(blocks[0], blocks[1]);
}

if (blocks[1]->nTime > blocks[2]->nTime) {
std::swap(blocks[1], blocks[2]);
}

// We should have our candidate in the middle now.
return blocks[1];
}


arith_uint256 ComputeTarget(const CBlockIndex *pindexFirst,
const CBlockIndex *pindexLast,
const Consensus::Params &params) {
assert(pindexLast->nHeight > pindexFirst->nHeight);

/**
* From the total work done and the time it took to produce that much work,
* we can deduce how much work we expect to be produced in the targeted time
* between blocks.
*/
arith_uint256 work = pindexLast->nChainWork - pindexFirst->nChainWork;
work *= params.nPowTargetSpacing;

// In order to avoid difficulty cliffs, we bound the amplitude of the
// adjustment we are going to do to a factor in [0.5, 2].
int64_t nActualTimespan =
int64_t(pindexLast->nTime) - int64_t(pindexFirst->nTime);
if (nActualTimespan > 288 * params.nPowTargetSpacing) {
nActualTimespan = 288 * params.nPowTargetSpacing;
} else if (nActualTimespan < 72 * params.nPowTargetSpacing) {
nActualTimespan = 72 * params.nPowTargetSpacing;
}

work /= nActualTimespan;

/**
* We need to compute T = (2^256 / W) - 1 but 2^256 doesn't fit in 256 bits.
* By expressing 1 as W / W, we get (2^256 - W) / W, and we can compute
* 2^256 - W as the complement of W.
*/
return (-work) / work;
}
5 changes: 5 additions & 0 deletions src/pow.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,16 @@
class CBlockHeader;
class CBlockIndex;
class uint256;
class arith_uint256;

unsigned int GetNextWorkRequired(const CBlockIndex* pindexLast, const CBlockHeader *pblock, const Consensus::Params&);
unsigned int CalculateNextWorkRequired(const CBlockIndex* pindexLast, int64_t nFirstBlockTime, const Consensus::Params&);

/** Check whether a block hash satisfies the proof-of-work requirement specified by nBits */
bool CheckProofOfWork(uint256 hash, unsigned int nBits, const Consensus::Params&);

const CBlockIndex *GetSuitableBlock(const CBlockIndex *pindex);
unsigned int GetNextSBTCWorkRequired(const CBlockIndex *pindexPrev, const CBlockHeader *pblock, const Consensus::Params& params);
arith_uint256 ComputeTarget(const CBlockIndex *pindexFirst, const CBlockIndex *pindexLast, const Consensus::Params &params);

#endif // BITCOIN_POW_H
20 changes: 13 additions & 7 deletions src/rpc/rawtransaction.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -824,15 +824,21 @@ UniValue signrawtransaction(const JSONRPCRequest& request)
const CKeyStore& keystore = tempKeystore;
#endif

int nHashType = SIGHASH_ALL;
int nHashType = SIGHASH_ALL | SIGHASH_SBTC_FORK;
if (request.params.size() > 3 && !request.params[3].isNull()) {
static std::map<std::string, int> mapSigHashValues = {
{std::string("ALL"), int(SIGHASH_ALL)},
{std::string("ALL|ANYONECANPAY"), int(SIGHASH_ALL|SIGHASH_ANYONECANPAY)},
{std::string("NONE"), int(SIGHASH_NONE)},
{std::string("NONE|ANYONECANPAY"), int(SIGHASH_NONE|SIGHASH_ANYONECANPAY)},
{std::string("SINGLE"), int(SIGHASH_SINGLE)},
{std::string("SINGLE|ANYONECANPAY"), int(SIGHASH_SINGLE|SIGHASH_ANYONECANPAY)},
{std::string("ALL"), int(SIGHASH_ALL)},
{std::string("ALL|ANYONECANPAY"), int(SIGHASH_ALL|SIGHASH_ANYONECANPAY)},
{std::string("ALL|SBTC_FORK"), int(SIGHASH_ALL|SIGHASH_SBTC_FORK)},
{std::string("ALL|SBTC_FORK|ANYONECANPAY"), int(SIGHASH_ALL|SIGHASH_SBTC_FORK|SIGHASH_ANYONECANPAY)},
{std::string("NONE"), int(SIGHASH_NONE)},
{std::string("NONE|ANYONECANPAY"), int(SIGHASH_NONE|SIGHASH_ANYONECANPAY)},
{std::string("NONE|SBTC_FORK"), int(SIGHASH_NONE|SIGHASH_SBTC_FORK)},
{std::string("NONE|SBTC_FORK|ANYONECANPAY"), int(SIGHASH_NONE|SIGHASH_SBTC_FORK|SIGHASH_ANYONECANPAY)},
{std::string("SINGLE"), int(SIGHASH_SINGLE)},
{std::string("SINGLE|ANYONECANPAY"), int(SIGHASH_SINGLE|SIGHASH_ANYONECANPAY)},
{std::string("SINGLE|SBTC_FORK"), int(SIGHASH_SINGLE|SIGHASH_SBTC_FORK)},
{std::string("SINGLE|SBTC_FORK|ANYONECANPAY"), int(SIGHASH_SINGLE|SIGHASH_SBTC_FORK|SIGHASH_ANYONECANPAY)},
};
std::string strHashType = request.params[3].get_str();
if (mapSigHashValues.count(strHashType))
Expand Down
24 changes: 20 additions & 4 deletions src/script/interpreter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -185,7 +185,7 @@ bool static IsDefinedHashtypeSignature(const valtype &vchSig) {
if (vchSig.size() == 0) {
return false;
}
unsigned char nHashType = vchSig[vchSig.size() - 1] & (~(SIGHASH_ANYONECANPAY));
unsigned char nHashType = vchSig[vchSig.size() - 1] & (~(SIGHASH_ANYONECANPAY | SIGHASH_SBTC_FORK));
if (nHashType < SIGHASH_ALL || nHashType > SIGHASH_SINGLE)
return false;

Expand All @@ -200,11 +200,27 @@ bool CheckSignatureEncoding(const std::vector<unsigned char> &vchSig, unsigned i
}
if ((flags & (SCRIPT_VERIFY_DERSIG | SCRIPT_VERIFY_LOW_S | SCRIPT_VERIFY_STRICTENC)) != 0 && !IsValidSignatureEncoding(vchSig)) {
return set_error(serror, SCRIPT_ERR_SIG_DER);
} else if ((flags & SCRIPT_VERIFY_LOW_S) != 0 && !IsLowDERSignature(vchSig, serror)) {
}
if ((flags & SCRIPT_VERIFY_LOW_S) != 0 && !IsLowDERSignature(vchSig, serror)) {
// serror is set
return false;
} else if ((flags & SCRIPT_VERIFY_STRICTENC) != 0 && !IsDefinedHashtypeSignature(vchSig)) {
return set_error(serror, SCRIPT_ERR_SIG_HASHTYPE);
}
if ((flags & SCRIPT_VERIFY_STRICTENC) != 0) {
if(!IsDefinedHashtypeSignature(vchSig)) {
return set_error(serror, SCRIPT_ERR_SIG_HASHTYPE);
}
unsigned char nHashType = vchSig[vchSig.size() - 1];
bool sbtcForkHash = nHashType & SIGHASH_SBTC_FORK;
bool sbtcforkEnabled = flags & SCRIPT_ENABLE_SIGHASH_SBTC_FORK;

if(!sbtcForkHash && sbtcforkEnabled) {
return set_error(serror, SCRIPT_ERR_ILLEGAL_SBTC_FORKID);
}

if(sbtcForkHash&& !sbtcforkEnabled) {
return set_error(serror, SCRIPT_ERR_ILLEGAL_SBTC_FORKID);
}

}
return true;
}
Expand Down
Loading

0 comments on commit 33c79d1

Please sign in to comment.