Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion configure.ac
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ AC_PREREQ([2.69])
define(_CLIENT_VERSION_MAJOR, 3)
define(_CLIENT_VERSION_MINOR, 4)
define(_CLIENT_VERSION_REVISION, 2)
define(_CLIENT_VERSION_BUILD, 3)
define(_CLIENT_VERSION_BUILD, 11)
define(_CLIENT_VERSION_RC, 0)
define(_CLIENT_VERSION_IS_RELEASE, true)
define(_COPYRIGHT_YEAR, 2023)
Expand Down
4 changes: 2 additions & 2 deletions doc/build-unix.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ Run the following commands to install required packages:

##### Debian/Ubuntu:
```bash
$ sudo apt-get install curl build-essential libtool autotools-dev automake pkg-config python3 bsdmainutils
$ sudo apt-get install curl build-essential libtool autotools-dev automake pkg-config python3 bsdmainutils libevent-dev libgmp-dev
```

##### Fedora:
Expand Down Expand Up @@ -158,4 +158,4 @@ If your user is in the `staff` group the limit can be raised with:

The change will only affect the current shell and processes spawned by it. To
make the change system-wide, change `datasize-cur` and `datasize-max` in
`/etc/login.conf`, and reboot.
`/etc/login.conf`, and reboot.
48 changes: 35 additions & 13 deletions src/chainparams.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,7 @@ static CBlock FindDevNetGenesisBlock(const CBlock &prevBlock, const CAmount& rew
// iteration of the above loop will give a result already
error("FindDevNetGenesisBlock: could not find devnet genesis block for %s", devNetName);
assert(false);
return block;
}

