Skip to content

Commit

Permalink
Merge pull request #449
Browse files Browse the repository at this point in the history
48ac1cb Test for fee distribution when number of tokens (and thus threshold) changes (Zathras)
2bc7ea2 Pass block into NotifyTotalTokensChanged() (Zathras)
dae6a2d Protect against fee distribution when the cache is empty (Zathras)
8600316 Protect against zero valued fee distribution thresholds (Zathras)
e1887e8 Clean up following @dexX7's feedback (thanks!) (zathras-crypto)
1a404df Fix incorrect value from getTotalTokens when fees are cached (zathras-crypto)
88d9690 Narrow scope of UpdateDistributionThresholds() (zathras-crypto)
aedf526 Add back in zero check dropped while prepping commits (zathras-crypto)
c655dd2 Check whether a property ID is valid by inferring from next available ID, instead of fetching the SP (zathras-crypto)
ebe318a Only generate the SHA256 obfuscation hashes we need instead of 255 every time (zathras-crypto)
c268e83 Drop non-Omni transactions quicker by looking for marker/Exodus bytes directly in scriptPubKey hex (zathras-crypto)
ba9ac74 Skip calling HandleExodusPurchase() on mainnet after Exodus crowdsale closed (zathras-crypto)
8732e15 Add consensus hash for block 440,000 (zathras-crypto)
a50c30d Add seed blocks for 430,000 to 440,000 (zathras-crypto)
fc78462 Update MAX_SEED_BLOCKS to include seed blocks above 390,000 (zathras-crypto)
d411286 Return immediately from VerifyCheckpoint if block isn't a multiple of 10K (zathras-crypto)
  • Loading branch information
dexX7 committed Jan 24, 2017
2 parents 20fb4bf + 48ac1cb commit 651c1cc
Show file tree
Hide file tree
Showing 14 changed files with 434 additions and 38 deletions.
2 changes: 1 addition & 1 deletion src/omnicore/encoding.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ bool OmniCore_Encode_ClassB(const std::string& senderAddress, const CPubKey& red
unsigned int nNextByte = 0;
unsigned char chSeqNum = 1;
std::string strObfuscatedHashes[1+MAX_SHA256_OBFUSCATION_TIMES];
PrepareObfuscatedHashes(senderAddress, strObfuscatedHashes);
PrepareObfuscatedHashes(senderAddress, MAX_SHA256_OBFUSCATION_TIMES, strObfuscatedHashes);
while (nRemainingBytes > 0) {
int nKeys = 1; // Assume one key of data, because we have data remaining
if (nRemainingBytes > (PACKET_SIZE - 1)) { nKeys += 1; } // ... or enough data to embed in 2 keys
Expand Down
18 changes: 10 additions & 8 deletions src/omnicore/fees.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,16 +33,14 @@ int64_t COmniFeeCache::GetDistributionThreshold(const uint32_t &propertyId)
}

// Sets the distribution thresholds to total tokens for a property / OMNI_FEE_THRESHOLD
void COmniFeeCache::UpdateDistributionThresholds()
void COmniFeeCache::UpdateDistributionThresholds(uint32_t propertyId)
{
for (uint8_t ecosystem = 1; ecosystem <= 2; ecosystem++) {
uint32_t startPropertyId = (ecosystem == 1) ? 1 : TEST_ECO_PROPERTY_1;
for (uint32_t itPropertyId = startPropertyId; itPropertyId < _my_sps->peekNextSPID(ecosystem); itPropertyId++) {
int64_t distributionThreshold = getTotalTokens(itPropertyId) / OMNI_FEE_THRESHOLD;
distributionThresholds[itPropertyId] = distributionThreshold;
}
int64_t distributionThreshold = getTotalTokens(propertyId) / OMNI_FEE_THRESHOLD;
if (distributionThreshold <= 0) {
// protect against zero valued thresholds for low token count properties
distributionThreshold = 1;
}

distributionThresholds[propertyId] = distributionThreshold;
}

// Gets the current amount of the fee cache for a property
Expand Down Expand Up @@ -183,6 +181,10 @@ void COmniFeeCache::DistributeCache(const uint32_t &propertyId, int block)

int64_t cachedAmount = GetCachedAmount(propertyId);

if (cachedAmount == 0) {
PrintToLog("Aborting fee distribution for property %d, the fee cache is empty!\n", propertyId);
}

OwnerAddrType receiversSet;
if (isTestEcosystemProperty(propertyId)) {
receiversSet = STO_GetReceivers("FEEDISTRIBUTION", OMNI_PROPERTY_TMSC, cachedAmount);
Expand Down
2 changes: 1 addition & 1 deletion src/omnicore/fees.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ class COmniFeeCache : public CDBBase
void printAll();

// Sets the distribution thresholds to total tokens for a property / OMNI_FEE_THRESHOLD
void UpdateDistributionThresholds();
void UpdateDistributionThresholds(uint32_t propertyId);
// Returns the distribution threshold for a property
int64_t GetDistributionThreshold(const uint32_t &propertyId);
// Return a set containing fee cache history items
Expand Down
58 changes: 51 additions & 7 deletions src/omnicore/omnicore.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -348,6 +348,8 @@ int64_t mastercore::getTotalTokens(uint32_t propertyId, int64_t* n_owners_total)
owners++;
}
}
int64_t cachedFee = p_feecache->GetCachedAmount(propertyId);
totalTokens += cachedFee;
}

