Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Tpos signature hf #154

Merged
merged 25 commits into from
Sep 18, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
60e7bdb
Added HF for new tpos and block signatures. Updated protocol versions…
durkmurder Aug 12, 2020
a314026
Fixed typo with HF check
durkmurder Aug 12, 2020
a6bcdf5
Fixed regtest for PoS. Code formatting
durkmurder Aug 13, 2020
e4e5350
Replaced icons and graphics. Fixed compilation issue with Qt 5.15.0
durkmurder Aug 13, 2020
ffa6720
Updated address prefixes for regtest
durkmurder Aug 14, 2020
f6ab52e
Refactoring. Introduced new version of tpos contract. Added support f…
durkmurder Aug 20, 2020
5ee0562
Added ability to create new tpos contracts
durkmurder Aug 20, 2020
9bc66b8
Added tests for tpos. Updated validation rules for contract transaction
durkmurder Aug 21, 2020
36b2e9d
Added more tests for HF and new contract. Added logic for parsing new…
durkmurder Aug 21, 2020
7a902f9
Added rpc calls for encoding payloads and displaying info about contract
durkmurder Aug 21, 2020
70e6b6f
Updated how signature is created for tpos contract
durkmurder Aug 22, 2020
753df43
Fixed parsing of legacy contracts
durkmurder Aug 24, 2020
71a7fd8
Minor refactoring
durkmurder Aug 24, 2020
a830381
Update version.h
durkmurder Aug 25, 2020
d96b9fc
Update checkblock.cpp
durkmurder Aug 25, 2020
c2959fb
Updated validity of contract. Small refactoring
durkmurder Aug 25, 2020
e2e0ff2
Refactroing. Added more tests for tpos
durkmurder Aug 25, 2020
1775be7
More updates to tpos tests
durkmurder Aug 31, 2020
7c61da6
Fixed issue with wrong reward calculations. Updated tests
durkmurder Aug 31, 2020
9944895
Fixed legacy contract serialization. Updated a few validation rules
durkmurder Sep 7, 2020
307d51f
Fixed handling of CMTBLOCK. Set HF date
durkmurder Sep 8, 2020
7247ba9
Merge branch 'master' of https://github.com/X9Developers/XSN into tpo…
durkmurder Sep 8, 2020
55478d1
Fixed compilation issues after merging with develop
durkmurder Sep 8, 2020
7b54eb7
Temporary changed version
durkmurder Sep 14, 2020
31297af
Updated version back
durkmurder Sep 14, 2020
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
4 changes: 2 additions & 2 deletions configure.ac
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,10 @@ dnl require autoconf 2.60 (AS_ECHO/AS_ECHO_N)
AC_PREREQ([2.60])
define(_CLIENT_VERSION_MAJOR, 1)
define(_CLIENT_VERSION_MINOR, 0)
define(_CLIENT_VERSION_REVISION, 21)
define(_CLIENT_VERSION_REVISION, 22)
define(_CLIENT_VERSION_BUILD, 0)
define(_CLIENT_VERSION_IS_RELEASE, true)
define(_COPYRIGHT_YEAR, 2019)
define(_COPYRIGHT_YEAR, 2020)
define(_COPYRIGHT_HOLDERS,[The %s developers])
define(_COPYRIGHT_HOLDERS_SUBSTITUTION,[[XSN Core]])
AC_INIT([XSN Core],[_CLIENT_VERSION_MAJOR._CLIENT_VERSION_MINOR._CLIENT_VERSION_REVISION],[https://github.com/xsn/xsn/issues],[xsn],[https://xsncore.org/])
Expand Down
1 change: 1 addition & 0 deletions src/Makefile.test.include
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@ BITCOIN_TESTS =\
test/timedata_tests.cpp \
test/torcontrol_tests.cpp \
test/transaction_tests.cpp \
test/tpos_tests.cpp \
test/txindex_tests.cpp \
test/txvalidation_tests.cpp \
test/txvalidationcache_tests.cpp \
Expand Down
1 change: 1 addition & 0 deletions src/XSNBtc.files
Original file line number Diff line number Diff line change
Expand Up @@ -431,6 +431,7 @@ test/test_xsn_fuzzy.cpp
test/test_xsn_main.cpp
test/timedata_tests.cpp
test/torcontrol_tests.cpp
test/tpos_tests.cpp
test/transaction_tests.cpp
test/txvalidation_tests.cpp
test/txvalidationcache_tests.cpp
Expand Down
49 changes: 30 additions & 19 deletions src/blocksigner.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,18 +20,19 @@ static CPubKey::InputScriptType GetScriptTypeFromDestination(const CTxDestinatio
return CPubKey::InputScriptType::SPENDUNKNOWN;
}

CBlockSigner::CBlockSigner(CBlock &block, const CKeyStore *keystore, const TPoSContract &contract) :
CBlockSigner::CBlockSigner(CBlock &block, const CKeyStore *keystore, const TPoSContract &contract, int chainHeight) :
refBlock(block),
refKeystore(keystore),
refContract(contract)
refContract(contract),
nChainHeight(chainHeight)
{

}

bool CBlockSigner::SignBlock()
{
CKey keySecret;
CPubKey::InputScriptType scriptType;
CPubKey::InputScriptType scriptType { CPubKey::InputScriptType::SPENDUNKNOWN };

if(refBlock.IsProofOfStake())
{
Expand All @@ -45,15 +46,18 @@ bool CBlockSigner::SignBlock()

if(refBlock.IsTPoSBlock())
{
CKeyID merchantKeyID;
if(!refContract.merchantAddress.GetKeyID(merchantKeyID))
if(!refContract.scriptMerchantAddress.IsPayToPublicKeyHash()) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would you mind elaborating why is this required?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Currently we accept merchant addresses only in P2PKH format, so we avoid signing blocks that would get rejected

return error("CBlockSigner::SignBlock() : merchant address is not P2PKH, critical error, can't accept.");
}

CTxDestination dest;
ExtractDestination(refContract.scriptMerchantAddress, dest);

if(merchantKeyID != activeMerchantnode.pubKeyMerchantnode.GetID())
if(dest != CTxDestination(activeMerchantnode.pubKeyMerchantnode.GetID())) {
return error("CBlockSigner::SignBlock() : contract address is different from merchantnode address, won't sign.");
}

scriptType = CPubKey::InputScriptType::SPENDP2PKH;

keySecret = activeMerchantnode.keyMerchantnode;
}
else
Expand All @@ -69,8 +73,13 @@ bool CBlockSigner::SignBlock()
scriptType = GetScriptTypeFromDestination(destination);
}
}
//?
return CHashSigner::SignHash(refBlock.IsTPoSBlock() ? refBlock.GetTPoSHash() : refBlock.GetHash(), keySecret, scriptType, refBlock.vchBlockSig);

const auto &hash = refBlock.IsTPoSBlock() ? refBlock.GetTPoSHash() : refBlock.GetHash();
if (IsTPoSNewSignaturesHardForkActivated(nChainHeight)) {
return CMessageSigner::SignMessage(std::string(hash.begin(), hash.end()), refBlock.vchBlockSig, keySecret, scriptType);
} else {
return CHashSigner::SignHash(hash, keySecret, scriptType, refBlock.vchBlockSig);
}
}

