Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

btc relay running into Incorrect difficulty target error #84

Open
gupadhyaya opened this issue Jan 3, 2022 · 2 comments
Open

btc relay running into Incorrect difficulty target error #84

gupadhyaya opened this issue Jan 3, 2022 · 2 comments
Assignees

Comments

@gupadhyaya
Copy link
Contributor

btc relay contract (https://explorer.harmony.one/address/0xf058a288d504fed8535afddef106bfbd48d8e72e) seem to be running into Incorrect difficulty target error repeatedly.

@hashmesan
Copy link

hashmesan commented May 24, 2022

Part I - Analysis

The first part of the analysis is to verify whether the difficulty function isCorrectDifficultyTarget is matching with the bitcoin data. It was tested with latest block and worked as expected.

Then, I proceeded to look at the specific block that failed, that require writing some tools to fetch all the account history data and see where it started failing. Finding the block requires some parsing of the header and rehash it. This article and difficulty stats page was helpful.

The following is the harmony transaction => bitcoin transaction mapping.

    if(e.input && e.input.startsWith("0xc14e9f58")) { // submitHeader
        var header = e.input.substring(138, 138+160);
        var headerBuf = Buffer.from(header, "hex")
        var headerDecoded = BitcoinBlock.decodeHeaderOnly(headerBuf);
        //console.log(header);
        console.log(e.ethHash, "->", (Buffer.from(headerDecoded.hash).reverse().toString("hex")))
    }

Output

[truncated]
0x79e562cf32e070dd1d77a2bfd1006635f9b9b5a08e396ea5e1c7311eef477c19 -> 0000000000000000000769594a98bd5a813e8554c5eded0ddb994a0ff2546fcf
0x2fd62dbe339dc397be38023df3a2fcca54254a27d75707af501cfee32f164862 -> 0000000000000000000769594a98bd5a813e8554c5eded0ddb994a0ff2546fcf
0x760bbe4524c5834c5359db78522412a69ba5a1135ca5ccbf2915f76b60c1c627 -> 0000000000000000000769594a98bd5a813e8554c5eded0ddb994a0ff2546fcf
0x568ee9499d4b443dec337abcf6bea2cad05931d55fe7abbd23e3d279d21054b5 -> 0000000000000000000769594a98bd5a813e8554c5eded0ddb994a0ff2546fcf
0x3ca7304af157ff761b4924f6a1573549e7787080f7b39f1dc563239184a27fc0 -> 00000000000000000004680d21d3c5e94dc03d197a3bb5653b1f9d7d5015a2a9
0x50b8b56f91239485b598adee6e793938189c749a32bcf0edd9d320a54ce02661 -> 00000000000000000007f3976e8f71ab54516e5afcab962d86c0ffe2fe82b503
0x7e086ccf43e0f7e97986197704d0262e07e59fcf5b69fc840a77b62d52d3b3eb -> 000000000000000000016af0391a356ada4b09fe137a7fdb35a747ee543ce2bc
0xc29be9d73177a8060d4a22cd7b70b2145a76fc313055b422486e15e6e1944972 -> 00000000000000000000af8b9cb78c9c6e1118382c269f9e746f896a17b9e073
[truncated]

Each difficulty epoch lasts for 2016 blocks. The difficulty function is calculated by taking parameters (startTarget, startTime, and end Time)

The last working bitcoin block : 00000000000000000004680d21d3c5e94dc03d197a3bb5653b1f9d7d5015a2a9 (end of epoch) succeeded then the next one failed : 0000000000000000000769594a98bd5a813e8554c5eded0ddb994a0ff2546fcf (start of new epoch)

When I retrieved the data from bitcoin blockchain and called isCorrectDifficultyTarget, it successful calculated the target.

start epoch
713664 (height)
00000000000000000007e0f205011034fcb6577b0840b35fcabc4f5a77645f35
0x170ba21f
**1639216857** (Saturday, December 11, 2021 10:00:57 AM)

end of epoch
00000000000000000004680d21d3c5e94dc03d197a3bb5653b1f9d7d5015a2a9
715679 (height)
0x170ba21f (bits)
1640422619 (time)
epoch = 354.999

If it works with bitcoin data, then there is no issue with difficulty function, therefore the state of the contract is the cause... next I wrote a script to pull the states of the parameters (startTarget, startTime, and end Time)

npx buidler run scripts/mainnet_fetch.ts --network mainnet 
All contracts have already been compiled, skipping compilation.
Current height: 0xa9a215507d9d1f3b65b53b7a193dc04de9c5d3210d6804000000000000000000,715679
epochStartTime: **1640114681** (Tuesday, December 21, 2021 7:24:41 PM)
epochStartTarget: 1114247386799443053935571112778061457902663314832359424
epochEndTime: 1640422619
epochEndTarget: 1114247386799443053935571112778061457902663314832359424

THE STATE PARAMETERS ARE DIFFERENT THAN BITCOIN BLOCKCHAIN!
I suspect there was a header that came in with the same block height and overwrote the time stamp. The bad block came 10 days after the start difficulty epoch (December 11), which was Dec 21.

Next steps: Trace down which _submitBlockHeader caused the startEpochTime. It could be caused by a fork, not sure at this moment. We may have to add some error checking to prevent this happen in the future.

@hashmesan
Copy link

hashmesan commented May 25, 2022

Part II Analysis

There are total of 45256 submitBlockHeader transactions. There are 44718 txs that are duplicate and failed.
There are 538 remaining transactions that are valid. (not enough for a full epoch - 2016)
The oldest transaction is 0xec8a6ca54e5336dec0cd6edd8b7db8393ba836381c5bb12ed7902ad9c43ec371 with block header
000000000000000000068a54e6e187dc6d55460ce14fff23fe03113ede4496d1 on block 715141 @ time 1640115873.

The epochStartTime already present on the contract is
epochStartTime: **1640114681** (Tuesday, December 21, 2021 7:24:41 PM). (Notice it is smaller than the oldest block that was submited @ 1640115873)

The conclusion is: The contract was initialized with the wrong parameters. Make sure it is initialized with the correct startEpoch block.

Take current block divide by 2016, take the floor to get the Epoch #. Take the Epoch # multiply by 2016 to find your begin epoch. Feed in with the correct target, and time from bitcoin getblock.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants