在分布式协议中推动unordered_map的向量值的问题
我们正在实施套接字编程协议,并遇到了使我们感到困惑的错误。复制对象接收相同类型的多个传入消息,需要保留收到的消息列表。问题是,当我们将int推向与密钥关联的向量时,代码显然返回而无需打印。以下是我们运行此代码时从接收副本中输出的当前输出:
Signshare message received.
Signshare message received from replica: 1
This replica is a c_collector
The receiving view number is the same as this replicas view number. PASSED!
No previous signshare message with sequence s was accepted for view v. PASSED!
In push_seq_signshare
SHOULD PRINT 4 TIMES!!!!!:
Signshare message received.
Signshare message received from replica: 0
This replica is a c_collector
The receiving view number is the same as this replicas view number. PASSED!
No previous signshare message with sequence s was accepted for view v. PASSED!
Signshare message received.
Signshare message received from replica: 3
This replica is a c_collector
The receiving view number is the same as this replicas view number. PASSED!
No previous signshare message with sequence s was accepted for view v. PASSED!
Signshare message received.
Signshare message received from replica: 2
我们希望行应该打印4次!
我们在副本类中有一个私人属性,可以跟踪即将到来的消息中的消息ID。它是表单的unordered_map:key = make_pair(int,int);值=向量
这是声明的样子:
std::unordered_map<std::pair<int, int>, std::vector<int>, pair_hash> accepted_sequence_signshare;
我们发现有必要创建一个结构来传递到无序的地图声明(上面的pair_hash参数)以使键伸缩,这就是结构的外观:
struct pair_hash
{
template <class T1, class T2>
std::size_t operator()(const std::pair<T1, T2> &p) const
{
auto h1 = std::hash<T1>{}(p.first);
auto h2 = std::hash<T2>{}(p.second);
// Mainly for demonstration purposes, i.e. works but is overly simple
// In the real world, use sth. like boost.hash_combine
return h1 ^ h2;
}
};
我们的程序相反复杂(这是一个分布式套接字编程协议),但我们认为导致错误的相关代码段位于我们的消息处理功能之一中。
void handleSIGNSHARE(message &msg, replica *r)
{
cout << "Signshare message received." << endl;
int recv_repID;
int recv_v;
int recv_s;
msg >> recv_repID >> recv_v >> recv_s;
cout << "Signshare message received from replica: " << recv_repID << endl;
cout << "This replica is a c_collector" << endl;
if (r->v == recv_v)
{
cout << "The receiving view number is the same as this replicas view number. PASSED!" << endl;
// no previous signshare message with sequence s was accepted for view v
if (r->validate_view_sequence_signshare(recv_repID, recv_v, recv_s))
{
cout << "No previous signshare message with sequence s was accepted for view v. PASSED!" << endl;
// third condition: threshold signature sigma(h) passes verification unimplemented
// We believe through debugging that this line is the line with the bug.
r->push_sequence_signshare(recv_repID, recv_v, recv_s);
// This print statement should print 4 times (all nodes in the network send this message type to this replica
// with 4 replicas in the network. It only prints 1 time.
cout << "SHOULD PRINT 4 TIMES!!!!!: " << r->get_size_for_view_sequence_signshare(recv_v, recv_s) << endl;
//)(UJKLNLSNDFLKNLK) Only want this to run once. Take care of the race condition that can occur here
if (r->get_size_for_view_sequence_signshare(recv_v, recv_s) >= sig_N)
{
msg.setID(FULLCOMMITPROOF);
msg << r->s << r->v << r->repID;
r->sendToAll(msg);
}
}
else
{
cout << "No previous signshare message with sequence s was accepted for view v. PASSED!" << endl;
}
}
else
{
cout << "The receiving view number is NOT the same as this replicas view number. FAILED!" << endl;
}
}
我们认为引起问题的行已上面列出,但为了清楚:
r->push_sequence_signshare(recv_repID, recv_v, recv_s);
最后,下面是上面调用的方法:
void push_sequence_signshare(int r, int v, int s)
{
mtx_signshare.lock();
cout << "In push_seq_signshare" << endl;
if (accepted_sequence_signshare.find(std::make_pair(v, s)) == accepted_sequence_signshare.end())
{
std::vector<int> vec;
accepted_sequence_signshare.emplace(std::make_pair(v, s), vec);
}
accepted_sequence_signshare[std::make_pair(v, s)].push_back(r);
mtx_signshare.unlock();
}
我们尝试过的
我们一直在调试我们的输出最近2-3个小时尝试了push_squerence_signshare的不同实现(int r,int v,int s)。本质上,我们希望该函数将整数推到与key =(v,s)关联的向量。我们尝试了声明属性的不同方法(而不是让值为std :: vector,我们尝试了std :: vector*),但没有成功。我们还尝试了将不同的方法插入unordered_map,例如emplace,insert和map [key] .push_back(value)。
援助将不胜感激!
We are implementing a socket programming protocol and have run into a bug that has baffled us. The replica object receives multiple incoming messages of the same type and needs to keep a list of the messages received. The problem is when we push an int on to the vector associated with the key, the code apparently returns without printing. Below is our current output from the receiving replica when we run this code:
Signshare message received.
Signshare message received from replica: 1
This replica is a c_collector
The receiving view number is the same as this replicas view number. PASSED!
No previous signshare message with sequence s was accepted for view v. PASSED!
In push_seq_signshare
SHOULD PRINT 4 TIMES!!!!!:
Signshare message received.
Signshare message received from replica: 0
This replica is a c_collector
The receiving view number is the same as this replicas view number. PASSED!
No previous signshare message with sequence s was accepted for view v. PASSED!
Signshare message received.
Signshare message received from replica: 3
This replica is a c_collector
The receiving view number is the same as this replicas view number. PASSED!
No previous signshare message with sequence s was accepted for view v. PASSED!
Signshare message received.
Signshare message received from replica: 2
We desire the line SHOULD PRINT 4 TIMES!!!!!:
to print 4 times, but it does not.
We have a private attribute in the replica class that keeps track of message ids of in coming messages. It is an unordered_map of the form: key = make_pair(int, int); value = vector
Here is what the declaration looks like:
std::unordered_map<std::pair<int, int>, std::vector<int>, pair_hash> accepted_sequence_signshare;
We found it necessary to create a struct to pass into the unordered map declaration (the pair_hash parameter above) to make the key hashable and this is what that struct looks like:
struct pair_hash
{
template <class T1, class T2>
std::size_t operator()(const std::pair<T1, T2> &p) const
{
auto h1 = std::hash<T1>{}(p.first);
auto h2 = std::hash<T2>{}(p.second);
// Mainly for demonstration purposes, i.e. works but is overly simple
// In the real world, use sth. like boost.hash_combine
return h1 ^ h2;
}
};
Our program is rather complicated (it is a distributed socket programming protocol) but we believe the relevant code snippet that is causing the bug is within one of our message handling functions.
void handleSIGNSHARE(message &msg, replica *r)
{
cout << "Signshare message received." << endl;
int recv_repID;
int recv_v;
int recv_s;
msg >> recv_repID >> recv_v >> recv_s;
cout << "Signshare message received from replica: " << recv_repID << endl;
cout << "This replica is a c_collector" << endl;
if (r->v == recv_v)
{
cout << "The receiving view number is the same as this replicas view number. PASSED!" << endl;
// no previous signshare message with sequence s was accepted for view v
if (r->validate_view_sequence_signshare(recv_repID, recv_v, recv_s))
{
cout << "No previous signshare message with sequence s was accepted for view v. PASSED!" << endl;
// third condition: threshold signature sigma(h) passes verification unimplemented
// We believe through debugging that this line is the line with the bug.
r->push_sequence_signshare(recv_repID, recv_v, recv_s);
// This print statement should print 4 times (all nodes in the network send this message type to this replica
// with 4 replicas in the network. It only prints 1 time.
cout << "SHOULD PRINT 4 TIMES!!!!!: " << r->get_size_for_view_sequence_signshare(recv_v, recv_s) << endl;
//)(UJKLNLSNDFLKNLK) Only want this to run once. Take care of the race condition that can occur here
if (r->get_size_for_view_sequence_signshare(recv_v, recv_s) >= sig_N)
{
msg.setID(FULLCOMMITPROOF);
msg << r->s << r->v << r->repID;
r->sendToAll(msg);
}
}
else
{
cout << "No previous signshare message with sequence s was accepted for view v. PASSED!" << endl;
}
}
else
{
cout << "The receiving view number is NOT the same as this replicas view number. FAILED!" << endl;
}
}
The line that we think is causing the issue is listed above, but just for clarity:
r->push_sequence_signshare(recv_repID, recv_v, recv_s);
Finally, below is the method called above in full:
void push_sequence_signshare(int r, int v, int s)
{
mtx_signshare.lock();
cout << "In push_seq_signshare" << endl;
if (accepted_sequence_signshare.find(std::make_pair(v, s)) == accepted_sequence_signshare.end())
{
std::vector<int> vec;
accepted_sequence_signshare.emplace(std::make_pair(v, s), vec);
}
accepted_sequence_signshare[std::make_pair(v, s)].push_back(r);
mtx_signshare.unlock();
}
What we have tried
We have been debugging our output for the last 2-3 hours have tried different implementations of push_sequence_signshare(int r, int v, int s). Essentially we want the function to just push the integer on to the vector associated with key = (v,s). We have tried different methods of declaring the attribute (instead of having the value be std::vector, we tried std::vector*) but had no success. We have also tried different methods of inserting into the unordered_map such as emplace, insert and map[key].push_back(value).
Assistance would be greatly appreciated!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论