bool CBlockSigner::CheckBlockSignature() const
Expand All @@ -85,24 +94,26 @@ bool CBlockSigner::CheckBlockSignature() const

CTxDestination destination;

if(!ExtractDestination(txout.scriptPubKey, destination))
{
if(!ExtractDestination(txout.scriptPubKey, destination)) {
return error("CBlockSigner::CheckBlockSignature() : failed to extract destination from script: %s", txout.scriptPubKey.ToString());
}

auto hashMessage = refBlock.IsTPoSBlock() ? refBlock.GetTPoSHash() : refBlock.GetHash();
if(refBlock.IsProofOfStake())
{
if(refBlock.IsTPoSBlock())
{
destination = refContract.merchantAddress.Get();
if(refBlock.IsProofOfStake()) {
if(refBlock.IsTPoSBlock()) {
if (!ExtractDestination(refContract.scriptMerchantAddress, destination)) {
return error("CBlockSigner::CheckBlockSignature() : failed to extract destination from script: %s", refContract.scriptMerchantAddress.ToString());
}
}
}
else
{
else {
return true;
}

std::string strError;
return CHashSigner::VerifyHash(hashMessage, destination, refBlock.vchBlockSig, strError);
if (IsTPoSNewSignaturesHardForkActivated(nChainHeight)) {
return CMessageSigner::VerifyMessage(destination, refBlock.vchBlockSig, std::string(hashMessage.begin(), hashMessage.end()), strError);
} else {
return CHashSigner::VerifyHash(hashMessage, destination, refBlock.vchBlockSig, strError);
}
}
3 changes: 2 additions & 1 deletion src/blocksigner.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,14 @@ class CKeyStore;

struct CBlockSigner {

CBlockSigner(CBlock &block, const CKeyStore *keystore, const TPoSContract &contract);
CBlockSigner(CBlock &block, const CKeyStore *keystore, const TPoSContract &contract, int chainHeight);

bool SignBlock();
bool CheckBlockSignature() const;

CBlock &refBlock;
const CKeyStore *refKeystore;
const TPoSContract &refContract;
int nChainHeight{0};
};
#endif // BLOCKSIGNER_H
25 changes: 13 additions & 12 deletions src/chainparams.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,7 @@ class CMainParams : public CChainParams {
consensus.nPosTargetSpacing = 1 * 60; // XSN: 1 minutes
consensus.nPosTargetTimespan = 60 * 40;
consensus.nPoSUpdgradeHFHeight = 898488; // 4 December 2019
consensus.nTPoSSignatureUpgradeHFHeight = 1348224; // tpos signature update HF, 8 October 2020
consensus.nMerchantnodeMinimumConfirmations = 1;
consensus.nMasternodeMinimumConfirmations = 15;
consensus.nStakeMinAge = 60 * 60;
Expand All @@ -110,6 +111,7 @@ class CMainParams : public CChainParams {
consensus.nMaxBlockSpacingFixDeploymentHeight = 674980; // apprx 28 of June
consensus.fPowAllowMinDifficultyBlocks = false;
consensus.fPowNoRetargeting = false;
consensus.fPoSNoRetargeting = false;
consensus.nRuleChangeActivationThreshold = 1080; // 75% of 2016
consensus.nMinerConfirmationWindow = 1440; // nPowTargetTimespan / nPowTargetSpacing
consensus.vDeployments[Consensus::DEPLOYMENT_TESTDUMMY].bit = 28;
Expand Down Expand Up @@ -235,6 +237,7 @@ class CTestNetParams : public CChainParams {
consensus.nMasternodeMinimumConfirmations = 1;
consensus.nMerchantnodeMinimumConfirmations = 1;
consensus.fPowNoRetargeting = false;
consensus.fPoSNoRetargeting = false;
consensus.nPowKGWHeight = 4001; // nPowKGWHeight >= nPowDGWHeight means "no KGW"
consensus.nPowDGWHeight = 4001;
consensus.nMaxBlockSpacingFixDeploymentHeight = 0;
Expand Down Expand Up @@ -289,11 +292,6 @@ class CTestNetParams : public CChainParams {

vFixedSeeds.clear();
vSeeds.clear();
// nodes with support for servicebits filtering should be at the top
// vSeeds.emplace_back("testnet-seed.xsn.jonasschnelli.ch");
// vSeeds.emplace_back("seed.txsn.petertodd.org");
// vSeeds.emplace_back("seed.testnet.xsn.sprovoost.nl");
// vSeeds.emplace_back("testnet-seed.bluematt.me"); // Just a static list of stable node(s), only supports x9

base58Prefixes[PUBKEY_ADDRESS] = std::vector<unsigned char>(1,140);
base58Prefixes[SCRIPT_ADDRESS] = std::vector<unsigned char>(1,19);
Expand Down Expand Up @@ -360,13 +358,16 @@ class CRegTestParams : public CChainParams {
consensus.nPowTargetSpacing = 1 * 60; // XSN: 1 minutes
consensus.nPosTargetSpacing = 1 * 60; // PoSW: 1 minutes
consensus.nPosTargetTimespan = 60 * 40;
consensus.nPoSUpdgradeHFHeight = 0;
consensus.nTPoSSignatureUpgradeHFHeight = 80;
consensus.fPowAllowMinDifficultyBlocks = true;
consensus.fPowNoRetargeting = true;
consensus.fPoSNoRetargeting = true;
consensus.nPowKGWHeight = 4001; // nPowKGWHeight >= nPowDGWHeight means "no KGW"
consensus.nPowDGWHeight = 4001;
consensus.nLastPoWBlock = 75;
consensus.nMaxBlockSpacingFixDeploymentHeight = 0;
consensus.nStakeMinAge = 60 * 60;
consensus.nStakeMinAge = 60;
consensus.nStakeMaxAge = 60 * 60 * 24; // one day
consensus.nCoinbaseMaturity = 20;
consensus.nFirstBlocksEmpty = 0;
Expand Down Expand Up @@ -422,13 +423,13 @@ class CRegTestParams : public CChainParams {
0
};

base58Prefixes[PUBKEY_ADDRESS] = std::vector<unsigned char>(1,140);
base58Prefixes[SCRIPT_ADDRESS] = std::vector<unsigned char>(1,19);
base58Prefixes[SECRET_KEY] = std::vector<unsigned char>(1,239);
base58Prefixes[EXT_PUBLIC_KEY] = {0x04, 0x35, 0x87, 0xCF};
base58Prefixes[EXT_SECRET_KEY] = {0x04, 0x35, 0x83, 0x94};
base58Prefixes[PUBKEY_ADDRESS] = std::vector<unsigned char>(1,76);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are these changes actually needed? It was useful for testing but is it ok to keep the change? Also, I'd add the details to the README for using the regtest.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, should be ok, doesn't look too bad

base58Prefixes[SCRIPT_ADDRESS] = std::vector<unsigned char>(1,16);
base58Prefixes[SECRET_KEY] = std::vector<unsigned char>(1,204);
base58Prefixes[EXT_PUBLIC_KEY] = {0x04, 0x88, 0xB2, 0x1E};
base58Prefixes[EXT_SECRET_KEY] = {0x04, 0x88, 0xAD, 0xE4};

bech32_hrp = "bcrt";
bech32_hrp = "xc";

/* enable fallback fee on regtest */
m_fallback_fee_enabled = true;
Expand Down
2 changes: 2 additions & 0 deletions src/consensus/params.h
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@ struct Params {
uint256 powLimit;
bool fPowAllowMinDifficultyBlocks;
bool fPowNoRetargeting;
bool fPoSNoRetargeting;
int64_t nPowTargetSpacing;
int64_t nPowTargetTimespan;
int64_t nPosTargetSpacing;
Expand All @@ -101,6 +102,7 @@ struct Params {
int nTPoSContractSignatureDeploymentTime;
int nMaxBlockSpacingFixDeploymentHeight;
int nPoSUpdgradeHFHeight;
int nTPoSSignatureUpgradeHFHeight;
};
} // namespace Consensus

Expand Down
1 change: 1 addition & 0 deletions src/httpserver.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
#include <ui_interface.h>

#include <memory>
#include <queue>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
Expand Down
2 changes: 1 addition & 1 deletion src/interfaces/wallet.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -242,7 +242,7 @@ class WalletImpl : public Wallet
{
LOCK2(cs_main, m_wallet.cs_wallet);
auto pending = MakeUnique<PendingWalletTxImpl>(m_wallet);
if(!TPoSUtils::CreateTPoSTransaction(&m_wallet, pending->m_tx, pending->m_key, tpos_address, merchant_address, merchant_commission, fail_reason)) {
if(!TPoSUtils::CreateTPoSTransaction(&m_wallet, pending->m_tx, pending->m_key, tpos_address, merchant_address, merchant_commission, true, fail_reason)) {
return {};
}
return std::move(pending);
Expand Down
1 change: 0 additions & 1 deletion src/key_io.h
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,6 @@ class CBitcoinAddress {

CTxDestination Get() const;
bool GetKeyID(CKeyID &keyID) const;
bool GetIndexKey(uint160& hashBytes, int& type) const;
bool IsScript() const;
std::string ToString() const;

Expand Down
8 changes: 5 additions & 3 deletions src/masternode-payments.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1114,9 +1114,11 @@ void AdjustMasternodePayment(CMutableTransaction &tx, const CTxOut &txoutMastern
int i = tx.vout.size() - 2;
if(tposContract.IsValid()) // here we have 3 outputs, first as stake reward, second as tpos reward, third as MN reward
{
masternodePayment /= 100; // to calculate percentage
tx.vout[i - 1].nValue -= masternodePayment * tposContract.stakePercentage; // adjust reward for owner.
tx.vout[i].nValue -= masternodePayment * (100 - tposContract.stakePercentage); // adjust reward for merchant
tx.vout[i - 1].nValue -= TPoSUtils::GetOwnerPayment(masternodePayment, tposContract.nOperatorReward); // adjust reward for owner.
// it might be that last vout is masternode, since operator reward was 0
if (tx.vout[i].scriptPubKey == tposContract.scriptMerchantAddress) {
tx.vout[i].nValue -= TPoSUtils::GetOperatorPayment(masternodePayment, tposContract.nOperatorReward); // adjust reward for merchant
}
}
else // here we have 2 outputs, first as stake reward, second as MN reward
{
Expand Down