Optimise serialization of MerklePath, avoiding ambiguity of std::vector<bool>

The serialization enforces a maximum supported Merkle tree depth of 64.

Closes #2831.
This commit is contained in:
Jack Grigg
2017-12-22 20:44:35 +00:00
parent 7346f09026
commit d58ed91af0
4 changed files with 146 additions and 134 deletions

View File

@@ -9,6 +9,7 @@
#include "serialize.h"
#include "Zcash.h"
#include "zcash/util.h"
namespace libzcash {
@@ -21,8 +22,29 @@ public:
template <typename Stream, typename Operation>
inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) {
READWRITE(authentication_path);
READWRITE(index);
std::vector<std::vector<unsigned char>> pathBytes;
uint64_t indexInt;
if (ser_action.ForRead()) {
READWRITE(pathBytes);
READWRITE(indexInt);
MerklePath &us = *(const_cast<MerklePath*>(this));
for (size_t i = 0; i < pathBytes.size(); i++) {
us.authentication_path.push_back(convertBytesVectorToVector(pathBytes[i]));
us.index.push_back((indexInt >> ((pathBytes.size() - 1) - i)) & 1);
}
} else {
assert(authentication_path.size() == index.size());
pathBytes.resize(authentication_path.size());
for (size_t i = 0; i < authentication_path.size(); i++) {
pathBytes[i].resize((authentication_path[i].size()+7)/8);
for (unsigned int p = 0; p < authentication_path[i].size(); p++) {
pathBytes[i][p / 8] |= authentication_path[i][p] << (7-(p % 8));
}
}
indexInt = convertVectorToInt(index);
READWRITE(pathBytes);
READWRITE(indexInt);
}
}
MerklePath() { }