示例#1
0
void Payload_Reject::deserialize(uint8_t* dataptr, size_t len)
{
   uint64_t typeLen;
   auto remaining = len;
   auto varintlen = get_varint(typeLen, dataptr, len);
   auto ptr = dataptr + varintlen;
   remaining -= (varintlen + typeLen + 1);

   string msgtype((char*)ptr, typeLen);
   auto typeIter = BitcoinP2P::strToPayload_.find(msgtype);
   if (typeIter == BitcoinP2P::strToPayload_.end())
      throw BitcoinMessageDeserError("unknown reject type");

   rejectType_ = typeIter->second;
   ptr += typeLen;

   code_ = (char)*ptr;
   ptr++;

   uint64_t reasonLen;
   varintlen = get_varint(reasonLen, ptr, len);
   ptr += varintlen;
   remaining -= (reasonLen + varintlen);

   reasonStr_ = move(string((char*)ptr, reasonLen));
   ptr += reasonLen;

   if (remaining == 32)
      extra_.resize(32);

   memcpy(&extra_[0], ptr, 32);
}
示例#2
0
void Payload_GetData::deserialize(uint8_t* dataptr, size_t len)
{
   uint64_t invCount;
   auto varintlen = get_varint(invCount, dataptr, len);

   if (invCount > INV_MAX)
      throw BitcoinMessageDeserError("inv count > INV_MAX");

   invVector_.resize(invCount);

   auto ptr = dataptr + varintlen;
   auto remaining = len - varintlen;

   for (auto& entry : invVector_)
   {
      if (remaining < INV_ENTRY_LEN)
         throw BitcoinMessageDeserError("inv deser size mismatch");

      auto entrytype = *(uint32_t*)(ptr);
      if ((entrytype & ~Inv_Witness) > 3)
         throw BitcoinMessageDeserError("invalid inv entry type");

      entry.invtype_ = (InvType)entrytype;
      memcpy(entry.hash, ptr + 4, 32);

      remaining -= INV_ENTRY_LEN;
      ptr += INV_ENTRY_LEN;
   }
}
示例#3
0
unsigned long UnMarshaller::get_varint() {
    bool done;
    unsigned long val = get_varint(&done);

    if(!done) {
        std::ostringstream msg;

        msg << "Unable to unmarshal variable length integer: exceeds " << sizeof(long) << " bytes";

        Exception::type_error(state, msg.str().c_str());
    }

    return val;
}
示例#4
0
void Payload_Version::deserialize(uint8_t* data, size_t len)
{
   uint8_t* dataptr = data;

   vheader_.version_ = *(uint32_t*)dataptr;
   dataptr += 4;
   vheader_.services_ = *(uint64_t*)dataptr;
   dataptr += 8;
   vheader_.timestamp_ = *(int64_t*)dataptr;
   dataptr += 8;

   vheader_.addr_recv_.services_ = *(uint64_t*)dataptr;
   dataptr += 8;
   memcpy(vheader_.addr_recv_.ipV6_, dataptr, 16);
   dataptr += 16;
   vheader_.addr_recv_.port_ = *(uint16_t*)dataptr;
   dataptr += 2;

   vheader_.addr_from_.services_ = *(uint64_t*)dataptr;
   dataptr += 8;
   memcpy(vheader_.addr_from_.ipV6_, dataptr, 16);
   dataptr += 16;
   vheader_.addr_from_.port_ = *(uint16_t*)dataptr;
   dataptr += 2;

   vheader_.nonce_ = *(uint64_t*)dataptr;
   dataptr += 8;

   size_t remaining = len - MESSAGE_HEADER_LEN - USERAGENT_OFFSET;
   uint64_t uaLen;
   auto varintlen = get_varint(uaLen, dataptr, remaining);
   dataptr += varintlen;
   char* userAgentPtr = (char*)(dataptr);
   userAgent_ = string(userAgentPtr, uaLen);
   dataptr += uaLen;

   startHeight_ = *(uint32_t*)dataptr;
}
示例#5
0
Object* UnMarshaller::get_positive_varint() {
    bool done;
    unsigned long val = get_varint(&done);

    bool is_fixnum = done;
    mp_int mp_val;

    // do we need to switch to bignum math?
    if(!done) {
        int shift = sizeof(long) * 7;
        mp_int a;

        mp_init_set_int(&mp_val, val);
        mp_init(&a);

#if (__WORDSIZE == 64)
        // mp_(init_)set_int can only deal with 32 bit values,
        // so the above call only copied the lower 32 bits of _val_.
        // Handle the upper 32 bits as well:
        mp_set_int(&a, val >> 32);
        mp_mul_2d(&a, 32, &a);
        mp_add(&a, &mp_val, &mp_val);
#endif

        while(!done) {
            unsigned int byte = stream.get();

            mp_set_int(&a, byte & ~128);
            mp_mul_2d(&a, shift, &a);
            mp_add(&a, &mp_val, &mp_val);

            shift += 7;
            done = byte < 128;
        }

        mp_clear(&a);
    }