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;
}
Exemple #3
0
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;
	}
}