horizontalsystems/bitcoin-kit-ios

RegTest support

cuhte3 opened this issue ยท 9 comments

Thanks for the awesome library!

I'd like to extend the kit to support regTest in my app. It seems like there are at least 3 steps involved:

  • implement RegTest class which follows INetwork protocol
  • implement transactions syncer class which follows ISyncTransactionApi protocol
  • add hardcoded checkpoints for the network

Would that be enough or I miss something?

First two steps seems pretty straightforward however am wondering how the checkpoint strings are encoded..?

esen commented

Hey @cuhte3 ,

For RegTest you better use this class. You don't have to implement ISyncTransactionApi and make a checkpoint file because syncableFromApi parameter of RegTest class is false. It just syncs everything from your node. ISyncTransactionApi is for those who want to do an initial sync(transactions before the checkpoint) from API.

Hey @esen,

initially I've tried to use the default RegTest implementation (replaced only dnsSeed and port)

network = RegTest()
initialSyncApi = nil

however BitcoinCoreBuilder build() function throws an error if the transaction syncer isn't provided.

guard let initialSyncApi = initialSyncApi else { throw BuildError.noInitialSyncApi }

esen commented

guard let initialSyncApi = initialSyncApi else { throw BuildError.noInitialSyncApi }

Seems like a bug, this network type was not used for a long time. Let's mark this ticket a bug.

This API is not actually needed if network.syncableFromApi is false. I think, if you have implemented a ISyncTransactionApi protocol already, you can set it to the builder and use the existing RegTest network.

Yeah I've implemented the syncer, the only thing is still not clear is how to encode a block as checkpoint string? Could please provide an example? @esen

Thanks!

esen commented

We use checkpoint files generated by our android tool here. But you don't have to have checkpoints file. You can use full sync mode which doesn't require any checkpoints

Thanks for the hint @esen I'll try the android tool! Initially I've tried the .full sync mode, but even in full mode checkpoint is required otherwise app will crush here when this is called inside BitcoinCoreBuilder build().

I was able create checkpoint string using the android tool, however am having an issue while decoding it.

Here is how I encoded the block:

val blockHeader = BlockHeader(
      version = 1, 
      previousBlockHeaderHash = "6f102460dad34356a6e2cdd318b8664c8359c46cb30b3256aee99b9681efe264".toByteArray(Charsets.UTF_8), 
      merkleRoot = "93be680f2ddf0ef81afd1c35549a01151047553b81a78f66ff00f894638c8b49".toByteArray(Charsets.UTF_8), 
      timestamp = 1648491396, 
      bits = 545259519, 
      nonce = 2, 
      hash = "7144667ea86f6f7f539aaf60e9ebbee582ccb83fcb6022504732e77279c4427b".toByteArray(Charsets.UTF_8)
)
val block = Block(header = blockHeader, height = 75813)

the output checkpoint string looks like this

01000000366631303234363064616433343335366136653263646433313862383636346338333539633436636233306233323536616565393962393638316566653236343933626536383066326464663065663831616664316333353534396130313135313034373535336238316137386636366666303066383934363338633862343984fb4162ffff7f20020000002528010037313434363637656138366636663766353339616166363065396562626565353832636362383366636236303232353034373332653737323739633434323762

I assume its way too long (compared to those in framework) and it's decode into wrong block (wrong height, timestamp, bits etc). This resulting me having having peerHasExpiredBlockChain error (height of this decoded block far ahead)

if I do not include previous block header hash info the output string looks like this

010000003933626536383066326464663065663831616664316333353534396130313135313034373535336238316137386636366666303066383934363338633862343984fb4162ffff7f20020000002528010037313434363637656138366636663766353339616166363065396562626565353832636362383366636236303232353034373332653737323739633434323762

the block data decoded correctly however am getting noPreviousBlock error here

@esen could you please provide en example how to encode a block? Should the bip44 checkpoint pointing to genesis block?

esen commented

@cuhte3,

You have wrong Block initialization. Here is are examples of initializing a Block instance from raw hex values.