Skip to content

Commit

Permalink
SA-93 Add empty block validation
Browse files Browse the repository at this point in the history
  • Loading branch information
Beksultan committed Jul 10, 2023
1 parent f7e511b commit 8b6eeca
Show file tree
Hide file tree
Showing 9 changed files with 25 additions and 14 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -61,4 +61,8 @@ class MainBlockPayload(
override fun getBytes(): ByteArray =
transactionMerkleHash.toByteArray() + stateMerkleHash.toByteArray() + receiptMerkleHash.toByteArray()

fun hasTransferTransactions(): Boolean = transferTransactions.isNotEmpty()

fun hasVoteTransactions(): Boolean = voteTransactions.isNotEmpty()

}
Original file line number Diff line number Diff line change
Expand Up @@ -125,37 +125,43 @@ class MainBlockValidator(

fun checkReceiptsAndStates(): BlockValidateHandler = { block, _, _, new ->
block as MainBlock
val blockStates = block.getPayload().delegateStates + block.getPayload().accountStates
val payload = block.getPayload()
val blockStates = payload.delegateStates + payload.accountStates

blockStates.forEach {
if (!stateManager.verify(it)) {
throw ValidationException("Invalid block states in block: height #${block.height}, hash ${block.hash}")
}
}

block.getPayload().receipts.forEach {
payload.receipts.forEach {
if (!receiptService.verify(it)) {
throw ValidationException("Invalid block receipts in block: height #${block.height}, hash ${block.hash}")
}
}

if (new) {
val delegateWallet = stateManager.getByAddress<DelegateState>(block.publicKey).walletAddress
val transactions = block.getPayload().delegateTransactions + block.getPayload().transferTransactions +
block.getPayload().voteTransactions + block.getPayload().rewardTransactions
val transactions = payload.delegateTransactions + payload.transferTransactions +
payload.voteTransactions + payload.rewardTransactions
val receipts = transactionManager.processTransactions(transactions, delegateWallet)
val states = statePool.getStates()

if (block.getPayload().receipts.size != receipts.size) {
if (payload.receipts.size != receipts.size) {
throw ValidationException("Invalid count block receipts in block: height #${block.height}, hash ${block.hash}")
}

if (!consensusProperties.emptyBlockProductionEnabled!! && !payload.hasTransferTransactions() && !payload.hasVoteTransactions()) {
throw ValidationException("Block won't be created due to allow to create empty blocks: ${consensusProperties.emptyBlockProductionEnabled}" +
" has transfer transactions: ${payload.hasTransferTransactions()} has vote transactions: ${payload.hasVoteTransactions()}")
}

if (blockStates.size != states.size) {
throw ValidationException("Invalid count block states in block: height #${block.height}, hash ${block.hash}")
}

receipts.forEach { r ->
block.getPayload().receipts.firstOrNull { it.hash == r.hash }
payload.receipts.firstOrNull { it.hash == r.hash }
?: throw ValidationException("Invalid block receipts in block: height #${block.height}, hash ${block.hash}")
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ data class NodeInfo(

override fun read(buf: ByteBuf) {
uid = buf.readString()
address = NetworkAddress::class.java.newInstance()
address = NetworkAddress::class.java.getDeclaredConstructor().newInstance()
address.read(buf)
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ inline fun <reified T : Message> ByteBuf.readList(): MutableList<T> {
val size = this.readInt()
val list = mutableListOf<T>()
for (index in 1..size) {
val instance = T::class.java.newInstance()
val instance = T::class.java.getDeclaredConstructor().newInstance()
instance.read(this)
list.add(instance)
}
Expand All @@ -55,7 +55,7 @@ inline fun <reified T : Message> ByteBuf.readSet(): MutableSet<T> {
val size = this.readInt()
val set = mutableSetOf<T>()
for (index in 1..size) {
val instance = T::class.java.newInstance()
val instance = T::class.java.getDeclaredConstructor().newInstance()
instance.read(this)
set.add(instance)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -65,9 +65,10 @@ class ClientChannelInitializer(
epochResponseHandler,
mainBlockHandler,
genesisBlockHandler,

blockAvailabilityRequestHandler,
blockAvailabilityResponseHandler,
syncStatusHandler,
blockAvailabilityRequestHandler,
// core
transferTransactionHandler,
delegateTransactionHandler,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -65,9 +65,9 @@ class ServerChannelInitializer(
epochResponseHandler,
mainBlockHandler,
genesisBlockHandler,
blockAvailabilityRequestHandler,
blockAvailabilityResponseHandler,
syncStatusHandler,
blockAvailabilityRequestHandler,
// core
transferTransactionHandler,
delegateTransactionHandler,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ class BlockAvailabilityResponse(
hash = buf.readString()
height = buf.readLong()
if (-1L != height) {
val block = GenesisBlockMessage::class.java.newInstance()
val block = GenesisBlockMessage::class.java.getDeclaredConstructor().newInstance()
block.read(buf)
genesisBlock = block
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ data class NewClient(
) : Message {

override fun read(buf: ByteBuf) {
nodeInfo = NodeInfo::class.java.newInstance()
nodeInfo = NodeInfo::class.java.getDeclaredConstructor().newInstance()
nodeInfo.read(buf)
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ object SmartContractInjector {


fun initSmartContract(clazz: Class<*>, owner: String, address: String): SmartContract {
val instance = clazz.newInstance() as SmartContract
val instance = clazz.getDeclaredConstructor().newInstance() as SmartContract

injectField(instance, OWNER_FIELD, owner)
injectField(instance, ADDRESS_FIELD, address)
Expand Down

0 comments on commit 8b6eeca

Please sign in to comment.