if (property.fixed) {
Expand Down Expand Up @@ -423,7 +425,7 @@ bool mastercore::update_tally_map(const std::string& who, uint32_t propertyId, i
* @param nTime The timestamp of the block to update the "Dev MSC" for
* @return The number of "Dev MSC" generated
*/
static int64_t calculate_and_update_devmsc(unsigned int nTime)
static int64_t calculate_and_update_devmsc(unsigned int nTime, int block)
{
// do nothing if before end of fundraiser
if (nTime < 1377993874) return 0;
Expand Down Expand Up @@ -458,6 +460,8 @@ static int64_t calculate_and_update_devmsc(unsigned int nTime)
exodus_prev = devmsc;
}

NotifyTotalTokensChanged(OMNI_PROPERTY_MSC, block);

return exodus_delta;
}

Expand All @@ -470,6 +474,13 @@ uint32_t mastercore::GetNextPropertyId(bool maineco)
}
}

// Perform any actions that need to be taken when the total number of tokens for a property ID changes
void NotifyTotalTokensChanged(uint32_t propertyId, int block)
{
p_feecache->UpdateDistributionThresholds(propertyId);
p_feecache->EvalCache(propertyId, block);
}

void CheckWalletUpdate(bool forceUpdate)
{
if (!WalletCacheUpdate()) {
Expand Down Expand Up @@ -556,6 +567,38 @@ int mastercore::GetEncodingClass(const CTransaction& tx, int nBlock)
bool hasOpReturn = false;
bool hasMoney = false;

/* Fast Search
* Perform a string comparison on hex for each scriptPubKey & look directly for Exodus hash160 bytes or omni marker bytes
* This allows to drop non-Omni transactions with less work
*/
std::string strClassC = "6f6d6e69";
std::string strClassAB = "76a914946cb2e08075bcbaf157e47bcb67eb2b2339d24288ac";
bool examineClosely = false;
for (unsigned int n = 0; n < tx.vout.size(); ++n) {
const CTxOut& output = tx.vout[n];
std::string strSPB = HexStr(output.scriptPubKey.begin(), output.scriptPubKey.end());
if (strSPB != strClassAB) { // not an exodus marker
if (nBlock < 395000) { // class C not enabled yet, no need to search for marker bytes
continue;
} else {
if (strSPB.find(strClassC) != std::string::npos) {
examineClosely = true;
break;
}
}
} else {
examineClosely = true;
break;
}
}

// Examine everything when not on mainnet
if (isNonMainNet()) {
examineClosely = true;
}

if (!examineClosely) return NO_MARKER;

for (unsigned int n = 0; n < tx.vout.size(); ++n) {
const CTxOut& output = tx.vout[n];

Expand Down Expand Up @@ -978,7 +1021,7 @@ static int parseTransaction(bool bRPConly, const CTransaction& wtx, int nBlock,

// ### PREPARE A FEW VARS ###
std::string strObfuscatedHashes[1+MAX_SHA256_OBFUSCATION_TIMES];
PrepareObfuscatedHashes(strSender, strObfuscatedHashes);
PrepareObfuscatedHashes(strSender, 1+nPackets, strObfuscatedHashes);
unsigned char packets[MAX_PACKETS][32];
unsigned int mdata_count = 0; // multisig data count

Expand Down Expand Up @@ -2274,7 +2317,11 @@ bool mastercore_handler_tx(const CTransaction& tx, int nBlock, unsigned int idx,
assert(mp_obj.getEncodingClass() != NO_MARKER);
assert(mp_obj.getSender().empty() == false);

fFoundTx |= HandleExodusPurchase(tx, nBlock, mp_obj.getSender(), nBlockTime);
// extra iteration of the outputs for every transaction, not needed on mainnet after Exodus closed
const CConsensusParams& params = ConsensusParams();
if (isNonMainNet() || nBlock <= params.LAST_EXODUS_BLOCK) {
fFoundTx |= HandleExodusPurchase(tx, nBlock, mp_obj.getSender(), nBlockTime);
}
}

if (pop_ret > 0) {
Expand Down Expand Up @@ -3709,7 +3756,7 @@ int mastercore_handler_block_end(int nBlockNow, CBlockIndex const * pBlockIndex,
}

// calculate devmsc as of this block and update the Exodus' balance
devmsc = calculate_and_update_devmsc(pBlockIndex->GetBlockTime());
devmsc = calculate_and_update_devmsc(pBlockIndex->GetBlockTime(), nBlockNow);

if (msc_debug_exo) {
int64_t balance = getMPbalance(exodus_address, OMNI_PROPERTY_MSC, BALANCE);
Expand All @@ -3722,9 +3769,6 @@ int mastercore_handler_block_end(int nBlockNow, CBlockIndex const * pBlockIndex,
// transactions were found in the block, signal the UI accordingly
if (countMP > 0) CheckWalletUpdate(true);

// total tokens for properties may have changed, recalculate distribution thresholds for MetaDEx fees
p_feecache->UpdateDistributionThresholds();

// calculate and print a consensus hash if required
if (msc_debug_consensus_hash_every_block) {
uint256 consensusHash = GetConsensusHash();
Expand Down
3 changes: 3 additions & 0 deletions src/omnicore/omnicore.h
Original file line number Diff line number Diff line change
Expand Up @@ -303,6 +303,9 @@ int mastercore_shutdown();
/** Global handler to total wallet balances. */
void CheckWalletUpdate(bool forceUpdate = false);

/** Used to notify that the number of tokens for a property has changed. */
void NotifyTotalTokensChanged(uint32_t propertyId, int block);

int mastercore_handler_disc_begin(int nBlockNow, CBlockIndex const * pBlockIndex);
int mastercore_handler_disc_end(int nBlockNow, CBlockIndex const * pBlockIndex);
int mastercore_handler_block_begin(int nBlockNow, CBlockIndex const * pBlockIndex);
Expand Down
2 changes: 1 addition & 1 deletion src/omnicore/rpcrequirements.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ void RequirePropertyName(const std::string& name)
void RequireExistingProperty(uint32_t propertyId)
{
LOCK(cs_tally);
if (!mastercore::_my_sps->hasSP(propertyId)) {
if (!mastercore::IsPropertyIdValid(propertyId)) {
throw JSONRPCError(RPC_INVALID_PARAMETER, "Property identifier does not exist");
}
}
Expand Down
5 changes: 5 additions & 0 deletions src/omnicore/rules.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,8 @@ std::vector<ConsensusCheckpoint> CMainConsensusParams::GetCheckpoints() const
uint256("1ca6c6f7f31ff7705a0336140485338abcbadf27e4bfdb3484b900b0b4673bba") },
{ 430000, uint256("000000000000000001868b2bb3a285f3cc6b33ea234eb70facf4dcdf22186b87"),
uint256("758b6850a3fdd86194d20f4c7f3bbbe66c38f78722c242e2ecefaaa42eda6a15") },
{ 440000, uint256("0000000000000000038cc0f7bcdbb451ad34a458e2d535764f835fdeb896f29b"),
uint256("94e3e045b846b35226c1b7c9399992515094e227fd195626e3875ad812b44e7a") },
};

const size_t nSize = sizeof(vCheckpoints) / sizeof(vCheckpoints[0]);
Expand Down Expand Up @@ -603,6 +605,9 @@ bool IsTransactionTypeAllowed(int txBlock, uint32_t txProperty, uint16_t txType,
*/
bool VerifyCheckpoint(int block, const uint256& blockHash)
{
// optimization; we only checkpoint every 10,000 blocks - skip any further work if block not a multiple of 10K
if (block % 10000 != 0) return true;

const std::vector<ConsensusCheckpoint>& vCheckpoints = ConsensusParams().GetCheckpoints();

for (std::vector<ConsensusCheckpoint>::const_iterator it = vCheckpoints.begin(); it != vCheckpoints.end(); ++it) {
Expand Down
Loading

0 comments on commit 651c1cc

Please sign in to comment.