Open joshmg opened 1 year ago
The implementation of this functionality within BCHN is as follows:
template <typename Stream> uint64_t ReadCompactSizeWithLimit(Stream &is, const uint64_t maxSize) {
uint8_t chSize = ser_readdata8(is);
uint64_t nSizeRet = 0;
if (chSize < 253) {
nSizeRet = chSize;
} else if (chSize == 253) {
nSizeRet = ser_readdata16(is);
if (nSizeRet < 253) {
throw std::ios_base::failure("non-canonical ReadCompactSize()");
}
} else if (chSize == 254) {
nSizeRet = ser_readdata32(is);
if (nSizeRet < 0x10000u) {
throw std::ios_base::failure("non-canonical ReadCompactSize()");
}
} else {
nSizeRet = ser_readdata64(is);
if (nSizeRet < 0x100000000ULL) {
throw std::ios_base::failure("non-canonical ReadCompactSize()");
}
}
if (nSizeRet > maxSize) {
throw std::ios_base::failure("ReadCompactSize(): size too large");
}
return nSizeRet;
}
The specification of Compact Variable Length Integer (/protocol/formats/variable-length-integer) (also known as "CompactSize" in Core-clients) does not specify that values should be canonically encoded, however this rule is enforced by all Core-derived clients.
E.g. the value
1
must be encoded as0x01
rather than0xFD0100
,0xFE0100000
, or0xFF010000000000000
.