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

fix: delay in TimeOffset applied to AdjustedTime caused by send/recei… #31

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
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
4 changes: 3 additions & 1 deletion src/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down
58 changes: 56 additions & 2 deletions src/net.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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<CMessageHeader*>(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<unsigned char*>(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<unsigned char*>(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);
Expand Down