Skip to content

Commit

Permalink
Merge pull request #362 from horizontalsystems/bitcoincash-abc-sync
Browse files Browse the repository at this point in the history
Disconnect peer if it is fork of Bitcoin Cash
  • Loading branch information
rafaelekol authored Jun 11, 2019
2 parents 18d151b + dc75a16 commit a9c781f
Show file tree
Hide file tree
Showing 4 changed files with 84 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,12 @@ import android.database.sqlite.SQLiteDatabase
import io.horizontalsystems.bitcoincash.blocks.BitcoinCashBlockValidatorHelper
import io.horizontalsystems.bitcoincash.blocks.validators.DAAValidator
import io.horizontalsystems.bitcoincash.blocks.validators.EDAValidator
import io.horizontalsystems.bitcoincash.blocks.validators.ForkValidator
import io.horizontalsystems.bitcoincore.AbstractKit
import io.horizontalsystems.bitcoincore.BitcoinCore
import io.horizontalsystems.bitcoincore.BitcoinCoreBuilder
import io.horizontalsystems.bitcoincore.blocks.validators.LegacyDifficultyAdjustmentValidator
import io.horizontalsystems.bitcoincore.extensions.toReversedByteArray
import io.horizontalsystems.bitcoincore.managers.BitcoinCashAddressSelector
import io.horizontalsystems.bitcoincore.managers.InsightApi
import io.horizontalsystems.bitcoincore.models.TransactionInfo
Expand Down Expand Up @@ -81,7 +83,12 @@ class BitcoinCashKit : AbstractKit {
if (networkType == NetworkType.MainNet) {
val blockHelper = BitcoinCashBlockValidatorHelper(storage)

bitcoinCore.addBlockValidator(DAAValidator(targetSpacing, blockHelper))
val svForkHeight = 556767
val abcForkBlockHash = "0000000000000000004626ff6e3b936941d341c5932ece4357eeccac44e6d56c".toReversedByteArray()

val daaValidator = DAAValidator(targetSpacing, blockHelper)
bitcoinCore.addBlockValidator(ForkValidator(svForkHeight, abcForkBlockHash, daaValidator))
bitcoinCore.addBlockValidator(daaValidator)
bitcoinCore.addBlockValidator(LegacyDifficultyAdjustmentValidator(blockHelper, heightInterval, targetTimespan, maxTargetBits))
bitcoinCore.addBlockValidator(EDAValidator(maxTargetBits, blockHelper, network.bip44CheckpointBlock.height))
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package io.horizontalsystems.bitcoincash.blocks.validators

import io.horizontalsystems.bitcoincore.blocks.validators.BlockValidatorException
import io.horizontalsystems.bitcoincore.blocks.validators.IBlockValidator
import io.horizontalsystems.bitcoincore.models.Block

class ForkValidator(private val forkHeight: Int, private val expectedBlockHash: ByteArray, private val concreteBlockValidator: IBlockValidator) : IBlockValidator {

override fun isBlockValidatable(block: Block, previousBlock: Block): Boolean {
return block.height == forkHeight
}

override fun validate(block: Block, previousBlock: Block) {
if (!block.headerHash.contentEquals(expectedBlockHash)) {
throw BlockValidatorException.WrongBlockHash(expectedBlockHash, block.headerHash)
}

concreteBlockValidator.validate(block, previousBlock)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
package io.horizontalsystems.bitcoincash.blocks.validators

import com.nhaarman.mockito_kotlin.mock
import com.nhaarman.mockito_kotlin.whenever
import io.horizontalsystems.bitcoincore.blocks.validators.BlockValidatorException
import io.horizontalsystems.bitcoincore.blocks.validators.IBlockValidator
import io.horizontalsystems.bitcoincore.models.Block
import org.junit.Assert
import org.junit.jupiter.api.Assertions
import org.junit.jupiter.api.assertThrows
import org.spekframework.spek2.Spek
import org.spekframework.spek2.style.specification.describe

object ForkValidatorTest : Spek({
val forkHeight = 100
val expectedBlockHash = byteArrayOf(1, 2, 3)
val concreteBlockValidator = mock<IBlockValidator>()
val validator by memoized { ForkValidator(forkHeight, expectedBlockHash, concreteBlockValidator) }

describe("#isBlockValidatable") {
val block = mock<Block>()

it("is true when block height is equal to fork height") {
whenever(block.height).thenReturn(forkHeight)
Assert.assertTrue(validator.isBlockValidatable(block, mock()))
}

it("is false when block height is not equal to fork height") {
whenever(block.height).thenReturn(104)
Assert.assertFalse(validator.isBlockValidatable(block, mock()))
}

}

describe("#validate") {
val block = mock<Block>()

it("validates without any error when block hash is equal to expected block hash") {
whenever(block.headerHash).thenReturn(expectedBlockHash)
Assertions.assertDoesNotThrow {
validator.validate(block, mock())
}
}

it("throws exception when block hash is not equal to expected block hash") {
whenever(block.headerHash).thenReturn(byteArrayOf(3, 2, 1))
assertThrows<BlockValidatorException.WrongBlockHash> {
validator.validate(block, mock())
}
}
}

})
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package io.horizontalsystems.bitcoincore.blocks.validators

import io.horizontalsystems.bitcoincore.extensions.toReversedHex

open class BlockValidatorException(msg: String) : RuntimeException(msg) {
class NoHeader : BlockValidatorException("No Header")
class NoCheckpointBlock : BlockValidatorException("No Checkpoint Block")
Expand All @@ -8,4 +10,5 @@ open class BlockValidatorException(msg: String) : RuntimeException(msg) {
class NotEqualBits : BlockValidatorException("Not Equal Bits")
class NotDifficultyTransitionEqualBits : BlockValidatorException("Not Difficulty Transition Equal Bits")
class InvalidProofOfWork : BlockValidatorException("Invalid Prove of Work")
class WrongBlockHash(expected: ByteArray, actual: ByteArray) : BlockValidatorException("Wrong Block Hash ${actual.toReversedHex()} vs expected ${expected.toReversedHex()}")
}

0 comments on commit a9c781f

Please sign in to comment.