bool CBBlockChainStorageLoadOrphan(void * validator, uint8_t orphanNum){ CBFullValidator * validatorObj = validator; CBDatabase * database = (CBDatabase *)validatorObj->storage; CB_ORPHAN_KEY[2] = orphanNum; uint32_t len = CBDatabaseGetLength(database, CB_ORPHAN_KEY); CBByteArray * orphanData = CBNewByteArrayOfSize(len); if (NOT orphanData) { CBLogError("There was an error when initialising a byte array for an orphan."); return false; } if (NOT CBDatabaseReadValue(database, CB_ORPHAN_KEY, CBByteArrayGetData(orphanData), len, 0)) { CBLogError("There was an error when reading the data for an orphan."); CBReleaseObject(orphanData); return false; } validatorObj->orphans[orphanNum] = CBNewBlockFromData(orphanData); CBBlockDeserialise(validatorObj->orphans[orphanNum], true); if (NOT validatorObj->orphans[orphanNum]) { CBLogError("There was an error when creating a block object for an orphan."); CBReleaseObject(orphanData); return false; } CBReleaseObject(orphanData); return true; }
void * CBBlockChainStorageLoadBlock(void * validator, uint32_t blockID, uint32_t branch){ CBFullValidator * validatorObj = validator; CBDatabase * database = (CBDatabase *)validatorObj->storage; CB_BLOCK_KEY[2] = branch; CBInt32ToArray(CB_BLOCK_KEY, 3, blockID); uint32_t blockDataLen = CBDatabaseGetLength(database, CB_BLOCK_KEY); if (NOT blockDataLen) return NULL; blockDataLen -= CB_BLOCK_START; // Get block data CBByteArray * data = CBNewByteArrayOfSize(blockDataLen); if (NOT data) { CBLogError("Could not initialise a byte array for loading a block."); return NULL; } if (NOT CBDatabaseReadValue(database, CB_BLOCK_KEY, CBByteArrayGetData(data), blockDataLen, CB_BLOCK_START)){ CBLogError("Could not read a block from the database."); CBReleaseObject(data); return NULL; } // Make and return the block CBBlock * block = CBNewBlockFromData(data); CBReleaseObject(data); if (NOT block) { CBLogError("Could not create a block object when loading a block."); return NULL; } return block; }
uint32_t CBBlockHeadersDeserialise(CBBlockHeaders * self) { CBByteArray * bytes = CBGetMessage(self)->bytes; if (NOT bytes) { CBGetMessage(self)->logError("Attempting to deserialise a CBBlockHeaders with no bytes."); return 0; } if (bytes->length < 82) { CBGetMessage(self)->logError("Attempting to deserialise a CBBlockHeaders with less bytes than required for one header."); return 0; } CBVarInt headerNum = CBVarIntDecode(bytes, 0); if (headerNum.val > 2000) { CBGetMessage(self)->logError("Attempting to deserialise a CBBlockHeaders with a var int over 2000."); return 0; } // Deserialise each header self->blockHeaders = malloc(sizeof(*self->blockHeaders) * (size_t)headerNum.val); if (NOT self->blockHeaders) { CBGetMessage(self)->logError("Cannot allocate %i bytes of memory in CBBlockHeadersDeserialise\n",sizeof(*self->blockHeaders) * (size_t)headerNum.val); return 0; } self->headerNum = headerNum.val; uint16_t cursor = headerNum.size; for (uint16_t x = 0; x < headerNum.val; x++) { // Make new CBBlock from the rest of the data. CBByteArray * data = CBByteArraySubReference(bytes, cursor, bytes->length-cursor); if (NOT data) { CBGetMessage(self)->logError("Cannot create a new CBByteArray in CBBlockHeadersDeserialise for the header number %u.",x); return 0; } self->blockHeaders[x] = CBNewBlockFromData(data, CBGetMessage(self)->logError); if (NOT self->blockHeaders[x]) { CBGetMessage(self)->logError("Cannot create a new CBBlock in CBBlockHeadersDeserialise for the header number %u.",x); CBReleaseObject(data); return 0; } // Deserialise uint8_t len = CBBlockDeserialise(self->blockHeaders[x], false); // false for no transactions. Only the header. if (NOT len) { CBGetMessage(self)->logError("CBBlockHeaders cannot be deserialised because of an error with the CBBlock number %u.",x); CBReleaseObject(data); return 0; } // Adjust length data->length = len; CBReleaseObject(data); cursor += len; } return cursor; }
void BRHandleBlock(BRConnection *c, CBByteArray *message) { BRBlockChain *bc = ((BRConnector *) c->connector)->block_chain; CBBlock *block = CBNewBlockFromData(message); CBBlockDeserialise(block, true); /* process block */ CBBlockStatus status = CBFullValidatorProcessBlock(bc->validator, block, time(NULL)); #ifdef BRDEBUG if (status != CB_BLOCK_STATUS_MAIN) { fprintf(stderr, "Block didn't extend the main branch. Status: %d. See CBBlockStatus struct in include/CBFullValidator.h\n", status); } #endif CBReleaseObject(block); }
int CBBlockHeadersDeserialise(CBBlockHeaders * self) { CBByteArray * bytes = CBGetMessage(self)->bytes; if (! bytes) { CBLogError("Attempting to deserialise a CBBlockHeaders with no bytes."); return CB_DESERIALISE_ERROR; } if (bytes->length < 82) { CBLogError("Attempting to deserialise a CBBlockHeaders with less bytes than required for one header."); return CB_DESERIALISE_ERROR; } CBVarInt headerNum = CBByteArrayReadVarInt(bytes, 0); if (headerNum.val > 2000) { CBLogError("Attempting to deserialise a CBBlockHeaders with a var int over 2000."); return CB_DESERIALISE_ERROR; } // Deserialise each header self->headerNum = headerNum.val; int cursor = headerNum.size; for (int x = 0; x < headerNum.val; x++) { // Make new CBBlock from the rest of the data. CBByteArray * data = CBByteArraySubReference(bytes, cursor, bytes->length-cursor); self->blockHeaders[x] = CBNewBlockFromData(data); // Deserialise int len = CBBlockDeserialise(self->blockHeaders[x], false); // false for no transactions. Only the header. if (len == CB_DESERIALISE_ERROR){ CBLogError("CBBlockHeaders cannot be deserialised because of an error with the CBBlock number %" PRIu16 ".", x); CBReleaseObject(data); return CB_DESERIALISE_ERROR; } // Adjust length data->length = len; CBReleaseObject(data); cursor += len; } return cursor; }