diff --git a/src/main.cpp b/src/main.cpp index 33518c321..1a1a85d63 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -4968,7 +4968,9 @@ bool static ProcessMessage(CNode* pfrom, std::string strCommand, CDataStream& vR pfrom->nStartingHeight, addrMe.ToString(), pfrom->id, remoteAddr); - int64_t nTimeOffset = nTime - GetTime(); +// receive queue time offset fix +// int64_t nTimeOffset = nTime - GetTime(); + int64_t nTimeOffset = nTime - (nTimeReceived/1000000); pfrom->nTimeOffset = nTimeOffset; const int nTimeSlotLength = Params().GetConsensus().nTimeSlotLength; if (abs64(nTimeOffset) < 2 * nTimeSlotLength) { diff --git a/src/net.cpp b/src/net.cpp index e9d0e43d7..b6ab43f5d 100644 --- a/src/net.cpp +++ b/src/net.cpp @@ -861,13 +861,67 @@ int CNetMessage::readData(const char* pch, unsigned int nBytes) return nCopy; } - // requires LOCK(cs_vSend) size_t CConnman::SocketSendData(CNode* pnode) { auto it = pnode->vSendMsg.begin(); size_t nSentSize = 0; - +/* Begin queue send delay time offset fix + The Sendtime is not the time this message was put in the queue, + it is Now(). Observed queue delays of 30 seconds or more are introduced + on hosts with restricted resources during "tip" folloowing and chain + re-org operations. This delay corrupts AdjustedTime on the receiving host + + format of VERSION message in std::deque, not contiguous + (4) message start + (12) command = version + (4) size + (4) checksum +------- chunk 2 ------- + (4) nVersion + (8) nServiceInt + (8) nTime + (x) CAddress addrMe + (x) CAddress addrFrom + (8) nNonce + ........ and so on... +*/ + union uS + { + uint64_t ui64_tm; + u_char uchr_tm[8]; + }; + union uS uSendbuff; + const int bigint = 1; + auto& sh = *it; +// at front of deque, hdrbuf is first + CMessageHeader * shdr = reinterpret_cast(sh.data()); + std::string strCommand = shdr->GetCommand(); + if (strCommand == NetMsgType::VERSION) { +/* do not increment "it", it corrupts deque + header and message are in 2 sequential non-contiguious chunks in the deque, see: + void CConnman::PushMessage(CNode* pnode, CSerializedNetMsg&& msg) + ... + pnode->vSendMsg.push_back(std::move(serializedHeader)); + if (nMessageSize) + pnode->vSendMsg.push_back(std::move(msg.data)); +*/ + auto& sd = *(std::next(it, 1)); // point to next data chunk + memcpy(uSendbuff.uchr_tm, reinterpret_cast(sd.data() + 12), 8); + int64_t nSendtime = uSendbuff.ui64_tm; + int64_t nNow = (pnode->fInbound) ? GetAdjustedTime() : GetTime(); + int64_t nNewSendtime = nNow; + if (! *(char *)&bigint) { // if bigendian + nSendtime = bswap_64(uSendbuff.ui64_tm); + nNewSendtime = bswap_64(nNow); + } +// LogPrintf("HACK %s size %d %" PRId64 " %" PRId64 "\n", strCommand.c_str(), shdr->nMessageSize, nSendtime, nNow); + if (nSendtime != nNow) { + uSendbuff.ui64_tm = nNewSendtime; + memcpy(reinterpret_cast(sd.data() + 12), uSendbuff.uchr_tm, 8); + } + } +// end time offset fix while (it != pnode->vSendMsg.end()) { const auto& data = *it; assert(data.size() > pnode->nSendOffset);