uint32_t CBNetworkAddressListSerialise(CBNetworkAddressList * self, bool force){ CBByteArray * bytes = CBGetMessage(self)->bytes; if (! bytes) { CBLogError("Attempting to serialise a CBNetworkAddress with no bytes."); return 0; } CBVarInt num = CBVarIntFromUInt64(self->addrNum); if (bytes->length < (26 + self->timeStamps * 4) * self->addrNum + num.size) { CBLogError("Attempting to serialise a CBNetworkAddress without enough bytes."); return 0; } CBVarIntEncode(bytes, 0, num); uint16_t cursor = num.size; for (uint8_t x = 0; x < num.val; x++) { if (! CBGetMessage(self->addresses[x])->serialised // Serailise if not serialised yet. // Serialise if force is true. || force // If the data shares the same data as this address broadcast, re-serialise the address, in case it got overwritten. || CBGetMessage(self->addresses[x])->bytes->sharedData == bytes->sharedData || (CBGetMessage(self->addresses[x])->bytes->length != 26) ^ self->timeStamps) { if (CBGetMessage(self->addresses[x])->serialised) // Release old byte array CBReleaseObject(CBGetMessage(self->addresses[x])->bytes); CBGetMessage(self->addresses[x])->bytes = CBByteArraySubReference(bytes, cursor, bytes->length-cursor); if (! CBNetworkAddressSerialise(self->addresses[x], self->timeStamps)) { CBLogError("CBNetworkAddress cannot be serialised because of an error with the CBNetworkAddress number %u.", x); // Release CBByteArray objects to avoid problems overwritting pointer without release, if serialisation is tried again. for (uint8_t y = 0; y < x + 1; y++) CBReleaseObject(CBGetMessage(self->addresses[y])->bytes); return 0; } }else{ // Move serialsed data to one location CBByteArrayCopyByteArray(bytes, cursor, CBGetMessage(self->addresses[x])->bytes); CBByteArrayChangeReference(CBGetMessage(self->addresses[x])->bytes, bytes, cursor); } cursor += CBGetMessage(self->addresses[x])->bytes->length; } // Change bytes length bytes->length = cursor; // Is now serialised CBGetMessage(self)->serialised = true; return cursor; }
uint32_t CBAddressBroadcastSerialise(CBAddressBroadcast * self, bool force){ CBByteArray * bytes = CBGetMessage(self)->bytes; if (NOT bytes) { CBGetMessage(self)->onErrorReceived(CB_ERROR_MESSAGE_SERIALISATION_NULL_BYTES,"Attempting to serialise a CBAddressBroadcast with no bytes."); return 0; } if (bytes->length < (26 + self->timeStamps * 4) * self->addrNum) { CBGetMessage(self)->onErrorReceived(CB_ERROR_MESSAGE_SERIALISATION_BAD_BYTES,"Attempting to serialise a CBAddressBroadcast without enough bytes."); return 0; } CBVarInt num = CBVarIntFromUInt64(self->addrNum); CBVarIntEncode(bytes, 0, num); uint16_t cursor = num.size; for (uint8_t x = 0; x < num.val; x++) { if (force && CBGetMessage(self->addresses[x])->serialised) CBReleaseObject(CBGetMessage(self->addresses[x])->bytes); if (NOT CBGetMessage(self->addresses[x])->serialised || force) { CBGetMessage(self->addresses[x])->bytes = CBByteArraySubReference(bytes, cursor, bytes->length-cursor); uint32_t len = CBNetworkAddressSerialise(self->addresses[x],self->timeStamps); if (NOT len) { CBGetMessage(self)->onErrorReceived(CB_ERROR_MESSAGE_SERIALISATION_BAD_BYTES,"CBAddressBroadcast cannot be serialised because of an error with the CBNetworkAddress number %u.",x); // Release CBByteArray objects to avoid problems overwritting pointer without release, if serialisation is tried again. for (uint8_t y = 0; y < x + 1; y++) CBReleaseObject(CBGetMessage(self->addresses[y])->bytes); return 0; } CBGetMessage(self->addresses[x])->bytes->length = len; }else if (CBGetMessage(self->addresses[x])->bytes->sharedData != bytes->sharedData){ // Move serialsed data to one location CBByteArrayCopyByteArray(bytes, cursor, CBGetMessage(self->addresses[x])->bytes); CBByteArrayChangeReference(CBGetMessage(self->addresses[x])->bytes, bytes, cursor); } cursor += CBGetMessage(self->addresses[x])->bytes->length; } CBGetMessage(self)->serialised = true; return cursor; }
uint32_t CBVersionSerialise(CBVersion * self, bool force){ CBByteArray * bytes = CBGetMessage(self)->bytes; if (NOT bytes) { CBGetMessage(self)->logError("Attempting to serialise a CBVersion with no bytes."); return 0; } if (bytes->length < 46) { CBGetMessage(self)->logError("Attempting to serialise a CBVersion with less than 46 bytes."); return 0; } CBByteArraySetInt32(bytes, 0, self->version); CBByteArraySetInt64(bytes, 4, self->services); CBByteArraySetInt64(bytes, 12, self->time); if (force && CBGetMessage(self->addRecv)->serialised) CBReleaseObject(CBGetMessage(self->addRecv)->bytes); if (NOT CBGetMessage(self->addRecv)->serialised || force) { CBGetMessage(self->addRecv)->bytes = CBByteArraySubReference(bytes, 20, bytes->length-20); if (NOT CBGetMessage(self->addRecv)->bytes) { CBGetMessage(self)->logError("Cannot create a new CBByteArray sub reference in CBVersionSerialise for receiving address."); return 0; } uint32_t len = CBNetworkAddressSerialise(self->addRecv,false); if (NOT len) { CBGetMessage(self)->logError("CBVersion cannot be serialised because of an error with the receiving CBNetworkAddress"); // Release bytes to avoid problems overwritting pointer without release, if serialisation is tried again. CBReleaseObject(CBGetMessage(self->addRecv)->bytes); return 0; } CBGetMessage(self->addRecv)->bytes->length = len; }else if (CBGetMessage(self->addRecv)->bytes->sharedData != bytes->sharedData){ // Move serialsed data to one location CBByteArrayCopyByteArray(bytes, 20, CBGetMessage(self->addRecv)->bytes); CBByteArrayChangeReference(CBGetMessage(self->addRecv)->bytes, bytes, 20); } if (self->version >= 106) { if (bytes->length < 85) { CBGetMessage(self)->logError("Attempting to serialise a CBVersion with less than 85 bytes required."); return 0; } if (self->userAgent->length > 400) { CBGetMessage(self)->logError("Attempting to serialise a CBVersion with a userAgent over 400 bytes."); return 0; } if (force && CBGetMessage(self->addSource)->serialised) CBReleaseObject(CBGetMessage(self->addSource)->bytes); if (NOT CBGetMessage(self->addSource)->serialised || force) { CBGetMessage(self->addSource)->bytes = CBByteArraySubReference(bytes, 46, bytes->length-46); if (NOT CBGetMessage(self->addSource)->bytes) { CBGetMessage(self)->logError("Cannot create a new CBByteArray sub reference in CBVersionSerialise for source address."); return 0; } uint32_t len = CBNetworkAddressSerialise(self->addSource,false); if (NOT len) { CBGetMessage(self)->logError("CBVersion cannot be serialised because of an error with the source CBNetworkAddress"); // Release bytes to avoid problems overwritting pointer without release, if serialisation is tried again. CBReleaseObject(CBGetMessage(self->addSource)->bytes); return 0; } CBGetMessage(self->addSource)->bytes->length = len; }else if (CBGetMessage(self->addSource)->bytes->sharedData != bytes->sharedData){ // Move serialsed data to one location CBByteArrayCopyByteArray(bytes, 46, CBGetMessage(self->addSource)->bytes); CBByteArrayChangeReference(CBGetMessage(self->addSource)->bytes, bytes, 46); } CBByteArraySetInt64(bytes, 72, self->nonce); CBVarInt varInt = CBVarIntFromUInt64(self->userAgent->length); CBVarIntEncode(bytes, 80, varInt); if (bytes->length < 84 + varInt.size + varInt.val) { CBGetMessage(self)->logError("Attempting to deserialise a CBVersion without enough space to cover the userAgent and block height."); return 0; } CBByteArrayCopyByteArray(bytes, 80 + varInt.size,self->userAgent); CBByteArrayChangeReference(self->userAgent,bytes,80 + varInt.size); CBByteArraySetInt32(bytes, 80 + varInt.size + (uint32_t)varInt.val, self->blockHeight); CBGetMessage(self)->serialised = true; return 84 + varInt.size + (uint32_t)varInt.val; }else{ // Not the further message. CBGetMessage(self)->serialised = true; return 46; } }