CBByteArray * CBVersionChecksumBytesGetString(CBVersionChecksumBytes * self) {
    if (self->cachedString) {
        // Return cached string
        CBRetainObject(self->cachedString);
        return self->cachedString;
    } else {
        // Make string
        CBByteArrayReverseBytes(CBGetByteArray(self)); // Make this into little-endian
        CBBigInt bytes;
        CBBigIntAlloc(&bytes, CBGetByteArray(self)->length);
        bytes.length = CBGetByteArray(self)->length;
        memcpy(bytes.data, CBByteArrayGetData(CBGetByteArray(self)), bytes.length);
        char * string = CBEncodeBase58(&bytes);
        if (NOT string)
            return NULL;
        CBByteArray * str = CBNewByteArrayFromString(string, true, CBGetByteArray(self)->logError);
        if (NOT str) {
            free(string);
            return NULL;
        }
        CBByteArrayReverseBytes(CBGetByteArray(self)); // Now the string is got, back to big-endian.
        if (self->cacheString) {
            self->cachedString = str;
            CBRetainObject(str); // Retain for this object.
        }
        return str; // No additional retain. Retained from constructor.
    }
}
Exemple #2
0
void CBInitAlert(CBAlert * self, int32_t version, int64_t relayUntil, int64_t expiration, int32_t ID, int32_t cancel, int32_t minVer, int32_t maxVer, int32_t priority, CBByteArray * hiddenComment, CBByteArray * displayedComment, CBByteArray * reserved) {
	
	self->version = version;
	self->relayUntil = relayUntil;
	self->expiration = expiration;
	self->ID = ID;
	self->cancel = cancel;
	self->minVer = minVer;
	self->maxVer = maxVer;
	self->priority = priority;
	
	self->hiddenComment = hiddenComment;
	if (hiddenComment) CBRetainObject(hiddenComment);
	
	self->displayedComment = displayedComment;
	if (displayedComment) CBRetainObject(displayedComment);
	
	self->reserved = reserved;
	if (reserved) CBRetainObject(reserved);
	
	self->signature = NULL;
	self->payload = NULL;
	
	CBInitMessageByObject(CBGetMessage(self));
	
}
Exemple #3
0
void CBNodeSendMessageOnNetworkThread(CBNetworkCommunicator * self, CBPeer * peer, CBMessage * message, void (*callback)(void *, void *)){
	CBSendMessageData * data = malloc(sizeof(*data));
	*data = (CBSendMessageData){self,peer,message,callback};
	CBRetainObject(message);
	CBRetainObject(peer);
	// Shouldn't block in the cases where this thread already has a mutex used by the CBNetworkCommunicator code.
	CBRunOnEventLoop(self->eventLoop, CBNodeSendMessageOnNetworkThreadVoid, data, false);
}
bool CBInitTransactionInput(CBTransactionInput * self,CBScript * script,uint32_t sequence,CBByteArray * prevOutHash,uint32_t prevOutIndex,void (*onErrorReceived)(CBError error,char *,...)){
	if (script){
		self->scriptObject = script;
		CBRetainObject(script);
	}else
		self->scriptObject = NULL;
	self->prevOut.hash = prevOutHash;
	CBRetainObject(prevOutHash);
	self->prevOut.index = prevOutIndex;
	self->sequence = sequence;
	if (NOT CBInitMessageByObject(CBGetMessage(self), onErrorReceived))
		return false;
	return true;
}
Exemple #5
0
bool CBInitVersion(CBVersion * self,int32_t version,CBVersionServices services,int64_t time,CBNetworkAddress * addRecv,CBNetworkAddress * addSource,uint64_t nonce,CBByteArray * userAgent,int32_t blockHeight,void (*logError)(char *,...)){
	self->version = version;
	self->services = services;
	self->time = time;
	self->addRecv = addRecv;
	CBRetainObject(addRecv);
	self->addSource = addSource;
	CBRetainObject(addSource);
	self->nonce = nonce;
	self->userAgent = userAgent;
	CBRetainObject(userAgent);
	self->blockHeight = blockHeight;
	if (NOT CBInitMessageByObject(CBGetMessage(self), logError))
		return false;
	return true;
}
Exemple #6
0
bool CBInitNetworkAddress(CBNetworkAddress * self, uint64_t lastSeen, CBByteArray * ip, uint16_t port, CBVersionServices services, bool isPublic){
	self->lastSeen = lastSeen;
	self->penalty = 0;
	self->ip = ip;
	self->isPublic = isPublic;
	if (NOT ip) {
		ip = CBNewByteArrayOfSize(16);
		if (NOT ip)
			return false;
		memset(CBByteArrayGetData(ip), 0, 16);
		self->type = CB_IP_INVALID;
	}else{
		// Determine IP type
		self->type = CBGetIPType(CBByteArrayGetData(ip));
		CBRetainObject(ip);
	}
	self->port = port;
	self->services = services;
	self->bucketSet = false;
	if (NOT CBInitMessageByObject(CBGetMessage(self))){
		CBReleaseObject(ip);
		return false;
	}
	return true;
}
Exemple #7
0
bool CBInitInventoryItem(CBInventoryItem * self, CBInventoryItemType type, CBByteArray * hash){
	self->type = type;
	self->hash = hash;
	CBRetainObject(hash);
	if (NOT CBInitMessageByObject(CBGetMessage(self)))
		return false;
	return true;
}
Exemple #8
0
bool CBInitInventoryItem(CBInventoryItem * self,CBInventoryItemType type,CBByteArray * hash,void (*logError)(char *,...)){
	self->type = type;
	self->hash = hash;
	CBRetainObject(hash);
	if (NOT CBInitMessageByObject(CBGetMessage(self), logError))
		return false;
	return true;
}
CBByteArray * CBVersionChecksumBytesGetString(CBVersionChecksumBytes * self){
	if (self->cachedString) {
		// Return cached string
		CBRetainObject(self->cachedString);
		return self->cachedString;
	}else{
		// Make string
		CBByteArrayReverseBytes(CBGetByteArray(self)); // Make this into little-endian
		char * string = CBEncodeBase58(CBByteArrayGetData(CBGetByteArray(self)),CBGetByteArray(self)->length);
		CBByteArray * str = CBNewByteArrayWithData((uint8_t *)string, strlen(string), CBGetByteArray(self)->events);
		CBByteArrayReverseBytes(CBGetByteArray(self)); // Now the string is got, back to big-endian.
		if (self->cacheString) {
			self->cachedString = str;
			CBRetainObject(str); // Retain for this object.
		}
		return str; // No additional retain. Retained from constructor.
	}
}
Exemple #10
0
bool CBInitMessageByData(CBMessage * self,CBByteArray * data,void (*onErrorReceived)(CBError error,char *,...)){
	if (NOT CBInitObject(CBGetObject(self)))
		return false;
	self->bytes = data;
	CBRetainObject(data); // Retain data for this object.
	self->onErrorReceived = onErrorReceived;
	self->expectResponse = false;
	self->serialised = true;
	return true;
}
Exemple #11
0
bool CBInventoryAddInventoryItem(CBInventory * self, CBInventoryItem * item) {
	
	bool taken = CBInventoryTakeInventoryItem(self, item);
	
	if (taken)
		CBRetainObject(item);
	
	return taken;
	
}
bool CBInitTransactionOutput(CBTransactionOutput * self, uint64_t value, CBScript * script){
	if (script){
		self->scriptObject = script;
		CBRetainObject(script);
	}else
		self->scriptObject = NULL;
	self->value = value;
	if (NOT CBInitMessageByObject(CBGetMessage(self)))
		return false;
	return true;
}
Exemple #13
0
CBOnMessageReceivedAction CBNodeOnMessageReceived(CBNetworkCommunicator * comm, CBPeer * peer, CBMessage * message){
	CBNode * self = CBGetNode(comm);
	// Add message to queue
	CBRetainObject(message);
	CBRetainObject(peer);
	CBMutexLock(self->messageProcessMutex);
	if (self->messageQueue == NULL)
		self->messageQueue = self->messageQueueBack = malloc(sizeof(*self->messageQueueBack));
	else{
		self->messageQueueBack->next = malloc(sizeof(*self->messageQueueBack));
		self->messageQueueBack = self->messageQueueBack->next;
	}
	self->messageQueueBack->peer = peer;
	self->messageQueueBack->message = message;
	self->messageQueueBack->next = NULL;
	// Wakeup thread if this is the first in the queue
	if (self->messageQueue == self->messageQueueBack)
		// We have just added a block to the queue when there was not one before so wake-up the processing thread.
		CBConditionSignal(self->messageProcessWaitCond);
	CBMutexUnlock(self->messageProcessMutex);
	return CB_MESSAGE_ACTION_CONTINUE;
}
bool CBInitVersionChecksumBytesFromString(CBVersionChecksumBytes * self,CBByteArray * string,bool cacheString,void (*logError)(char *,...)) {
    // Cache string if needed
    if (cacheString) {
        self->cachedString = string;
        CBRetainObject(string);
    } else
        self->cachedString = NULL;
    self->cacheString = cacheString;
    // Get bytes from string conversion
    CBBigInt bytes;
    CBBigIntAlloc(&bytes, 25); // 25 is the number of bytes for bitcoin addresses.
    if (NOT CBDecodeBase58Checked(&bytes, (char *)CBByteArrayGetData(string), logError))
        return false;
    // Take over the bytes with the CBByteArray
    if (NOT CBInitByteArrayWithData(CBGetByteArray(self), bytes.data, bytes.length, logError))
        return false;
    CBByteArrayReverseBytes(CBGetByteArray(self)); // CBBigInt is in little-endian. Conversion needed to make bitcoin address the right way.
    return true;
}
bool CBInitVersionChecksumBytesFromString(CBVersionChecksumBytes * self,CBByteArray * string,bool cacheString,CBEvents * events){
	// Cache string if needed
	if (cacheString) {
		self->cachedString = string;
		CBRetainObject(string);
	}else
		self->cachedString = NULL;
	self->cacheString = cacheString;
	// Get bytes from string conversion
	CBBigInt bytes = CBDecodeBase58Checked((char *)CBByteArrayGetData(string), events);
	if (bytes.length == 1) {
		return false;
	}
	// Take over the bytes with the CBByteArray
	if (NOT CBInitByteArrayWithData(CBGetByteArray(self), bytes.data, bytes.length, events))
		return false;
	CBByteArrayReverseBytes(CBGetByteArray(self)); // CBBigInt is in little-endian. Conversion needed to make bitcoin address the right way.
	return true;
}
Exemple #16
0
void CBAlertAddUserAgent(CBAlert * self, CBByteArray * userAgent) {
	
	CBRetainObject(userAgent);
	CBAlertTakeUserAgent(self, userAgent);
	
}
Exemple #17
0
bool CBTransactionAddOutput(CBTransaction * self, CBTransactionOutput * output){
	CBRetainObject(output);
	return CBTransactionTakeOutput(self, output);
}
Exemple #18
0
void CBChainDescriptorAddHash(CBChainDescriptor * self, CBByteArray * hash){
	CBRetainObject(hash);
	CBChainDescriptorTakeHash(self, hash);
}
Exemple #19
0
void CBNodeDisconnectPeer(CBPeer * peer){
	CBRetainObject(peer);
	CBRunOnEventLoop(CBGetNetworkCommunicator(peer->nodeObj)->eventLoop, CBNodeDisconnectPeerRun, peer, false);
}
Exemple #20
0
int main(){
	unsigned int s = (unsigned int)time(NULL);
	s = 1337544566;
	printf("Session = %ui\n",s);
	srand(s);
	// Test genesis block
	CBByteArray * genesisMerkleRoot = CBNewByteArrayWithDataCopy((uint8_t []){0x3B,0xA3,0xED,0xFD,0x7A,0x7B,0x12,0xB2,0x7A,0xC7,0x2C,0x3E,0x67,0x76,0x8F,0x61,0x7F,0xC8,0x1B,0xC3,0x88,0x8A,0x51,0x32,0x3A,0x9F,0xB8,0xAA,0x4B,0x1E,0x5E,0x4A}, 32, onErrorReceived);
	CBByteArray * genesisInScript = CBNewByteArrayWithDataCopy((uint8_t [77]){0x04,0xFF,0xFF,0x00,0x1D,0x01,0x04,0x45,0x54,0x68,0x65,0x20,0x54,0x69,0x6D,0x65,0x73,0x20,0x30,0x33,0x2F,0x4A,0x61,0x6E,0x2F,0x32,0x30,0x30,0x39,0x20,0x43,0x68,0x61,0x6E,0x63,0x65,0x6C,0x6C,0x6F,0x72,0x20,0x6F,0x6E,0x20,0x62,0x72,0x69,0x6E,0x6B,0x20,0x6F,0x66,0x20,0x73,0x65,0x63,0x6F,0x6E,0x64,0x20,0x62,0x61,0x69,0x6C,0x6F,0x75,0x74,0x20,0x66,0x6F,0x72,0x20,0x62,0x61,0x6E,0x6B,0x73}, 77, onErrorReceived);
	CBByteArray * genesisOutScript = CBNewByteArrayWithDataCopy((uint8_t [67]){0x41,0x04,0x67,0x8A,0xFD,0xB0,0xFE,0x55,0x48,0x27,0x19,0x67,0xF1,0xA6,0x71,0x30,0xB7,0x10,0x5C,0xD6,0xA8,0x28,0xE0,0x39,0x09,0xA6,0x79,0x62,0xE0,0xEA,0x1F,0x61,0xDE,0xB6,0x49,0xF6,0xBC,0x3F,0x4C,0xEF,0x38,0xC4,0xF3,0x55,0x04,0xE5,0x1E,0xC1,0x12,0xDE,0x5C,0x38,0x4D,0xF7,0xBA,0x0B,0x8D,0x57,0x8A,0x4C,0x70,0x2B,0x6B,0xF1,0x1D,0x5F,0xAC}, 67, onErrorReceived);
	// Test hash
	CBBlock * genesisBlock = CBNewBlockGenesis(onErrorReceived);
	uint8_t calcHash[32];
	CBBlockCalculateHash(genesisBlock,calcHash);
	if(memcmp(genesisBlock->hash, calcHash,32)){
		printf("GENESIS BLOCK HASH FAIL\n0x");
		uint8_t * d = genesisBlock->hash;
		for (int x = 0; x < 32; x++) {
			printf("%.2X",d[x]);
		}
		printf("\n!=\n0x");
		d = calcHash;
		for (int x = 0; x < 32; x++) {
			printf("%.2X",d[x]);
		}
		return 1;
	}
	// Test deserialised data
	if (genesisBlock->version != 1) {
		printf("GENESIS BLOCK VERSION FAIL\n");
		return 1;
	}
	for (int x = 0; x < 32; x++) {
		if(CBByteArrayGetByte(genesisBlock->prevBlockHash, x) != 0){
			printf("GENESIS BLOCK PREV FAIL\n");
			return 1;
		}
	}
	if (CBByteArrayCompare(genesisBlock->merkleRoot, genesisMerkleRoot)) {
		printf("GENESIS BLOCK MERKLE ROOT FAIL\n0x");
		uint8_t * d = CBByteArrayGetData(genesisBlock->merkleRoot);
		for (int x = 0; x < 32; x++) {
			printf("%.2X",d[x]);
		}
		printf("\n!=\n0x");
		d = CBByteArrayGetData(genesisMerkleRoot);
		for (int x = 0; x < 32; x++) {
			printf("%.2X",d[x]);
		}
		return 1;
	}
	if (genesisBlock->time != 1231006505) {
		printf("GENESIS BLOCK TIME FAIL\n0x");
		return 1;
	}
	if (genesisBlock->target != 0x1D00FFFF) {
		printf("GENESIS BLOCK DIFFICULTY FAIL\n0x");
		return 1;
	}
	if (genesisBlock->nonce != 2083236893) {
		printf("GENESIS BLOCK DIFFICULTY FAIL\n0x");
		return 1;
	}
	if (genesisBlock->transactionNum != 1) {
		printf("GENESIS BLOCK TRANSACTION NUM FAIL\n0x");
		return 1;
	}
	CBTransaction * genesisCoinBase = genesisBlock->transactions[0];
	if (genesisCoinBase->inputNum != 1) {
		printf("GENESIS BLOCK TRANSACTION INPUT NUM FAIL\n0x");
		return 1;
	}
	if (genesisCoinBase->outputNum != 1) {
		printf("GENESIS BLOCK TRANSACTION OUTPUT NUM FAIL\n0x");
		return 1;
	}
	if (genesisCoinBase->version != 1) {
		printf("GENESIS BLOCK TRANSACTION VERSION FAIL\n0x");
		return 1;
	}
	if (genesisCoinBase->lockTime != 0) {
		printf("GENESIS BLOCK TRANSACTION LOCK TIME FAIL\n0x");
		return 1;
	}
	if (genesisCoinBase->inputs[0]->scriptObject->length != 0x4D) {
		printf("GENESIS BLOCK TRANSACTION INPUT SCRIPT LENGTH FAIL\n0x");
		return 1;
	}
	if (genesisCoinBase->outputs[0]->scriptObject->length != 0x43) {
		printf("GENESIS BLOCK TRANSACTION OUTPUT SCRIPT LENGTH FAIL\n0x");
		return 1;
	}
	for (int x = 0; x < 32; x++) {
		if(CBByteArrayGetByte(genesisCoinBase->inputs[0]->prevOut.hash, x) != 0){
			printf("GENESIS BLOCK TRANSACTION INPUT OUT POINTER HASH FAIL\n");
			return 1;
		}
	}
	if (genesisCoinBase->inputs[0]->prevOut.index != 0xFFFFFFFF) {
		printf("GENESIS BLOCK TRANSACTION INPUT OUT POINTER INDEX FAIL\n0x");
		return 1;
	}
	if (genesisCoinBase->inputs[0]->sequence != CB_TRANSACTION_INPUT_FINAL) {
		printf("GENESIS BLOCK TRANSACTION INPUT SEQUENCE FAIL\n0x");
		return 1;
	}
	if (CBByteArrayCompare(genesisCoinBase->inputs[0]->scriptObject, genesisInScript)) {
		printf("GENESIS BLOCK IN SCRIPT FAIL\n0x");
		uint8_t * d = CBByteArrayGetData(genesisCoinBase->inputs[0]->scriptObject);
		for (int x = 0; x < genesisCoinBase->inputs[0]->scriptObject->length; x++) {
			printf("%.2X",d[x]);
		}
		printf("\n!=\n0x");
		d = CBByteArrayGetData(genesisInScript);
		for (int x = 0; x < genesisInScript->length; x++) {
			printf("%.2X",d[x]);
		}
		return 1;
	}
	if (genesisCoinBase->outputs[0]->value != 5000000000) {
		printf("GENESIS BLOCK TRANSACTION OUTPUT VALUE FAIL\n0x");
		return 1;
	}
	if (CBByteArrayCompare(genesisCoinBase->outputs[0]->scriptObject, genesisOutScript)) {
		printf("GENESIS BLOCK OUT SCRIPT FAIL\n0x");
		uint8_t * d = CBByteArrayGetData(genesisCoinBase->outputs[0]->scriptObject);
		for (int x = 0; x < genesisCoinBase->outputs[0]->scriptObject->length; x++) {
			printf("%.2X",d[x]);
		}
		printf("\n!=\n0x");
		d = CBByteArrayGetData(genesisOutScript);
		for (int x = 0; x < genesisOutScript->length; x++) {
			printf("%.2X",d[x]);
		}
		return 1;
	}
	// Test serialisation into genesis block
	CBBlock * block = CBNewBlock(onErrorReceived);
	block->version = 1;
	uint8_t * zeroHash = malloc(32);
	memset(zeroHash, 0, 32);
	block->prevBlockHash = CBNewByteArrayWithData(zeroHash, 32, onErrorReceived);
	block->merkleRoot = genesisMerkleRoot;
	block->target = 0x1D00FFFF;
	block->time = 1231006505;
	block->nonce = 2083236893;
	block->transactionNum = 1;
	block->transactions = malloc(sizeof(*block->transactions));
	block->transactions[0] = CBNewTransaction(0, 1, onErrorReceived);
	CBRetainObject(block->prevBlockHash); // Retain for the zero hash in the input
	CBTransactionTakeInput(block->transactions[0], CBNewTransactionInput(genesisInScript, CB_TRANSACTION_INPUT_FINAL, block->prevBlockHash, 0xFFFFFFFF, onErrorReceived));
	CBTransactionTakeOutput(block->transactions[0], CBNewTransactionOutput(5000000000, genesisOutScript, onErrorReceived));
	CBGetMessage(block)->bytes = CBNewByteArrayOfSize(CBGetMessage(genesisBlock)->bytes->length, onErrorReceived);
	CBBlockSerialise(block, true, true);
	if (CBByteArrayCompare(CBGetMessage(block)->bytes, CBGetMessage(genesisBlock)->bytes)) {
		printf("SERIALISATION TO GENESIS BLOCK FAIL\n0x");
		uint8_t * d = CBByteArrayGetData(CBGetMessage(block)->bytes);
		for (int x = 0; x < CBGetMessage(block)->bytes->length; x++) {
			printf("%.2X",d[x]);
		}
		printf("\n!=\n0x");
		d = CBByteArrayGetData(CBGetMessage(genesisBlock)->bytes);
		for (int x = 0; x < CBGetMessage(genesisBlock)->bytes->length; x++) {
			printf("%.2X",d[x]);
		}
		return 1;
	}
	CBReleaseObject(genesisBlock);
	// ??? Add tests for non-genesis blocks
	return 0;
}
Exemple #21
0
void CBBlockHeadersAddBlockHeader(CBBlockHeaders * self, CBBlock * header){
	CBRetainObject(header);
	CBBlockHeadersTakeBlockHeader(self, header);
}
bool CBAddressBroadcastAddNetworkAddress(CBAddressBroadcast * self,CBNetworkAddress * address){
	CBRetainObject(address);
	return CBAddressBroadcastTakeNetworkAddress(self,address);
}
Exemple #23
0
bool CBTransactionAddInput(CBTransaction * self, CBTransactionInput * input){
	CBRetainObject(input);
	return CBTransactionTakeInput(self, input);
}
Exemple #24
0
void CBInitTransactionInput(CBTransactionInput * self, CBScript * script, uint32_t sequence, CBByteArray * prevOutHash, uint32_t prevOutIndex){
	if (script)
		CBRetainObject(script);
	CBRetainObject(prevOutHash);
	CBInitTransactionInputTakeScriptAndHash(self, script, sequence, prevOutHash, prevOutIndex);
}
void CBNetworkAddressListAddNetworkAddress(CBNetworkAddressList * self, CBNetworkAddress * address){
	CBRetainObject(address);
	CBNetworkAddressListTakeNetworkAddress(self, address);
}
Exemple #26
0
bool CBBlockHeadersAddBlockHeader(CBBlockHeaders * self,CBBlock * header) {
    CBRetainObject(header);
    return CBBlockHeadersTakeBlockHeader(self,header);
}