-
Notifications
You must be signed in to change notification settings - Fork 2.4k
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
feat: Add testnet4 chain support (recreated) #2318
base: master
Are you sure you want to change the base?
feat: Add testnet4 chain support (recreated) #2318
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the updates. Definitely looks better now.
Have a couple of fixes that are required, otherwise things crash quite immediately (please test things before requesting review in the future).
After those fixes I was able to sync up to block height 70513
"not appear valid - got %v, want %v", spew.Sdump(hash), | ||
spew.Sdump(TestNet4Params.GenesisHash)) | ||
} | ||
require.Equal(t, "00000000da84f2bafbbc53dee25a72ae507ff4914b867c565be350b0da8bf043", hash.String()) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: line length. just do this?
expectedHash := "00000000da84f2bafbbc53dee25a72ae507ff4914b867c565be3" +
"50b0da8bf043"
require.Equal(t, expectedHash, hash.String())
@@ -268,6 +295,44 @@ var testNet3GenesisBlockBytes = []byte{ | |||
0xac, 0x00, 0x00, 0x00, 0x00, /* |.....| */ | |||
} | |||
|
|||
// testNet4GenesisBlockBytes are the wire encoded bytes for the genesis block of | |||
// the test network (version 4) | |||
var testNet4GenesisBlockBytes = []byte{ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could add it like this to be consistent with the rest:
var testNet4GenesisBlockBytes = []byte{
0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* |........| */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* |........| */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* |........| */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* |........| */
0x00, 0x00, 0x00, 0x00, 0x4e, 0x7b, 0x2b, 0x91, /* |....N{+.| */
0x28, 0xfe, 0x02, 0x91, 0xdb, 0x06, 0x93, 0xaf, /* |(.......| */
0x2a, 0xe4, 0x18, 0xb7, 0x67, 0xe6, 0x57, 0xcd, /* |*...g.W.| */
0x40, 0x7e, 0x80, 0xcb, 0x14, 0x34, 0x22, 0x1e, /* |@~...4".| */
0xae, 0xa7, 0xa0, 0x7a, 0x04, 0x6f, 0x35, 0x66, /* |...z.o5f| */
0xff, 0xff, 0x00, 0x1d, 0xbb, 0x0c, 0x78, 0x17, /* |......x.| */
0x01, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, /* |........| */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* |........| */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* |........| */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* |........| */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, /* |........| */
0xff, 0xff, 0x55, 0x04, 0xff, 0xff, 0x00, 0x1d, /* |..U.....| */
0x01, 0x04, 0x4c, 0x4c, 0x30, 0x33, 0x2f, 0x4d, /* |..LL03/M| */
0x61, 0x79, 0x2f, 0x32, 0x30, 0x32, 0x34, 0x20, /* |ay/2024 | */
0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, /* |00000000| */
0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, /* |00000000| */
0x30, 0x30, 0x30, 0x30, 0x31, 0x65, 0x62, 0x64, /* |00001ebd| */
0x35, 0x38, 0x63, 0x32, 0x34, 0x34, 0x39, 0x37, /* |58c24497| */
0x30, 0x62, 0x33, 0x61, 0x61, 0x39, 0x64, 0x37, /* |0b3aa9d7| */
0x38, 0x33, 0x62, 0x62, 0x30, 0x30, 0x31, 0x30, /* |83bb0010| */
0x31, 0x31, 0x66, 0x62, 0x65, 0x38, 0x65, 0x61, /* |11fbe8ea| */
0x38, 0x65, 0x39, 0x38, 0x65, 0x30, 0x30, 0x65, /* |8e98e00e| */
0xff, 0xff, 0xff, 0xff, 0x01, 0x00, 0xf2, 0x05, /* |........| */
0x2a, 0x01, 0x00, 0x00, 0x00, 0x23, 0x21, 0x00, /* |*....#!.| */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* |........| */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* |........| */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* |........| */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* |........| */
0xac, 0x00, 0x00, 0x00, 0x00, /* |..... | */
}
// interval, except the genesis block. | ||
if blockHeight%c.BlocksPerRetarget() == 0 { | ||
prevBlockTimestamp := time.Unix(prevNode.Timestamp(), 0) | ||
if header.Timestamp.Before( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is a 4th level if
nested block. That's just not readable IMO. This is consensus critical code, readability should be the second-highest priority (after correctness).
Especially if it can be un-nested with early returns in a function.
My proposal:
// Testnet4 only: Check timestamp against prev for
// difficulty-adjustment blocks to prevent timewarp attacks.
if c.ChainParams().EnforceBIP94 {
err := assertNoTimeWarp(
blockHeight, c.BlocksPerRetarget(),
header.Timestamp,
time.Unix(prevNode.Timestamp(), 0),
)
if err != nil {
return err
}
}
...
// assertNoTimeWarp checks the timestamp of the block against the previous
// block's timestamp for the first block of each difficulty adjustment interval
// to prevent timewarp attacks. This is defined in BIP-0094.
func assertNoTimeWarp(blockHeight, blocksPerReTarget int32, headerTimestamp,
prevBlockTimestamp time.Time) error {
// If this isn't the first block of the difficulty adjustment interval,
// then we can exit early.
if blockHeight%blocksPerReTarget != 0 {
return nil
}
// Check timestamp for the first block of each difficulty adjustment
// interval, except the genesis block.
if headerTimestamp.Before(prevBlockTimestamp.Add(-maxTimeWarp)) {
str := "block's timestamp %v is too early on diff adjustment " +
"block %v"
str = fmt.Sprintf(str, headerTimestamp, prevBlockTimestamp)
return ruleError(ErrTimewarpAttack, str)
}
return nil
}
DeploymentTaproot: { | ||
BitNumber: 2, | ||
DeploymentStarter: NewMedianTimeDeploymentStarter( | ||
time.Unix(0, 0), // Always true |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks like we use time.Time{}
in other places, which has a different semantic.
Should replace with:
DeploymentStarter: NewMedianTimeDeploymentStarter(
time.Time{}, // Always available for vote
),
DeploymentEnder: NewMedianTimeDeploymentEnder(
time.Time{}, // Never expires
),
@@ -179,6 +179,9 @@ const ( | |||
// TestNet3 represents the test network (version 3). | |||
TestNet3 BitcoinNet = 0x0709110b | |||
|
|||
// TestNet4 represents the test network (version 4). | |||
TestNet4 BitcoinNet = 0x1c163f28 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This has incorrect endianness and should be 0x283f161c
.
DeploymentEnder: NewMedianTimeDeploymentEnder( | ||
time.Unix(1230767999, 0), // December 31, 2008 UTC | ||
), | ||
}, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Seems like we need the CSV and SegWit deployments here as well, otherwise things panicked on my machine:
DeploymentTestDummyMinActivation: {
BitNumber: 22,
CustomActivationThreshold: 1815, // Only needs 90% hash rate.
MinActivationHeight: 10_0000, // Can only activate after height 10k.
DeploymentStarter: NewMedianTimeDeploymentStarter(
time.Time{}, // Always available for vote
),
DeploymentEnder: NewMedianTimeDeploymentEnder(
time.Time{}, // Never expires
),
},
DeploymentCSV: {
BitNumber: 29,
DeploymentStarter: NewMedianTimeDeploymentStarter(
time.Time{}, // Always available for vote
),
DeploymentEnder: NewMedianTimeDeploymentEnder(
time.Time{}, // Never expires
),
},
DeploymentSegwit: {
BitNumber: 29,
DeploymentStarter: NewMedianTimeDeploymentStarter(
time.Time{}, // Always available for vote
),
DeploymentEnder: NewMedianTimeDeploymentEnder(
time.Time{}, // Never expires
),
},
This PR is a recreation of the previous PR because I incidentally dropped a brunch and the PR was closed automatically.
Description
This PR adds support of the Bitcoin testnet version 4 chain (testnet3 is in a way of deprecation).
Reference: https://bips.dev/94/
Testnet4 genesis block: https://mempool.space/testnet4/block/00000000da84f2bafbbc53dee25a72ae507ff4914b867c565be350b0da8bf043