uint32_t CBAddressBroadcastDeserialise(CBAddressBroadcast * self){ CBByteArray * bytes = CBGetMessage(self)->bytes; if (NOT bytes) { CBLogError("Attempting to deserialise a CBAddressBroadcast with no bytes."); return 0; } if (bytes->length < 26 + self->timeStamps * 4) { CBLogError("Attempting to deserialise a CBAddressBroadcast without enough bytes to cover one address."); return 0; } CBVarInt num = CBVarIntDecode(bytes, 0); /* TODO fix this, don't just hack it away if (num.val > 30) { CBLogError("Attempting to deserialise a CBAddressBroadcast with a var int over 30."); return 0; } */ self->addresses = malloc(sizeof(*self->addresses) * (size_t)num.val); if (NOT self->addresses) { CBLogError("Cannot allocate %i bytes of memory in CBAddressBroadcastDeserialise\n", sizeof(*self->addresses) * (size_t)num.val); return 0; } self->addrNum = num.val; uint16_t cursor = num.size; for (uint8_t x = 0; x < num.val; x++) { // Make new CBNetworkAddress from the rest of the data. uint8_t len; CBByteArray * data = CBByteArraySubReference(bytes, cursor, bytes->length-cursor); if (data) { // Create a new network address object. It is public since it is in an address broadcast. self->addresses[x] = CBNewNetworkAddressFromData(data, true); if (self->addresses[x]){ // Deserialise len = CBNetworkAddressDeserialise(self->addresses[x], self->timeStamps); if (NOT len) CBLogError("CBAddressBroadcast cannot be deserialised because of an error with the CBNetworkAddress number %u.", x); }else{ len = 0; CBLogError("Could not create CBNetworkAddress in CBAddressBroadcastDeserialise for network address %u.", x); } }else{ len = 0; CBLogError("Could not create CBByteArray in CBAddressBroadcastDeserialise for network address %u.", x); } if (NOT len) { // Release bytes CBReleaseObject(data); return 0; } // Adjust length data->length = len; CBReleaseObject(data); cursor += len; } return cursor; }
uint32_t CBAddressBroadcastDeserialise(CBAddressBroadcast * self){ CBByteArray * bytes = CBGetMessage(self)->bytes; if (NOT bytes) { CBGetMessage(self)->onErrorReceived(CB_ERROR_MESSAGE_DESERIALISATION_NULL_BYTES,"Attempting to deserialise a CBAddressBroadcast with no bytes."); return 0; } if (bytes->length < 26 + self->timeStamps * 4) { CBGetMessage(self)->onErrorReceived(CB_ERROR_MESSAGE_DESERIALISATION_BAD_BYTES,"Attempting to deserialise a CBAddressBroadcast without enough bytes to cover one address."); return 0; } CBVarInt num = CBVarIntDecode(bytes, 0); if (num.val > 30) { CBGetMessage(self)->onErrorReceived(CB_ERROR_MESSAGE_DESERIALISATION_BAD_BYTES,"Attempting to deserialise a CBAddressBroadcast with a var int over 30."); return 0; } self->addresses = malloc(sizeof(*self->addresses) * (size_t)num.val); if (NOT self->addresses) { CBGetMessage(self)->onErrorReceived(CB_ERROR_OUT_OF_MEMORY,"Cannot allocate %i bytes of memory in CBAddressBroadcastDeserialise\n",sizeof(*self->addresses) * (size_t)num.val); return 0; } self->addrNum = num.val; uint16_t cursor = num.size; for (uint8_t x = 0; x < num.val; x++) { // Make new CBNetworkAddress from the rest of the data. uint8_t len; CBByteArray * data = CBByteArraySubReference(bytes, cursor, bytes->length-cursor); if (data) { self->addresses[x] = CBNewNetworkAddressFromData(data, CBGetMessage(self)->onErrorReceived); if (self->addresses[x]){ // Deserialise len = CBNetworkAddressDeserialise(self->addresses[x], self->timeStamps); if (NOT len) CBGetMessage(self)->onErrorReceived(CB_ERROR_MESSAGE_DESERIALISATION_BAD_BYTES,"CBAddressBroadcast cannot be deserialised because of an error with the CBNetworkAddress number %u.",x); }else{ len = 0; CBGetMessage(self)->onErrorReceived(CB_ERROR_INIT_FAIL,"Could not create CBNetworkAddress in CBAddressBroadcastDeserialise for network address %u.",x); } }else{ len = 0; CBGetMessage(self)->onErrorReceived(CB_ERROR_INIT_FAIL,"Could not create CBByteArray in CBAddressBroadcastDeserialise for network address %u.",x); } if (NOT len) { // Release bytes CBReleaseObject(data); return 0; } // Adjust length data->length = len; CBReleaseObject(data); cursor += len; } return cursor; }
uint32_t CBNetworkAddressListDeserialise(CBNetworkAddressList * self){ CBByteArray * bytes = CBGetMessage(self)->bytes; if (! bytes) { CBLogError("Attempting to deserialise a CBNetworkAddressList with no bytes."); return CB_DESERIALISE_ERROR; } if (bytes->length < 26 + self->timeStamps * 4) { CBLogError("Attempting to deserialise a CBNetworkAddressList without enough bytes to cover one address."); return CB_DESERIALISE_ERROR; } CBVarInt num = CBVarIntDecode(bytes, 0); if (num.val > 1000) { CBLogError("Attempting to deserialise a CBNetworkAddressList with a var int over 1000."); return CB_DESERIALISE_ERROR; } self->addresses = malloc(sizeof(*self->addresses) * (size_t)num.val); self->addrNum = (uint32_t)num.val; uint16_t cursor = num.size; for (uint32_t x = 0; x < num.val; x++) { // Make new CBNetworkAddress from the rest of the data. uint32_t len; CBByteArray * data = CBByteArraySubReference(bytes, cursor, bytes->length-cursor); // Create a new network address object. It is public since it is in an address broadcast. self->addresses[x] = CBNewNetworkAddressFromData(data, true); // Deserialise len = CBNetworkAddressDeserialise(self->addresses[x], self->timeStamps); if (len == CB_DESERIALISE_ERROR){ CBLogError("CBNetworkAddressList cannot be deserialised because of an error with the CBNetworkAddress number %u.", x); // Release bytes CBReleaseObject(data); return CB_DESERIALISE_ERROR; } // Adjust length data->length = len; CBReleaseObject(data); cursor += len; } return cursor; }
uint32_t CBVersionDeserialise(CBVersion * self){ CBByteArray * bytes = CBGetMessage(self)->bytes; if (NOT bytes) { CBGetMessage(self)->logError("Attempting to deserialise a CBVersion with no bytes."); return 0; } if (bytes->length < 46) { CBGetMessage(self)->logError("Attempting to deserialise a CBVersion with less than 46 bytes."); return 0; } self->version = CBByteArrayReadInt32(bytes, 0); self->services = (CBVersionServices) CBByteArrayReadInt64(bytes, 4); self->time = CBByteArrayReadInt64(bytes, 12); CBByteArray * data = CBByteArraySubReference(bytes, 20, bytes->length-20); // Get data from 20 bytes to the end of the byte array to deserialise the recieving network address. if (NOT data) { CBGetMessage(self)->logError("Cannot create a new CBByteArray in CBVersionDeserialise for the receiving address."); return 0; } self->addRecv = CBNewNetworkAddressFromData(data, CBGetMessage(self)->logError); if (NOT self->addRecv) { CBGetMessage(self)->logError("Cannot create a new CBNetworkAddress in CBVersionDeserialise for the receiving address."); CBReleaseObject(data); return 0; } uint32_t len = CBNetworkAddressDeserialise(self->addRecv, false); // No time from version message. if (NOT len){ CBGetMessage(self)->logError("CBVersion cannot be deserialised because of an error with the receiving address."); CBReleaseObject(data); return 0; } // Readjust CBByteArray length for recieving address data->length = len; CBReleaseObject(data); if (self->version >= 106) { // ??? Very old. No need for backwards compatibility? Might as well. if (bytes->length < 85) { CBGetMessage(self)->logError("Attempting to deserialise a CBVersion with less than 85 bytes required."); return 0; } // Source address deserialisation data = CBByteArraySubReference(bytes, 46, bytes->length-46); if (NOT data) { CBGetMessage(self)->logError("Cannot create a new CBByteArray in CBVersionDeserialise for the source address."); return 0; } self->addSource = CBNewNetworkAddressFromData(data, CBGetMessage(self)->logError); if (NOT self->addSource) { CBGetMessage(self)->logError("Cannot create a new CBNetworkAddress in CBVersionDeserialise for the source address."); CBReleaseObject(data); return 0; } uint32_t len = CBNetworkAddressDeserialise(self->addSource, false); // No time from version message. if (NOT len){ CBGetMessage(self)->logError("CBVersion cannot be deserialised because of an error with the source address."); CBReleaseObject(data); return 0; } // Readjust CBByteArray length for source address data->length = len; CBReleaseObject(data); self->nonce = CBByteArrayReadInt64(bytes, 72); uint8_t x = CBByteArrayGetByte(bytes, 80); // Check length for decoding CBVarInt if (x > 253){ CBGetMessage(self)->logError("Attempting to deserialise a CBVersion with a var string that is too big."); return 0; } CBVarInt varInt = CBVarIntDecode(bytes, 80); 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; } if (varInt.val > 400) { // cbitcoin accepts userAgents upto 400 bytes CBGetMessage(self)->logError("Attempting to deserialise a CBVersion with a userAgent over 400 bytes."); return 0; } self->userAgent = CBNewByteArraySubReference(bytes, 80 + varInt.size, (uint32_t)varInt.val); if (NOT self->userAgent) { CBGetMessage(self)->logError("Cannot create a new CBByteArray in CBVersionDeserialise"); return 0; } self->blockHeight = CBByteArrayReadInt32(bytes, 80 + varInt.size + (uint32_t)varInt.val); return 84 + varInt.size + (uint32_t)varInt.val; }else return 46; // Not the further message. }