|
|
@ -425,10 +425,45 @@ bool CheckTransaction(const CTransaction& tx, CValidationState &state) |
|
|
|
{ |
|
|
|
{ |
|
|
|
// Basic checks that don't depend on any context
|
|
|
|
// Basic checks that don't depend on any context
|
|
|
|
if (tx.IsSpamMessage()) { |
|
|
|
if (tx.IsSpamMessage()) { |
|
|
|
if (tx.message.size() > MAX_SPAM_MSG_SIZE) |
|
|
|
string spamMsg = tx.message.ExtractPushDataString(0); |
|
|
|
|
|
|
|
if (!spamMsg.size()) |
|
|
|
|
|
|
|
return state.DoS(100, error("CheckTransaction() : invalid or empty spam message")); |
|
|
|
|
|
|
|
if (spamMsg.size() > MAX_SPAM_MSG_SIZE) |
|
|
|
return state.DoS(100, error("CheckTransaction() : spam message too big")); |
|
|
|
return state.DoS(100, error("CheckTransaction() : spam message too big")); |
|
|
|
// [MF] TODO: check message signature
|
|
|
|
|
|
|
|
// [MF] Problem: registration of this user may be in the block itself, better check later.
|
|
|
|
string spamUser = tx.userName.ExtractPushDataString(0); |
|
|
|
|
|
|
|
if( spamUser != "nobody" ) { |
|
|
|
|
|
|
|
string strSign = tx.userName.ExtractPushDataString(1); |
|
|
|
|
|
|
|
if (!strSign.size()) |
|
|
|
|
|
|
|
return state.DoS(100, error("CheckTransaction() : spam signature missing")); |
|
|
|
|
|
|
|
vector<unsigned char> vchSig((const unsigned char*)strSign.data(), |
|
|
|
|
|
|
|
(const unsigned char*)strSign.data() + strSign.size()); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
CPubKey pubkey; |
|
|
|
|
|
|
|
CTransaction txPubKey; |
|
|
|
|
|
|
|
uint256 hashBlock; |
|
|
|
|
|
|
|
uint256 userhash = SerializeHash(spamUser); |
|
|
|
|
|
|
|
if( !GetTransaction(userhash, txPubKey, hashBlock) ) |
|
|
|
|
|
|
|
return state.DoS(100, error("CheckTransaction() : spam signed by unknown user")); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
std::vector< std::vector<unsigned char> > vData; |
|
|
|
|
|
|
|
if( !txPubKey.pubKey.ExtractPushData(vData) || vData.size() < 1 ) |
|
|
|
|
|
|
|
return state.DoS(100, error("CheckTransaction() : spam signed with broken pubkey")); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
pubkey = CPubKey(vData[0]); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// compute message hash for signature checking
|
|
|
|
|
|
|
|
CHashWriter ss(SER_GETHASH, PROTOCOL_VERSION); |
|
|
|
|
|
|
|
ss << strMessageMagic; |
|
|
|
|
|
|
|
ss << tx.message; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
CPubKey pubkeyRec; |
|
|
|
|
|
|
|
if (!pubkeyRec.RecoverCompact(ss.GetHash(), vchSig)) |
|
|
|
|
|
|
|
return state.DoS(100, error("CheckTransaction() : RecoverCompact failed for spammsg")); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (pubkeyRec.GetID() != pubkey.GetID()) |
|
|
|
|
|
|
|
return state.DoS(100, error("CheckTransaction() : spam signature verification failed")); |
|
|
|
|
|
|
|
} |
|
|
|
} else { |
|
|
|
} else { |
|
|
|
if (tx.userName.empty()) |
|
|
|
if (tx.userName.empty()) |
|
|
|
return state.DoS(10, error("CheckTransaction() : username empty")); |
|
|
|
return state.DoS(10, error("CheckTransaction() : username empty")); |
|
|
@ -1713,12 +1748,11 @@ bool ProcessBlock(CValidationState &state, CNode* pfrom, CBlock* pblock, CDiskBl |
|
|
|
if( pblock->vtx[0].IsSpamMessage() ) { |
|
|
|
if( pblock->vtx[0].IsSpamMessage() ) { |
|
|
|
string msg = pblock->vtx[0].message.ExtractPushDataString(0); |
|
|
|
string msg = pblock->vtx[0].message.ExtractPushDataString(0); |
|
|
|
string user = pblock->vtx[0].userName.ExtractPushDataString(0); |
|
|
|
string user = pblock->vtx[0].userName.ExtractPushDataString(0); |
|
|
|
// [MF] FIXME: validate user properly
|
|
|
|
|
|
|
|
if( msg.length() <= 140 ) { |
|
|
|
// SpamMessage was already validated in CheckBlock => CheckTransation
|
|
|
|
printf("ProcessBlock: msg='%s' user='%s'\n", msg.c_str(), user.c_str()); |
|
|
|
printf("ProcessBlock: msg='%s' user='%s'\n", msg.c_str(), user.c_str()); |
|
|
|
receivedSpamMessage(msg, user); |
|
|
|
receivedSpamMessage(msg, user); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
return true; |
|
|
|
return true; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
@ -3492,7 +3526,7 @@ static bool CreateSpamMsgTx(CTransaction &txNew, std::vector<unsigned char> &sal |
|
|
|
std::string strUsername = strSpamUser; |
|
|
|
std::string strUsername = strSpamUser; |
|
|
|
|
|
|
|
|
|
|
|
CKeyID keyID; |
|
|
|
CKeyID keyID; |
|
|
|
if( !pwalletMain->GetKeyIdFromUsername(strSpamUser, keyID) ) { |
|
|
|
if( strSpamUser != "nobody" && !pwalletMain->GetKeyIdFromUsername(strSpamUser, keyID) ) { |
|
|
|
if( pwalletMain->vchDefaultKey.IsValid() ) { |
|
|
|
if( pwalletMain->vchDefaultKey.IsValid() ) { |
|
|
|
keyID = pwalletMain->vchDefaultKey.GetID(); |
|
|
|
keyID = pwalletMain->vchDefaultKey.GetID(); |
|
|
|
strUsername = pwalletMain->mapKeyMetadata[keyID].username; |
|
|
|
strUsername = pwalletMain->mapKeyMetadata[keyID].username; |
|
|
@ -3534,6 +3568,10 @@ static bool CreateSpamMsgTx(CTransaction &txNew, std::vector<unsigned char> &sal |
|
|
|
txNew.pubKey.clear(); // pubKey will be updated to include extranonce
|
|
|
|
txNew.pubKey.clear(); // pubKey will be updated to include extranonce
|
|
|
|
txNew.nNonce = 0; // no update needed for spamMessage's nonce.
|
|
|
|
txNew.nNonce = 0; // no update needed for spamMessage's nonce.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
CValidationState state; |
|
|
|
|
|
|
|
bool ret = CheckTransaction(txNew, state); |
|
|
|
|
|
|
|
printf("CheckTransaction returned %d\n", ret ); |
|
|
|
|
|
|
|
|
|
|
|
return true; |
|
|
|
return true; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|