void CChainParams::AddLLMQ(Consensus::LLMQType llmqType)
Expand Down Expand Up @@ -344,9 +345,23 @@ class CMainParams : public CChainParams {
nPoolMaxParticipants = 5;
nFulfilledRequestExpireTime = 60*60; // fulfilled requests expire in 1 hour

vSporkAddressesV1 = {"sJbcSRccZQfmgjeW28uEEh9PswngZj1RXb"};
vSporkAddressesV2 = {"sRSMpxfoejLYu7Y7Jd44MPfK76ap6cnXUR"};
nMinSporkKeys = 1;
vSporkAddressesV1 = {
"sJbcSRccZQfmgjeW28uEEh9PswngZj1RXb" // o
};
vSporkAddressesV2 = {
"sJbcSRccZQfmgjeW28uEEh9PswngZj1RXb", // o
"sRSMpxfoejLYu7Y7Jd44MPfK76ap6cnXUR", // c
"seHPSLpCmMxTKLSeaBaAvEMZgyk39xCA3q", // s
"sMXHsSGHCVJAfsebfs3g3g1hRcTioWTjBo" // d
};
vSporkAddressesV3 = {
"sRSMpxfoejLYu7Y7Jd44MPfK76ap6cnXUR", // c
"seHPSLpCmMxTKLSeaBaAvEMZgyk39xCA3q", // s
"sMXHsSGHCVJAfsebfs3g3g1hRcTioWTjBo" // d
};
nMinSporkKeysV1 = 1;
nMinSporkKeysV3 = 2;

fBIP9CheckMasternodesUpgraded = true;

/**
Expand Down Expand Up @@ -410,16 +425,17 @@ class CMainParams : public CChainParams {
{700000, uint256S("000000000361299a95ea6a73d9a202a94893b3ec4fb441330740e20f9748cf36")},
{703355, uint256S("0000000002354cfaeb716435d7cfa632651f32ea22ef9796d25b893e264b2ea5")},
{703363, uint256S("00000000013b1c713a1ae71e6328f0f21efa08c7b8432d40bce681e4588645c4")},
// 2023/09
{717100, uint256S("0000000003189edcd28335b5e8bbb00752bad82c01c87604f4614ef103b14b24")}
// 2023/10
{750001, uint256S("00000000006ed565d981c2ba21d19fd1b655847fa156e8a1da4647a33bbb5b74")},
{750222, uint256S("000000000106b46906143c81532016eb1dcccf9859f3e1fc4f249c797f0c36ac")}
}
};

chainTxData = ChainTxData{
1692077442, // * UNIX timestamp of last known number of transactions (Block 1)
703363, // * total number of transactions between genesis and that timestamp
1697678866, // * UNIX timestamp of last known number of transactions (Block 750222)
1498527, // * total number of transactions between genesis and that timestamp
// (the tx=... number in the SetBestChain debug.log lines)
0.0153 // * estimated number of transactions per second after that timestamp
0.0208 // * estimated number of transactions per second after that timestamp
};
}
};
Expand Down Expand Up @@ -589,8 +605,10 @@ class CTestNetParams : public CChainParams {
nFulfilledRequestExpireTime = 5*60; // fulfilled requests expire in 5 minutes

vSporkAddressesV1 = {"yjPtiKh2uwk3bDutTEA2q9mCtXyiZRWn55"};
vSporkAddressesV2 = {"yaBHHsZP4MthVVexFXiLgzUw7mwzxY9KRF"};
nMinSporkKeys = 1;
vSporkAddressesV2 = {"yjPtiKh2uwk3bDutTEA2q9mCtXyiZRWn55", "yaBHHsZP4MthVVexFXiLgzUw7mwzxY9KRF"};
vSporkAddressesV3 = {"yaBHHsZP4MthVVexFXiLgzUw7mwzxY9KRF"};
nMinSporkKeysV1 = 1;
nMinSporkKeysV3 = 1;
fBIP9CheckMasternodesUpgraded = true;

checkpointData = {
Expand Down Expand Up @@ -778,9 +796,11 @@ class CDevNetParams : public CChainParams {
nPoolMaxParticipants = 20;
nFulfilledRequestExpireTime = 5*60; // fulfilled requests expire in 5 minutes

vSporkAddressesV1 = {"yjPtiKh2uwk3bDutTEA2q9mCtXyiZRWn55"};
vSporkAddressesV1 = {"yaBHHsZP4MthVVexFXiLgzUw7mwzxY9KRF"};
vSporkAddressesV2 = {"yaBHHsZP4MthVVexFXiLgzUw7mwzxY9KRF"};
nMinSporkKeys = 1;
vSporkAddressesV3 = {"yaBHHsZP4MthVVexFXiLgzUw7mwzxY9KRF"};
nMinSporkKeysV1 = 1;
nMinSporkKeysV3 = 1;
// devnets are started with no blocks and no MN, so we can't check for upgraded MN (as there are none)
fBIP9CheckMasternodesUpgraded = false;

Expand Down Expand Up @@ -959,7 +979,9 @@ class CRegTestParams : public CChainParams {
// privKey: cP4EKFyJsHT39LDqgdcB43Y3YXjNyjb5Fuas1GQSeAtjnZWmZEQK
vSporkAddressesV1 = {"yj949n1UH6fDhw6HtVE5VMj2iSTaSWBMcW"};
vSporkAddressesV2 = {"yj949n1UH6fDhw6HtVE5VMj2iSTaSWBMcW"};
nMinSporkKeys = 1;
vSporkAddressesV3 = {"yj949n1UH6fDhw6HtVE5VMj2iSTaSWBMcW"};
nMinSporkKeysV1 = 1;
nMinSporkKeysV3 = 1;
// regtest usually has no masternodes in most tests, so don't check for upgraged MNs
fBIP9CheckMasternodesUpgraded = false;

Expand Down
8 changes: 6 additions & 2 deletions src/chainparams.h
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,9 @@ class CChainParams
int FulfilledRequestExpireTime() const { return nFulfilledRequestExpireTime; }
const std::vector<std::string>& SporkAddressesV1() const { return vSporkAddressesV1; }
const std::vector<std::string>& SporkAddressesV2() const { return vSporkAddressesV2; }
int MinSporkKeys() const { return nMinSporkKeys; }
const std::vector<std::string>& SporkAddressesV3() const { return vSporkAddressesV3; }
int MinSporkKeysV1() const { return nMinSporkKeysV1; }
int MinSporkKeysV3() const { return nMinSporkKeysV3; }
bool BIP9CheckMasternodesUpgraded() const { return fBIP9CheckMasternodesUpgraded; }
const Consensus::LLMQParams& GetLLMQ(Consensus::LLMQType llmqType) const;
bool HasLLMQ(Consensus::LLMQType llmqType) const;
Expand Down Expand Up @@ -144,7 +146,9 @@ class CChainParams
int nFulfilledRequestExpireTime;
std::vector<std::string> vSporkAddressesV1;
std::vector<std::string> vSporkAddressesV2;
int nMinSporkKeys;
std::vector<std::string> vSporkAddressesV3;
int nMinSporkKeysV1;
int nMinSporkKeysV3;
bool fBIP9CheckMasternodesUpgraded;

void AddLLMQ(Consensus::LLMQType llmqType);
Expand Down
34 changes: 17 additions & 17 deletions src/init.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1685,20 +1685,19 @@ bool AppInitMain(InitInterfaces& interfaces)
if (gArgs.IsArgSet("-sporkaddr")) {
vSporkAddresses = gArgs.GetArgs("-sporkaddr");
} else {
vSporkAddresses = Params().SporkAddressesV1();
vSporkAddresses = chainparams.SporkAddressesV1();
}
for (const auto& address: vSporkAddresses) {
if (!sporkManager.SetSporkAddress(address)) {
return InitError(_("Invalid spork address specified with -sporkaddr").translated);
}
}

int minsporkkeys = gArgs.GetArg("-minsporkkeys", Params().MinSporkKeys());
int minsporkkeys = gArgs.GetArg("-minsporkkeys", chainparams.MinSporkKeysV1());
if (!sporkManager.SetMinSporkKeys(minsporkkeys)) {
return InitError(_("Invalid minimum number of spork signers specified with -minsporkkeys").translated);
}


if (gArgs.IsArgSet("-sporkkey")) { // spork priv key
if (!sporkManager.SetPrivKey(gArgs.GetArg("-sporkkey", ""))) {
return InitError(_("Unable to sign spork message, wrong key?").translated);
Expand Down Expand Up @@ -2492,35 +2491,36 @@ bool AppInitMain(InitInterfaces& interfaces)

// ********************************************************* Step 12.1: uprade sporks

if (chain_active_height >= 750000 && chainparams.NetworkIDString() == CBaseChainParams::MAIN) {
if (chain_active_height < sporkManager.getNewSporkLockHeight()) {
LogPrintf("[init] CSporkManager -- Spork V3 Activation Height: %d Lock Height: %d\n", sporkManager.getNewSporkActHeight(), sporkManager.getNewSporkLockHeight());
}
if (chain_active_height >= sporkManager.getNewSporkActHeight() && chainparams.NetworkIDString() == CBaseChainParams::MAIN) {
std::vector<std::string> vSporkAddresses;
if (gArgs.IsArgSet("-sporkaddr")) {
vSporkAddresses = gArgs.GetArgs("-sporkaddr");
} else if (chain_active_height >= sporkManager.getNewSporkLockHeight()) {
vSporkAddresses = Params().SporkAddressesV3();
LogPrintf("Using V3 Spork Addresses\n");
} else {
vSporkAddresses = Params().SporkAddressesV2();
LogPrintf("Using V2 Spork Addresses\n");
}
sporkManager.ClearSporkAddresses();
for (const auto& address : vSporkAddresses) {
if (!sporkManager.SetSporkAddress(address)) {
return InitError(_("Invalid spork address specified with -sporkaddr").translated);
}
}
LogPrintf("Using V2 Spork Addresses\n");
}
if (chain_active_height >= 7500 && chainparams.NetworkIDString() == CBaseChainParams::TESTNET) {
std::vector<std::string> vSporkAddresses;
if (gArgs.IsArgSet("-sporkaddr")) {
vSporkAddresses = gArgs.GetArgs("-sporkaddr");
} else {
vSporkAddresses = Params().SporkAddressesV2();
if (!gArgs.IsArgSet("-sporkaddr")) {
if (!sporkManager.CheckSporkPubkeyIDs()) {
LogPrintf("CSporkManager -- WARN: mismatched spork addresses have been updated!\n");
}
}
sporkManager.ClearSporkAddresses();
for (const auto& address : vSporkAddresses) {
if (!sporkManager.SetSporkAddress(address)) {
return InitError(_("Invalid spork address specified with -sporkaddr").translated);
if (chain_active_height >= sporkManager.getNewSporkLockHeight()) {
if (!sporkManager.SetMinSporkKeys(Params().MinSporkKeysV3())) {
return InitError(_("Invalid minimum number of spork signers specified for V3!").translated);
}
}
LogPrintf("Using V2 Spork Addresses\n");
}

// ********************************************************* Step 13: finished
Expand Down
68 changes: 67 additions & 1 deletion src/spork.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,9 @@ void CSporkManager::CheckAndRemove()

void CSporkManager::ProcessSporkMessages(CNode* pfrom, std::string_view strCommand, CDataStream& vRecv, CConnman& connman)
{
if (!CheckSporkPubkeyIDs()) {
LogPrintf("CSporkManager::ProcessSporkMessages -- WARN: updated mismatching spork addresses\n");
}
ProcessSpork(pfrom, strCommand, vRecv, connman);
ProcessGetSporks(pfrom, strCommand, connman);
}
Expand Down Expand Up @@ -134,7 +137,11 @@ void CSporkManager::ProcessSpork(const CNode* pfrom, std::string_view strCommand
if (!spork.GetSignerKeyID(keyIDSigner) || WITH_LOCK(cs, return !setSporkPubKeyIDs.count(keyIDSigner))) {
LOCK(cs_main);
LogPrint(BCLog::SPORK, "CSporkManager::ProcessSpork -- ERROR: invalid signature\n");
Misbehaving(pfrom->GetId(), 100);

int nHeight = ::ChainActive().Tip()->nHeight;
if (nHeight > nNewSporkLockHeight) {
Misbehaving(pfrom->GetId(), 100);
}
return;
}

Expand Down Expand Up @@ -329,6 +336,65 @@ bool CSporkManager::SetPrivKey(const std::string& strPrivKey)
return true;
}

bool CSporkManager::CheckSporkPubkeyIDs()
{
const CChainParams& params = Params();
if (!::ChainActive().Tip() || params.NetworkIDString() != CBaseChainParams::MAIN)
{
return true;
}

int nHeight = ::ChainActive().Tip()->nHeight;
if (nHeight > nNewSporkLockHeight) {
// change completed. spork changes locked.
return true;
}

if (nHeight >= nNewSporkActHeight) { // start of checks
std::vector<std::string> vSporkAddresses = params.SporkAddressesV2();
bool fLocking = false;
bool matches = true;
int nFound = 0;
if (nHeight >= nNewSporkLockHeight - 200) { // act shortly before lockout
vSporkAddresses = params.SporkAddressesV3();
fLocking = true;
}
LOCK(cs);
for (const auto& strAddress : vSporkAddresses) {
CTxDestination dest = DecodeDestination(strAddress);
const CKeyID* keyID = boost::get<CKeyID>(&dest);
if (!keyID) {
LogPrintf("CSporkManager::CheckSporkPubkeyIDs -- Failed to parse spork address\n");
matches = false;
} else if (setSporkPubKeyIDs.find(*keyID) == setSporkPubKeyIDs.end()) {
LogPrintf("CSporkManager::CheckSporkPubkeyIDs -- WARN: spork address %s not found\n", strAddress);
matches = false;
} else {
nFound++;
}
}
if (nFound != setSporkPubKeyIDs.size()) {
LogPrintf("CSporkManager::CheckSporkPubkeyIDs -- WARN: spork address set length mismatch\n");
matches = false;
}
if (!matches) {
sporkManager.ClearSporkAddresses();
for (const auto& address : vSporkAddresses) {
if (!sporkManager.SetSporkAddress(address)) {
LogPrintf("CSporkManager::CheckSporkPubkeyIDs -- ERROR: invalid spork address\n");
}
}
if (fLocking) {
nMinSporkKeys = params.MinSporkKeysV3();
} else {
nMinSporkKeys = params.MinSporkKeysV1();
}
return false;
}
}
return true;
}

std::string CSporkManager::ToString() const
{
LOCK(cs);
Expand Down
16 changes: 16 additions & 0 deletions src/spork.h
Original file line number Diff line number Diff line change
Expand Up @@ -180,6 +180,9 @@ class CSporkManager
*/
bool SporkValueIsActive(SporkId nSporkID, int64_t& nActiveValueRet) const EXCLUSIVE_LOCKS_REQUIRED(cs);

int nNewSporkActHeight = 755040;
int nNewSporkLockHeight = 775200;

public:

CSporkManager() = default;
Expand Down Expand Up @@ -317,6 +320,19 @@ class CSporkManager
*/
bool SetPrivKey(const std::string& strPrivKey);

/**
* CheckSporkPubkeyIDs is used to check the pubkeys for spork signers
* match the expected. Will update the list if there is mismatching.
*
* This will return true if there are no mismatches.
*/
bool CheckSporkPubkeyIDs();

/* Gets height the new sporks should become active. */
int getNewSporkActHeight() { return nNewSporkActHeight; };
/* Gets height the new sporks should lock. Used for ban control. */
int getNewSporkLockHeight() { return nNewSporkLockHeight; };

/**
* ToString returns the string representation of the SporkManager.
*/
Expand Down