This commit is contained in:
Chris Stewart 2025-03-12 10:35:20 -05:00 committed by GitHub
commit c63887a080
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
24 changed files with 180 additions and 56 deletions

View file

@ -139,6 +139,7 @@ abstract class AppConfig extends StartStopAsync[Unit] with BitcoinSLogger {
val lastDirname = network match {
case MainNet => "mainnet"
case TestNet3 => "testnet3"
case TestNet4 => "testnet4"
case RegTest => "regtest"
case SigNet => "signet"
}

View file

@ -5,7 +5,8 @@ import org.bitcoins.core.config.{
MainNet,
RegTest,
SigNet,
TestNet3
TestNet3,
TestNet4
}
import org.bitcoins.crypto.StringFactory
@ -58,7 +59,7 @@ object ExplorerEnv extends StringFactory[ExplorerEnv] {
def fromBitcoinNetwork(network: BitcoinNetwork): ExplorerEnv = {
network match {
case MainNet => Production
case TestNet3 | RegTest | SigNet => Test
case TestNet3 | TestNet4 | RegTest | SigNet => Test
}
}
}

View file

@ -15,6 +15,7 @@ object DatadirUtil {
case "testnet3" => TestNet3
case "testnet" => TestNet3
case "test" => TestNet3
case "testnet4" => TestNet4
case "regtest" => RegTest
case "signet" => SigNet
case "sig" => SigNet
@ -25,6 +26,7 @@ object DatadirUtil {
network match {
case MainNet => "mainnet"
case TestNet3 => "testnet3"
case TestNet4 => "testnet4"
case RegTest => "regtest"
case SigNet => "signet"
}

View file

@ -35,7 +35,7 @@
<appender-ref ref="ASYNC-FILE"/>
</root>
<logger name="org.bitcoins.node" level="INFO"/>
<logger name="org.bitcoins.node" level="DEBUG"/>
<logger name="org.bitcoins.chain" level="INFO"/>

View file

@ -16,7 +16,7 @@ import org.bitcoins.commons.jsonmodels.bitcoind.GetBlockHeaderResult
import org.bitcoins.commons.util.BitcoinSLogger
import org.bitcoins.core.api.node.NodeApi
import org.bitcoins.core.api.wallet.{NeutrinoHDWalletApi, WalletApi}
import org.bitcoins.core.config.{MainNet, RegTest, SigNet, TestNet3}
import org.bitcoins.core.config.{MainNet, RegTest, SigNet, TestNet3, TestNet4}
import org.bitcoins.core.gcs.FilterType
import org.bitcoins.core.protocol.blockchain.Block
import org.bitcoins.core.protocol.transaction.Transaction
@ -430,7 +430,7 @@ object BitcoindRpcBackendUtil extends BitcoinSLogger {
import system.dispatcher
val interval = intervalOpt.getOrElse {
bitcoind.bitcoindRpcAppConfig.network match {
case MainNet | TestNet3 | SigNet => 10.seconds
case MainNet | TestNet3 | TestNet4 | SigNet => 10.seconds
case RegTest => 1.second
}
}

View file

@ -70,6 +70,7 @@ trait Client
val prefix = instance.network match {
case MainNet => ""
case TestNet3 => "testnet"
case TestNet4 => "testnet4"
case RegTest => "regtest"
case SigNet => "signet"
}

View file

@ -61,6 +61,7 @@ object BitcoindAuthCredentials extends BitcoinSLogger {
case TestNet3 => "testnet3"
case RegTest => "regtest"
case SigNet => "signet"
case TestNet4 => "testnet4"
}
Paths.get(datadir.toString, middleSegment, ".cookie")

View file

@ -70,15 +70,17 @@ case class BitcoindConfig(
case MainNet => "main"
case RegTest => "regtest"
case TestNet3 => "test"
case TestNet4 => "testnet4"
case SigNet => "signet"
}
/** The networks we're _not_ on */
private lazy val otherNetworks = network match {
case MainNet => List("test", "regtest", "signet")
case RegTest => List("main", "test", "signet")
case TestNet3 => List("main", "regtest", "signet")
case SigNet => List("main", "test", "regtest")
case MainNet => List("test", "regtest", "signet", "testnet4")
case RegTest => List("main", "test", "signet", "testnet4")
case TestNet3 => List("main", "regtest", "signet", "testnet4")
case TestNet4 => List("main", "test", "regtest", "signet")
case SigNet => List("main", "test", "regtest", "testnet4")
}
private lazy val ourNetworkString: String = networkString(network)

View file

@ -49,7 +49,7 @@ sealed abstract class Pow {
case RegTestNetChainParams =>
RegTestNetChainParams.compressedPowLimit
case TestNetChainParams | MainNetChainParams |
SigNetChainParams(_) =>
SigNetChainParams(_) | TestNet4ChainParams =>
// if we can't find a non min difficulty block, let's just fail
throw new RuntimeException(
s"Could not find non mindifficulty block in chain of size=${blockchain.length}! hash=${tip.hashBE.hex} height=${currentHeight}"

View file

@ -257,6 +257,7 @@ object CLightningConfig
network match {
case MainNet => "bitcoin"
case TestNet3 => "testnet"
case TestNet4 => "testnet4"
case RegTest => "regtest"
case SigNet => "signet"
}

View file

@ -28,15 +28,6 @@ object CLightningInstanceLocal
override val DEFAULT_CONF_FILE: Path = DEFAULT_DATADIR.resolve("config")
private[clightning] def getNetworkDirName(network: BitcoinNetwork): String = {
network match {
case MainNet => ""
case TestNet3 => "testnet"
case SigNet => "signet"
case RegTest => "regtest"
}
}
override def fromConfigFile(
file: File = DEFAULT_CONF_FILE.toFile
)(implicit system: ActorSystem): CLightningInstanceLocal = {

View file

@ -1,6 +1,6 @@
package org.bitcoins.core.crypto
import org.bitcoins.core.config.{MainNet, RegTest, SigNet, TestNet3}
import org.bitcoins.core.config.{MainNet, RegTest, SigNet, TestNet3, TestNet4}
import org.bitcoins.crypto.{ECPrivateKey, ECPrivateKeyBytes}
import org.bitcoins.testkitcore.gen.{
ChainParamsGenerator,
@ -72,7 +72,7 @@ class WIFEncodingTest extends BitcoinSUnitTest {
network match {
case MainNet =>
assert(ECPrivateKeyUtil.parseNetworkFromWIF(wif).get == MainNet)
case TestNet3 | RegTest | SigNet =>
case TestNet3 | TestNet4 | RegTest | SigNet =>
assert(ECPrivateKeyUtil.parseNetworkFromWIF(wif).get == TestNet3)
}
assert(

View file

@ -173,6 +173,24 @@ sealed abstract class SigNet extends BitcoinNetwork {
}
case object SigNet extends SigNet
sealed abstract class TestNet4 extends BitcoinNetwork {
override def chainParams: BitcoinChainParams = TestNet4ChainParams
override def port: Int = 48333
override def rpcPort: Int = 48334
override def magicBytes: ByteVector = ByteVector(
0x1c,
0x16,
0x3f,
0x28
)
override def dnsSeeds: Seq[String] = Vector(
"seed.testnet4.bitcoin.sprovoost.nl",
"seed.testnet4.wiz.biz"
)
}
case object TestNet4 extends TestNet4
// $COVERAGE-ON$
object Networks extends StringFactory[NetworkParameters] {
@ -214,6 +232,7 @@ object BitcoinNetworks extends StringFactory[BitcoinNetwork] {
case "testnet3" => TestNet3
case "testnet" => TestNet3
case "test" => TestNet3
case "testnet4" => TestNet4
case "regtest" => RegTest
case "signet" => SigNet
case "sig" => SigNet

View file

@ -40,7 +40,7 @@ object HDCoinType {
def fromNetwork(np: NetworkParameters): HDCoinType = {
np match {
case MainNet => Bitcoin
case TestNet3 | RegTest | SigNet => Testnet
case TestNet3 | TestNet4 | RegTest | SigNet => Testnet
}
}

View file

@ -50,7 +50,7 @@ object BtcHumanReadablePart extends StringFactory[BtcHumanReadablePart] {
def apply(network: NetworkParameters): BtcHumanReadablePart =
network match {
case _: MainNet => bc
case _: TestNet3 => tb
case _: TestNet3 | _: TestNet4 => tb
case _: RegTest => bcrt
case _: SigNet => tb
}

View file

@ -2,8 +2,7 @@ package org.bitcoins.core.protocol.blockchain
import java.math.BigInteger
import java.nio.charset.StandardCharsets
import org.bitcoins.core.config._
import org.bitcoins.core.config.*
import org.bitcoins.core.consensus.Merkle
import org.bitcoins.core.currency.{Bitcoins, CurrencyUnit, Satoshis}
import org.bitcoins.core.number.{Int32, UInt32}
@ -12,12 +11,12 @@ import org.bitcoins.core.protocol.script.{
ScriptPubKey,
ScriptSignature
}
import org.bitcoins.core.protocol.transaction._
import org.bitcoins.core.protocol.transaction.*
import org.bitcoins.core.script.constant.{BytesToPushOntoStack, ScriptConstant}
import org.bitcoins.core.script.crypto.OP_CHECKSIG
import org.bitcoins.core.util.{BitcoinScriptUtil, NumberUtil}
import org.bitcoins.crypto.{DoubleSha256Digest, DoubleSha256DigestBE}
import scodec.bits.{ByteVector, _}
import scodec.bits.{ByteVector, *}
import scala.concurrent.duration.{Duration, DurationInt}
@ -345,7 +344,7 @@ object TestNetChainParams extends BitcoinChainParams {
Int32.one,
Satoshis(5000000000L))
override lazy val base58Prefixes: Map[Base58Type, ByteVector] =
override lazy val base58Prefixes: Map[Base58Type, ByteVector] = {
Map(
Base58Type.PubKeyAddress -> hex"6f",
Base58Type.ScriptAddress -> hex"c4",
@ -353,6 +352,7 @@ object TestNetChainParams extends BitcoinChainParams {
Base58Type.ExtPublicKey -> hex"043587cf",
Base58Type.ExtSecretKey -> hex"04358394"
)
}
/** Testnet pow limit
* [[https://github.com/bitcoin/bitcoin/blob/a083f75ba79d465f15fddba7b00ca02e31bb3d40/src/chainparams.cpp#L189 testnet pow limit]]
@ -505,6 +505,98 @@ case class SigNetChainParams(
override def signetBlocks: Boolean = true
}
object TestNet4ChainParams extends BitcoinChainParams {
/** The best chain should have this amount of work */
override val minimumChainWork: BigInteger = {
val bytes = ByteVector.fromValidHex(
"00000000000000000000000000000000000000000000005faa15d02e6202f3ba")
new BigInteger(1, bytes.toArray)
}
/** @inheritdoc
*/
override def network: BitcoinNetwork = TestNet4
/** Return the BIP70 network string (
* [[org.bitcoins.core.protocol.blockchain.MainNetChainParams MainNetChainParams]],
* [[org.bitcoins.core.protocol.blockchain.MainNetChainParams TestNetChainParams]]
* or
* [[org.bitcoins.core.protocol.blockchain.MainNetChainParams RegTestNetChainParams]].)
*
* @see
* [[https://github.com/bitcoin/bips/blob/master/bip-0070.mediawiki BIP70]]
*/
override def networkId: String = "testnet4"
/** The Genesis [[org.bitcoins.core.protocol.blockchain.Block Block]] in the
* blockchain.
*/
override val genesisBlock: Block = {
val asm = Seq(
BytesToPushOntoStack(33),
ScriptConstant(
"000000000000000000000000000000000000000000000000000000000000000000"),
OP_CHECKSIG
)
val spk = ScriptPubKey.fromAsm(asm)
createGenesisBlock(
timestamp =
"03/May/2024 000000000000000000001ebd58c244970b3aa9d783bb001011fbe8ea8e98e00e",
scriptPubKey = spk,
time = UInt32(1714777860),
nonce = UInt32(393743547),
nBits = UInt32.fromHex("1d00ffff"),
version = Int32.one,
amount = Bitcoins(50)
)
}
/** The mapping from a
* [[org.bitcoins.core.protocol.blockchain.Base58Type Base58Type]]to a
* String. Base58 prefixes for various keys/hashes on the network.
*
* @see
* Bitcoin wiki
* [[https://en.bitcoin.it/wiki/List_of_address_prefixes article]] on
* address prefixes
*/
override def base58Prefixes: Map[Base58Type, ByteVector] = {
TestNetChainParams.base58Prefixes
}
/** The minimum amount of proof of work required for a block
* [[https://github.com/bitcoin/bitcoin/blob/eb7daf4d600eeb631427c018a984a77a34aca66e/src/consensus/params.h#L70 bitcoin core pow limit]]
*
* @return
*/
override def powLimit: BigInteger = MainNetChainParams.powLimit
/** Whether we should allow minimum difficulty blocks or not As an example you
* can trivially mine blocks on [[RegTestNetChainParams]] and
* [[TestNetChainParams]] but not the [[MainNetChainParams]]
*
* @return
*/
override def allowMinDifficultyBlocks: Boolean = true
/** Whether this chain supports proof of work retargeting or not
*
* @see
* [[https://github.com/bitcoin/bitcoin/blob/eb7daf4d600eeb631427c018a984a77a34aca66e/src/consensus/params.h#L72 link]]
* @return
*/
override def noRetargeting: Boolean = false
/** Uses signet blocks that require checking the signet challenge */
override def signetBlocks: Boolean = false
/** Blocks must satisfy the given script to be considered valid (only for
* signet networks)
*/
override def signetChallenge: ScriptPubKey = EmptyScriptPubKey
}
sealed abstract class Base58Type
object Base58Type {

View file

@ -64,7 +64,7 @@ object LnParams {
def fromNetworkParameters(np: NetworkParameters): LnParams =
np match {
case MainNet => LnBitcoinMainNet
case TestNet3 => LnBitcoinTestNet
case TestNet3 | TestNet4 => LnBitcoinTestNet
case RegTest => LnBitcoinRegTest
case SigNet => LnBitcoinSigNet
}

View file

@ -15,18 +15,22 @@ object HDUtil {
(hdPurpose, network) match {
case (SegWit, MainNet) | (Taproot, MainNet) => SegWitMainNetPriv
case (SegWit, TestNet3 | RegTest | SigNet) => SegWitTestNet3Priv
case (Taproot, TestNet3 | RegTest | SigNet) => SegWitTestNet3Priv
case (SegWit, TestNet3 | RegTest | SigNet | TestNet4) =>
SegWitTestNet3Priv
case (Taproot, TestNet3 | RegTest | SigNet | TestNet4) =>
SegWitTestNet3Priv
case (NestedSegWit, MainNet) => NestedSegWitMainNetPriv
case (NestedSegWit, TestNet3 | RegTest | SigNet) =>
case (NestedSegWit, TestNet3 | RegTest | SigNet | TestNet4) =>
NestedSegWitTestNet3Priv
case (Multisig, MainNet) => LegacyMainNetPriv
case (Multisig, TestNet3 | RegTest | SigNet) =>
case (Multisig, TestNet3 | RegTest | SigNet | TestNet4) =>
LegacyTestNet3Priv
case (Legacy, MainNet) => LegacyMainNetPriv
case (Legacy, TestNet3 | RegTest | SigNet) => LegacyTestNet3Priv
case (Legacy, TestNet3 | RegTest | SigNet | TestNet4) =>
LegacyTestNet3Priv
case (HDPurpose(585), MainNet) => SegWitMainNetPriv
case (HDPurpose(585), TestNet3 | RegTest | SigNet) => SegWitTestNet3Priv
case (HDPurpose(585), TestNet3 | RegTest | SigNet | TestNet4) =>
SegWitTestNet3Priv
case (unknown: HDPurpose, _) =>
throw new IllegalArgumentException(s"Got unknown HD purpose $unknown")
}
@ -40,16 +44,16 @@ object HDUtil {
(hdPurpose, network) match {
case (SegWit, MainNet | SigNet) => ExtKeyPubVersion.SegWitMainNetPub
case (SegWit, TestNet3 | RegTest | SigNet) =>
case (SegWit, TestNet3 | RegTest | SigNet | TestNet4) =>
ExtKeyPubVersion.SegWitTestNet3Pub
case (NestedSegWit, MainNet) => ExtKeyPubVersion.NestedSegWitMainNetPub
case (NestedSegWit, TestNet3 | RegTest | SigNet) =>
case (NestedSegWit, TestNet3 | RegTest | SigNet | TestNet4) =>
ExtKeyPubVersion.NestedSegWitTestNet3Pub
case (Multisig, MainNet) => ExtKeyPubVersion.LegacyMainNetPub
case (Multisig, TestNet3 | RegTest | SigNet) =>
case (Multisig, TestNet3 | RegTest | SigNet | TestNet4) =>
ExtKeyPubVersion.LegacyTestNet3Pub
case (Legacy, MainNet) => ExtKeyPubVersion.LegacyMainNetPub
case (Legacy, TestNet3 | RegTest | SigNet) =>
case (Legacy, TestNet3 | RegTest | SigNet | TestNet4) =>
ExtKeyPubVersion.LegacyTestNet3Pub
case (unknown: HDPurpose, _) =>
throw new IllegalArgumentException(s"Got unknown HD purpose $unknown")

View file

@ -77,6 +77,7 @@ case class DLCOracleAppConfig(
val lastDirname = network match {
case MainNet => "mainnet"
case TestNet3 => "testnet3"
case TestNet4 => "testnet4"
case RegTest => "regtest"
case SigNet => "signet"
}

View file

@ -12,7 +12,7 @@ case class BlockstreamEsploraSite(network: BitcoinNetwork) extends EsploraSite {
override val url: String = network match {
case MainNet => "https://blockstream.info/api"
case TestNet3 => "https://blockstream.info/testnet/api"
case net @ (RegTest | SigNet) =>
case net @ (RegTest | SigNet | TestNet4) =>
sys.error(s"Blockstream.info does not support $net")
}
@ -27,7 +27,7 @@ case class BlockstreamTorEsploraSite(network: BitcoinNetwork)
"http://explorerzydxu5ecjrkwceayqybizmpjjznk5izmitf2modhcusuqlid.onion/api"
case TestNet3 =>
"http://explorerzydxu5ecjrkwceayqybizmpjjznk5izmitf2modhcusuqlid.onion/testnet/api"
case net @ (RegTest | SigNet) =>
case net @ (RegTest | TestNet4 | SigNet) =>
sys.error(s"Blockstream.info does not support $net")
}
@ -40,6 +40,7 @@ case class MempoolSpaceEsploraSite(network: BitcoinNetwork)
override val url: String = network match {
case MainNet => "https://mempool.space/api"
case TestNet3 => "https://mempool.space/testnet/api"
case TestNet4 => "https://mempool.space/testnet4/api/"
case SigNet => "https://mempool.space/signet/api"
case RegTest =>
sys.error(s"Mempool.space cannot be used for RegTest")
@ -56,6 +57,8 @@ case class MempoolSpaceTorEsploraSite(network: BitcoinNetwork)
"http://mempoolhqx4isw62xs7abwphsq7ldayuidyx2v2oethdhhj6mlo2r6ad.onion/api"
case TestNet3 =>
"http://mempoolhqx4isw62xs7abwphsq7ldayuidyx2v2oethdhhj6mlo2r6ad.onion/testnet/api"
case TestNet4 =>
"http://mempoolhqx4isw62xs7abwphsq7ldayuidyx2v2oethdhhj6mlo2r6ad.onion/testnet4/api"
case SigNet =>
"http://mempoolhqx4isw62xs7abwphsq7ldayuidyx2v2oethdhhj6mlo2r6ad.onion/signet/api"
case RegTest =>

View file

@ -27,6 +27,8 @@ case class MempoolSpaceProvider(
Uri("https://mempool.space/api/v1/fees/recommended")
case TestNet3 =>
Uri("https://mempool.space/testnet/api/v1/fees/recommended")
case TestNet4 =>
Uri("https://mempool.space/testnet4/api/v1/fees/recommended")
case SigNet =>
Uri("https://mempool.space/signet/api/v1/fees/recommended")
case RegTest =>

View file

@ -73,6 +73,7 @@ object LndInstanceLocal
network match {
case _: MainNet => "mainnet"
case _: TestNet3 => "testnet"
case _: TestNet4 => "testnet4"
case _: RegTest => "regtest"
case _: SigNet => "signet"
}

View file

@ -5,7 +5,7 @@ import org.apache.pekko.stream.scaladsl.SourceQueue
import org.bitcoins.asyncutil.AsyncUtil
import org.bitcoins.chain.config.ChainAppConfig
import org.bitcoins.core.api.node.{Peer, PeerManagerApi}
import org.bitcoins.core.config.{MainNet, RegTest, SigNet, TestNet3}
import org.bitcoins.core.config.{MainNet, RegTest, SigNet, TestNet3, TestNet4}
import org.bitcoins.core.p2p.{ServiceIdentifier, VersionMessage}
import org.bitcoins.core.util.StartStopAsync
import org.bitcoins.node.config.NodeAppConfig
@ -82,7 +82,7 @@ case class PeerFinder(
.filter(nodeAppConfig.torConf.enabled || !_.contains(".onion"))
val peers = BitcoinSNodeUtil.stringsToPeers(addresses)
Random.shuffle(peers)
case TestNet3 | RegTest | SigNet =>
case TestNet3 | RegTest | SigNet | TestNet4 =>
Vector.empty
}

View file

@ -15,6 +15,7 @@ import org.bitcoins.core.protocol.blockchain.{
MainNetChainParams,
RegTestNetChainParams,
SigNetChainParams,
TestNet4ChainParams,
TestNetChainParams
}
import org.bitcoins.core.protocol.script.ScriptPubKey
@ -522,7 +523,8 @@ case class AccountHandling(
protected[wallet] lazy val DEFAULT_HD_COIN_TYPE: HDCoinType = {
chainParams match {
case MainNetChainParams => HDCoinType.Bitcoin
case RegTestNetChainParams | TestNetChainParams | SigNetChainParams(_) =>
case RegTestNetChainParams | TestNetChainParams | TestNet4ChainParams |
SigNetChainParams(_) =>
HDCoinType.Testnet
}