Commit 55c66483 authored by Sergei Zubov's avatar Sergei Zubov

Merge network registration

parent 4dde29ea
using NBitcoin.DataEncoders;
using NBitcoin.Networks;
namespace NBitcoin
{
public partial class Network
{
/// <summary>
/// The name of the root folder containing the different Stratis blockchains (StratisMain, StratisTest,
/// StratisRegTest).
/// </summary>
protected const string DeStreamRootFolderName = "destream";
/// <summary> The default name used for the Stratis configuration file. </summary>
protected const string DeStreamDefaultConfigFilename = "destream.conf";
protected const int DeStreamMaxTimeOffsetSeconds = 25 * 60;
protected const int DeStreamDefaultMaxTipAgeInSeconds = 2 * 60 * 60;
public const string WalletAddressDeStreamMain = "TPPL2wmtxGzP8U6hQsGkRA9yCMsazB33ft";
public static Network DeStreamMain => NetworksContainer.GetNetwork("DeStreamMain") ??
NetworksContainer.Register(new DeStreamMain());
public static Network DeStreamTest => NetworksContainer.GetNetwork("DeStreamTest") ??
NetworksContainer.Register(new DeStreamTest());
public static Network DeStreamRegTest => NetworksContainer.GetNetwork("DeStreamRegTest") ??
NetworksContainer.Register(new DeStreamRegTest());
internal static Block CreateStratisGenesisBlock(ConsensusFactory consensusFactory, uint nTime, uint nNonce,
uint nBits, int nVersion, Money genesisReward)
{
string pszTimestamp =
"http://www.theonion.com/article/olympics-head-priestess-slits-throat-official-rio--53466";
return CreateStratisGenesisBlock(consensusFactory, pszTimestamp, nTime, nNonce, nBits, nVersion,
genesisReward);
}
private static Block CreateStratisGenesisBlock(ConsensusFactory consensusFactory, string pszTimestamp,
uint nTime, uint nNonce, uint nBits, int nVersion, Money genesisReward)
{
Transaction txNew = consensusFactory.CreateTransaction();
txNew.Version = 1;
txNew.Time = nTime;
txNew.AddInput(new TxIn
{
ScriptSig = new Script(Op.GetPushOp(0), new Op
{
Code = (OpcodeType) 0x1,
PushData = new[] {(byte) 42}
}, Op.GetPushOp(Encoders.ASCII.DecodeData(pszTimestamp)))
});
txNew.AddOutput(new TxOut
{
Value = genesisReward
});
Block genesis = consensusFactory.CreateBlock();
genesis.Header.BlockTime = Utils.UnixTimeToDateTime(nTime);
genesis.Header.Bits = nBits;
genesis.Header.Nonce = nNonce;
genesis.Header.Version = nVersion;
genesis.Transactions.Add(txNew);
genesis.Header.HashPrevBlock = uint256.Zero;
genesis.UpdateMerkleRoot();
return genesis;
}
}
}
\ No newline at end of file
using System;
using System.Collections.Generic;
using NBitcoin.DataEncoders;
namespace NBitcoin
{
public abstract class DeStreamNetwork : Network
{
/// <summary>
/// The name of the root folder containing the different Stratis blockchains (StratisMain, StratisTest,
/// StratisRegTest).
/// </summary>
protected const string DeStreamRootFolderName = "destream";
/// <summary> The default name used for the Stratis configuration file. </summary>
protected const string DeStreamDefaultConfigFilename = "destream.conf";
protected const int DeStreamMaxTimeOffsetSeconds = 25 * 60;
protected const int DeStreamDefaultMaxTipAgeInSeconds = 2 * 60 * 60;
protected LinkedList<string> DeStreamWallets;
public string GenesisWalletAddress { get; protected set; }
private LinkedListNode<string> DeStreamWalletsNode { get; set; }
public string DeStreamWallet
{
get
{
DeStreamWalletsNode = DeStreamWalletsNode.NextOrFirst() ?? DeStreamWallets.First;
return DeStreamWalletsNode.Value;
}
}
/// <summary>
/// </summary>
public double DeStreamFeePart { get; set; }
/// <summary>
/// Fee applied to all transactions
/// </summary>
public double FeeRate { get; set; }
/// <summary>
/// Splits fee between miner and DeStream
/// </summary>
/// <param name="fee">Total amount of fees to be split</param>
/// <param name="deStreamFee">DeStream fee part</param>
/// <param name="minerReward">Miner fee part</param>
public void SplitFee(long fee, out long deStreamFee, out long minerReward)
{
deStreamFee = Convert.ToInt64(fee * DeStreamFeePart);
minerReward = fee - deStreamFee;
}
/// <summary>
/// Subtracts fee from sum of fees and transfer funds
/// </summary>
/// <param name="value">Sum of fees and transfer funds</param>
/// <returns>Transfer funds without fees</returns>
public Money SubtractFee(Money value)
{
return Convert.ToInt64(value.Satoshi / (1.0 + FeeRate));
}
public bool IsDeStreamAddress(string address)
{
return DeStreamWallets.Contains(address);
}
}
}
\ No newline at end of file
using System;
using System.Collections.Generic;
using System.Text;
using NBitcoin.BouncyCastle.Math;
using NBitcoin.DataEncoders;
namespace NBitcoin.Networks
{
public class DeStreamRegTest : Network
{
public DeStreamRegTest()
{
// TODO: move this to Networks
var messageStart = new byte[4];
messageStart[0] = 0xcd;
messageStart[1] = 0xf2;
messageStart[2] = 0xc0;
messageStart[3] = 0xef;
var magic = BitConverter.ToUInt32(messageStart, 0); // 0xefc0f2cd
this.Name = "DeStreamRegTest";
this.RootFolderName = DeStreamRootFolderName;
this.DefaultConfigFilename = DeStreamDefaultConfigFilename;
this.Magic = magic;
this.DefaultPort = 18444;
this.RPCPort = 18442;
this.MaxTimeOffsetSeconds = DeStreamMaxTimeOffsetSeconds;
this.MaxTipAge = DeStreamDefaultMaxTipAgeInSeconds;
this.Consensus.SubsidyHalvingInterval = 210000;
this.Consensus.MajorityEnforceBlockUpgrade = 750;
this.Consensus.MajorityRejectBlockOutdated = 950;
this.Consensus.MajorityWindow = 1000;
this.Consensus.BuriedDeployments[BuriedDeployments.BIP34] = 0;
this.Consensus.BuriedDeployments[BuriedDeployments.BIP65] = 0;
this.Consensus.BuriedDeployments[BuriedDeployments.BIP66] = 0;
this.Consensus.BIP34Hash = new uint256("0x000000000000024b89b42a942fe0d9fea3bb44ab7bd1b19115dd6a759c0808b8");
this.Consensus.PowLimit = new Target(uint256.Parse("7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"));
this.Consensus.PowTargetTimespan = TimeSpan.FromSeconds(14 * 24 * 60 * 60); // two weeks
this.Consensus.PowTargetSpacing = TimeSpan.FromSeconds(10 * 60);
this.Consensus.PowAllowMinDifficultyBlocks = true;
this.Consensus.PowNoRetargeting = true;
this.Consensus.RuleChangeActivationThreshold = 1916; // 95% of 2016
this.Consensus.MinerConfirmationWindow = 2016; // nPowTargetTimespan / nPowTargetSpacing
this.Consensus.LastPOWBlock = 12500;
this.Consensus.IsProofOfStake = true;
this.Consensus.ConsensusFactory = new PosConsensusFactory() { Consensus = this.Consensus };
this.Consensus.ProofOfStakeLimit = new BigInteger(uint256.Parse("00000fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff").ToBytes(false));
this.Consensus.ProofOfStakeLimitV2 = new BigInteger(uint256.Parse("000000000000ffffffffffffffffffffffffffffffffffffffffffffffffffff").ToBytes(false));
this.Consensus.CoinType = 105;
this.Consensus.DefaultAssumeValid = null; // turn off assumevalid for regtest.
Block genesis = CreateStratisGenesisBlock(this.Consensus.ConsensusFactory, 1470467000, 1831645, 0x1e0fffff, 1, Money.Zero);
genesis.Header.Time = 1494909211;
genesis.Header.Nonce = 2433759;
genesis.Header.Bits = this.Consensus.PowLimit;
this.Genesis = genesis;
this.Consensus.HashGenesisBlock = genesis.GetHash();
Assert(this.Consensus.HashGenesisBlock == uint256.Parse("0x93925104d664314f581bc7ecb7b4bad07bcfabd1cfce4256dbd2faddcf53bd1f"));
this.Base58Prefixes[(int)Base58Type.PUBKEY_ADDRESS] = new byte[] { (65) };
this.Base58Prefixes[(int)Base58Type.SCRIPT_ADDRESS] = new byte[] { (196) };
this.Base58Prefixes[(int)Base58Type.SECRET_KEY] = new byte[] { (65 + 128) };
this.Base58Prefixes[(int)Base58Type.ENCRYPTED_SECRET_KEY_NO_EC] = new byte[] { 0x01, 0x42 };
this.Base58Prefixes[(int)Base58Type.ENCRYPTED_SECRET_KEY_EC] = new byte[] { 0x01, 0x43 };
this.Base58Prefixes[(int)Base58Type.EXT_PUBLIC_KEY] = new byte[] { (0x04), (0x88), (0xB2), (0x1E) };
this.Base58Prefixes[(int)Base58Type.EXT_SECRET_KEY] = new byte[] { (0x04), (0x88), (0xAD), (0xE4) };
this.Base58Prefixes[(int)Base58Type.PASSPHRASE_CODE] = new byte[] { 0x2C, 0xE9, 0xB3, 0xE1, 0xFF, 0x39, 0xE2 };
this.Base58Prefixes[(int)Base58Type.CONFIRMATION_CODE] = new byte[] { 0x64, 0x3B, 0xF6, 0xA8, 0x9A };
this.Base58Prefixes[(int)Base58Type.STEALTH_ADDRESS] = new byte[] { 0x2a };
this.Base58Prefixes[(int)Base58Type.ASSET_ID] = new byte[] { 23 };
this.Base58Prefixes[(int)Base58Type.COLORED_ADDRESS] = new byte[] { 0x13 };
var encoder = new Bech32Encoder("bc");
this.Bech32Encoders[(int)Bech32Type.WITNESS_PUBKEY_ADDRESS] = encoder;
this.Bech32Encoders[(int)Bech32Type.WITNESS_SCRIPT_ADDRESS] = encoder;
}
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using NBitcoin;
using NBitcoin.BouncyCastle.Math;
using NBitcoin.DataEncoders;
namespace NBitcoin
namespace Stratis.Bitcoin.Networks
{
public abstract partial class Network
{
protected LinkedList<string> DeStreamWallets;
private LinkedListNode<string> DeStreamWalletsNode { get; set; }
public string DeStreamWallet
{
get
{
this.DeStreamWalletsNode = this.DeStreamWalletsNode.NextOrFirst() ?? this.DeStreamWallets.First;
return this.DeStreamWalletsNode.Value;
}
}
/// <summary>
/// </summary>
public double DeStreamFeePart { get; set; }
/// <summary>
/// Fee applied to all transactions
/// </summary>
public double FeeRate { get; set; }
/// <summary>
/// Splits fee between miner and DeStream
/// </summary>
/// <param name="fee">Total amount of fees to be split</param>
/// <param name="deStreamFee">DeStream fee part</param>
/// <param name="minerReward">Miner fee part</param>
public void SplitFee(long fee, out long deStreamFee, out long minerReward)
{
deStreamFee = Convert.ToInt64(fee * this.DeStreamFeePart);
minerReward = fee - deStreamFee;
}
/// <summary>
/// Subtracts fee from sum of fees and transfer funds
/// </summary>
/// <param name="value">Sum of fees and transfer funds</param>
/// <returns>Transfer funds without fees</returns>
public Money SubtractFee(Money value)
{
return Convert.ToInt64(value.Satoshi / (1.0 + this.FeeRate));
}
public bool IsDeStreamAddress(string address)
{
return this.DeStreamWallets.Contains(address);
}
}
}
namespace NBitcoin.Networks
{
public class DeStreamMain : Network
public class DeStreamMain : DeStreamNetwork
{
public DeStreamMain()
{
var initialWalletAddresses = new[]
{
"DEaps8sntaCASk67ywscPkiLwrNQAD4e1b",
"DE1iWo2MSsEs2HjL813fSiNdELtFnyw1by",
"DEkf7nGEvjw2CyNCoTvzsNxsRn6ZVFGZkS",
"DEzX6oHMZVUD1qonkTSZFFjajGozsETwgs",
"DEcHCoeTRHKgGBwCzzdNvEegVW7Gp1VDK8",
"DEwTvJbTh8qrWtes3VYw14GnNNNV4P312b",
"DECAapLcscqNCU2ufDRbCFRMVkZyQLhL3w",
"DEBEVqQxXo3cFbk1on35tFjsDE5yHvGzy8",
"DEEPLTkkN4rCShkqez6cCdSYB54CU6A74z",
"DEK92CU1qa7TtPd6JdRqf2tNzxixZYDtB3"
};
const decimal initialCoins = 6000000000;
this.DeStreamWallets = new LinkedList<string>(new[]
{
"DEdt7fEuAYQSbtE7ypsJJD7vC6HtZDeriP",
"DErzhYkCcXKKDEWLiWTgSBjmHKKnd2KL15",
"DEa4NHRZyU4PZSKLTdcagxJU8KT6ASAguh",
"DE5h7hdQbvCuhdfVNQWVN42T3MZEP8NHZm",
"DE5HrG9YaoLUHC1hb3jfrZphfcERiHJYjj",
"DEzeEUeNt2fDM6Xe3C8crbtiB2ZHtp7SYR",
"DET5PmzTvLW8bnm6ugmNWjPvnaWLV5dHnL",
"DEfwS3ojmhKtYCNpKyP64GiMTUb6gUBAa9",
"DEf6Ewa9y3598FdY7D7xMBGwdVvXTvuAPm",
"DEHgpa9iXfamEcQxLSUiQQATiRJPHNz2pb"
}.OrderBy(p => Guid.NewGuid()));
// The message start string is designed to be unlikely to occur in normal data.
// The characters are rarely used upper ASCII, not valid as UTF-8, and produce
// a large 4-byte int at any alignment.
var messageStart = new byte[4];
messageStart[0] = 0x10;
messageStart[1] = 0xFE;
......@@ -102,63 +22,106 @@ namespace NBitcoin.Networks
uint magic = BitConverter.ToUInt32(messageStart, 0);
this.Name = "DeStreamMain";
this.RootFolderName = DeStreamRootFolderName;
this.DefaultConfigFilename = DeStreamDefaultConfigFilename;
this.Magic = magic;
this.DefaultPort = 0xDE01; // 56833,
this.RPCPort = 0xDE00; // 56832,
this.DefaultPort = 56833;
this.DefaultMaxOutboundConnections = 16;
this.DefaultMaxInboundConnections = 109;
this.RPCPort = 56832;
this.MaxTipAge = DeStreamDefaultMaxTipAgeInSeconds;
this.MinTxFee = 10000;
this.FallbackFee = 60000;
this.MinRelayTxFee = 10000;
this.RootFolderName = DeStreamRootFolderName;
this.DefaultConfigFilename = DeStreamDefaultConfigFilename;
this.MaxTimeOffsetSeconds = DeStreamMaxTimeOffsetSeconds;
this.MaxTipAge = DeStreamDefaultMaxTipAgeInSeconds;
this.CoinTicker = "DST";
this.Consensus.SubsidyHalvingInterval = 210000;
this.Consensus.MajorityEnforceBlockUpgrade = 750;
this.Consensus.MajorityRejectBlockOutdated = 950;
this.Consensus.MajorityWindow = 1000;
this.Consensus.BuriedDeployments[BuriedDeployments.BIP34] = 0;
this.Consensus.BuriedDeployments[BuriedDeployments.BIP65] = 0;
this.Consensus.BuriedDeployments[BuriedDeployments.BIP66] = 0;
this.Consensus.BIP34Hash =
new uint256("0x000000000000024b89b42a942fe0d9fea3bb44ab7bd1b19115dd6a759c0808b8");
this.Consensus.PowLimit =
new Target(new uint256("00000fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"));
this.Consensus.PowTargetTimespan = TimeSpan.FromSeconds(14 * 24 * 60 * 60); // two weeks
this.Consensus.PowTargetSpacing = TimeSpan.FromSeconds(10 * 60);
this.Consensus.PowAllowMinDifficultyBlocks = false;
this.Consensus.PowNoRetargeting = false;
this.Consensus.RuleChangeActivationThreshold = 1916; // 95% of 2016
this.Consensus.MinerConfirmationWindow = 2016; // nPowTargetTimespan / nPowTargetSpacing
this.Consensus.LastPOWBlock = 1000;
this.Consensus.IsProofOfStake = true;
this.Consensus.ConsensusFactory = new PosConsensusFactory {Consensus = this.Consensus};
this.Consensus.ProofOfStakeLimit = new BigInteger(uint256
.Parse("00000fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff").ToBytes(false));
this.Consensus.ProofOfStakeLimitV2 = new BigInteger(uint256
.Parse("000000000000ffffffffffffffffffffffffffffffffffffffffffffffffffff").ToBytes(false));
this.Consensus.CoinType = 3564;
this.Consensus.DefaultAssumeValid =
new uint256("0x55a8205ae4bbf18f4d238c43f43005bd66e0b1f679b39e2c5c62cf6903693a5e"); // 795970
this.Consensus.MaxMoney = long.MaxValue;
this.Consensus.ProofOfWorkReward = Money.Zero;
this.Consensus.ProofOfStakeReward = Money.Zero;
this.Consensus.CoinbaseMaturity = 50;
this.Consensus.MaxReorgLength = 500;
this.DeStreamFeePart = 0.9;
this.FeeRate = 0.0077;
this.Checkpoints = new Dictionary<int, CheckpointInfo>
var consensusFactory = new PosConsensusFactory();
// Create the genesis block.
var initialWalletAddresses = new[]
{
{
0, new CheckpointInfo(
new uint256("0x95dfb30e229e18197a812ece5d8d6c03efc9b9b65a9122a73f17d99613841b1b"),
new uint256("0x0000000000000000000000000000000000000000000000000000000000000000"))
}
"DEaps8sntaCASk67ywscPkiLwrNQAD4e1b",
"DE1iWo2MSsEs2HjL813fSiNdELtFnyw1by",
"DEkf7nGEvjw2CyNCoTvzsNxsRn6ZVFGZkS",
"DEzX6oHMZVUD1qonkTSZFFjajGozsETwgs",
"DEcHCoeTRHKgGBwCzzdNvEegVW7Gp1VDK8",
"DEwTvJbTh8qrWtes3VYw14GnNNNV4P312b",
"DECAapLcscqNCU2ufDRbCFRMVkZyQLhL3w",
"DEBEVqQxXo3cFbk1on35tFjsDE5yHvGzy8",
"DEEPLTkkN4rCShkqez6cCdSYB54CU6A74z",
"DEK92CU1qa7TtPd6JdRqf2tNzxixZYDtB3"
};
const decimal initialCoins = 6000000000;
this.GenesisTime = (uint) new DateTimeOffset(2018, 10, 27, 0, 0, 0, new TimeSpan()).ToUnixTimeSeconds();
this.GenesisNonce = 1831645;
this.GenesisBits = 0x1e0fffff;
this.GenesisVersion = 1;
this.GenesisReward = Money.Coins(initialCoins);
this.GenesisWalletAddress = initialWalletAddresses.First();
var genesisBlock = this.CreateDeStreamGenesisBlock(this.Consensus.ConsensusFactory, this.GenesisTime,
this.GenesisNonce, this.GenesisBits, this.GenesisVersion, this.GenesisReward,
initialWalletAddresses);
this.Genesis = genesisBlock;
// Taken from StratisX.
var consensusOptions = new PosConsensusOptions(
maxBlockBaseSize: 1_000_000,
maxStandardVersion: 2,
maxStandardTxWeight: 100_000,
maxBlockSigopsCost: 20_000,
maxStandardTxSigopsCost: 20_000 / 5
);
var buriedDeployments = new BuriedDeploymentsArray
{
[BuriedDeployments.BIP34] = 0,
[BuriedDeployments.BIP65] = 0,
[BuriedDeployments.BIP66] = 0
};
//TODO: BIP9
this.Consensus = new NBitcoin.Consensus(
consensusFactory: consensusFactory,
consensusOptions: consensusOptions,
coinType: 3564,
hashGenesisBlock: genesisBlock.GetHash(),
subsidyHalvingInterval: 210000,
majorityEnforceBlockUpgrade: 750,
majorityRejectBlockOutdated: 950,
majorityWindow: 1000,
buriedDeployments: buriedDeployments,
bip9Deployments: null, //TODO: BIP9
bip34Hash: new uint256("0x000000000000024b89b42a942fe0d9fea3bb44ab7bd1b19115dd6a759c0808b8"),
ruleChangeActivationThreshold: 1916, // 95% of 2016
minerConfirmationWindow: 2016, // nPowTargetTimespan / nPowTargetSpacing
maxReorgLength: 500,
defaultAssumeValid: new uint256("0x55a8205ae4bbf18f4d238c43f43005bd66e0b1f679b39e2c5c62cf6903693a5e"), // 795970
maxMoney: long.MaxValue,
coinbaseMaturity: 50,
premineHeight: 0,
premineReward: Money.Zero,
proofOfWorkReward: Money.Zero,
powTargetTimespan: TimeSpan.FromSeconds(14 * 24 * 60 * 60), // two weeks
powTargetSpacing: TimeSpan.FromSeconds(10 * 60),
powAllowMinDifficultyBlocks: false,
powNoRetargeting: false,
powLimit: new Target(new uint256("00000fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff")),
minimumChainWork: null,
isProofOfStake: true,
lastPowBlock: 1000,
proofOfStakeLimit: new BigInteger(uint256.Parse("00000fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff").ToBytes(false)),
proofOfStakeLimitV2: new BigInteger(uint256.Parse("000000000000ffffffffffffffffffffffffffffffffffffffffffffffffffff").ToBytes(false)),
proofOfStakeReward: Money.Zero
);
this.Base58Prefixes = new byte[12][];
this.Base58Prefixes[(int) Base58Type.PUBKEY_ADDRESS] = new byte[] {30};
this.Base58Prefixes[(int) Base58Type.SCRIPT_ADDRESS] = new byte[] {90};
......@@ -174,6 +137,16 @@ namespace NBitcoin.Networks
this.Base58Prefixes[(int) Base58Type.ASSET_ID] = new byte[] {23};
this.Base58Prefixes[(int) Base58Type.COLORED_ADDRESS] = new byte[] {0x13};
this.Checkpoints = new Dictionary<int, CheckpointInfo>
{
{
// TODO: fix checkpoints
0, new CheckpointInfo(
new uint256("0x95dfb30e229e18197a812ece5d8d6c03efc9b9b65a9122a73f17d99613841b1b"),
new uint256("0x0000000000000000000000000000000000000000000000000000000000000000"))
}
};
var encoder = new Bech32Encoder("bc");
this.Bech32Encoders = new Bech32Encoder[2];
this.Bech32Encoders[(int) Bech32Type.WITNESS_PUBKEY_ADDRESS] = encoder;
......@@ -188,19 +161,22 @@ namespace NBitcoin.Networks
string[] seedNodes = {"13.68.198.162", "13.70.18.104"};
this.SeedNodes = this.ConvertToNetworkAddresses(seedNodes, this.DefaultPort).ToList();
// Create the genesis block.
this.GenesisTime = (uint) new DateTimeOffset(2018, 10, 27, 0, 0, 0, new TimeSpan()).ToUnixTimeSeconds();
this.GenesisNonce = 1831645;
this.GenesisBits = 0x1e0fffff;
this.GenesisVersion = 1;
this.GenesisReward = Money.Coins(initialCoins);
this.GenesisWalletAddress = initialWalletAddresses.First();
this.Genesis = this.CreateDeStreamGenesisBlock(this.Consensus.ConsensusFactory, this.GenesisTime,
this.GenesisNonce, this.GenesisBits, this.GenesisVersion, this.GenesisReward,
initialWalletAddresses);
this.Consensus.HashGenesisBlock = this.Genesis.GetHash();
this.DeStreamWallets = new LinkedList<string>(new[]
{
"DEdt7fEuAYQSbtE7ypsJJD7vC6HtZDeriP",
"DErzhYkCcXKKDEWLiWTgSBjmHKKnd2KL15",
"DEa4NHRZyU4PZSKLTdcagxJU8KT6ASAguh",
"DE5h7hdQbvCuhdfVNQWVN42T3MZEP8NHZm",
"DE5HrG9YaoLUHC1hb3jfrZphfcERiHJYjj",
"DEzeEUeNt2fDM6Xe3C8crbtiB2ZHtp7SYR",
"DET5PmzTvLW8bnm6ugmNWjPvnaWLV5dHnL",
"DEfwS3ojmhKtYCNpKyP64GiMTUb6gUBAa9",
"DEf6Ewa9y3598FdY7D7xMBGwdVvXTvuAPm",
"DEHgpa9iXfamEcQxLSUiQQATiRJPHNz2pb"
}.OrderBy(p => Guid.NewGuid()));
Assert(this.Consensus.HashGenesisBlock ==
uint256.Parse("95dfb30e229e18197a812ece5d8d6c03efc9b9b65a9122a73f17d99613841b1b"));
Assert(this.Genesis.Header.HashMerkleRoot ==
......
using System;
using System.Collections.Generic;
using System.Linq;
using NBitcoin;
using NBitcoin.BouncyCastle.Math;
using NBitcoin.DataEncoders;
using NBitcoin.Protocol;
namespace NBitcoin.Networks
namespace Stratis.Bitcoin.Networks
{
public class DeStreamTest : DeStreamMain
public class DeStreamTest : DeStreamNetwork
{
public DeStreamTest() //: base()
{
public DeStreamTest()
{// The message start string is designed to be unlikely to occur in normal data.
// The characters are rarely used upper ASCII, not valid as UTF-8, and produce
// a large 4-byte int at any alignment.
var messageStart = new byte[4];
messageStart[0] = 0xFD;
messageStart[1] = 0xFC;
messageStart[2] = 0xFC;
messageStart[3] = 0xFD;
uint magic = BitConverter.ToUInt32(messageStart, 0);
this.Name = "DeStreamTest";
this.Magic = magic;
this.DefaultPort = 56849;
this.DefaultMaxOutboundConnections = 16;
this.DefaultMaxInboundConnections = 109;
this.RPCPort = 56848;
this.MaxTipAge = DeStreamDefaultMaxTipAgeInSeconds;
this.MinTxFee = 10000;
this.FallbackFee = 60000;
this.MinRelayTxFee = 10000;
this.RootFolderName = DeStreamRootFolderName;
this.DefaultConfigFilename = DeStreamDefaultConfigFilename;
this.MaxTimeOffsetSeconds = DeStreamMaxTimeOffsetSeconds;
this.CoinTicker = "TDST";
this.DeStreamFeePart = 0.9;
this.FeeRate = 0.0077;
var consensusFactory = new PosConsensusFactory();
// Create the genesis block.
var initialWalletAddresses = new[]
{
"TrpCjf3qT6QXckyXqF8nT1rCQzD2g8S6ES",
......@@ -33,6 +66,103 @@ namespace NBitcoin.Networks
"TgnFxUtqFsMXRm5kksd6o59njSCu67QeNi"
};
const decimal initialCoins = 6000000000;
this.GenesisTime = 1470467000;
this.GenesisNonce = 1831645;
this.GenesisBits = 0x1e0fffff;
this.GenesisVersion = 1;
this.GenesisReward = Money.Coins(initialCoins);
this.GenesisWalletAddress = initialWalletAddresses.First();
var genesisBlock = this.CreateDeStreamGenesisBlock(this.Consensus.ConsensusFactory, this.GenesisTime,
this.GenesisNonce, this.GenesisBits, this.GenesisVersion, this.GenesisReward,
initialWalletAddresses);
this.Genesis = genesisBlock;
// Taken from StratisX.
var consensusOptions = new PosConsensusOptions(
maxBlockBaseSize: 1_000_000,
maxStandardVersion: 2,
maxStandardTxWeight: 100_000,
maxBlockSigopsCost: 20_000,
maxStandardTxSigopsCost: 20_000 / 5
);
var buriedDeployments = new BuriedDeploymentsArray
{
[BuriedDeployments.BIP34] = 0,
[BuriedDeployments.BIP65] = 0,
[BuriedDeployments.BIP66] = 0
};
//TODO: BIP9
this.Consensus = new NBitcoin.Consensus(
consensusFactory: consensusFactory,
consensusOptions: consensusOptions,
coinType: 1,
hashGenesisBlock: genesisBlock.GetHash(),
subsidyHalvingInterval: 210000,
majorityEnforceBlockUpgrade: 750,
majorityRejectBlockOutdated: 950,
majorityWindow: 1000,
buriedDeployments: buriedDeployments,
bip9Deployments: null, //TODO: BIP9
bip34Hash: new uint256("0x000000000000024b89b42a942fe0d9fea3bb44ab7bd1b19115dd6a759c0808b8"),
ruleChangeActivationThreshold: 1916, // 95% of 2016
minerConfirmationWindow: 2016, // nPowTargetTimespan / nPowTargetSpacing
maxReorgLength: 500,
defaultAssumeValid: new uint256("0x55a8205ae4bbf18f4d238c43f43005bd66e0b1f679b39e2c5c62cf6903693a5e"), // 795970
maxMoney: long.MaxValue,
coinbaseMaturity: 10,
premineHeight: 0,
premineReward: Money.Zero,
proofOfWorkReward: Money.Zero,
powTargetTimespan: TimeSpan.FromSeconds(14 * 24 * 60 * 60), // two weeks
powTargetSpacing: TimeSpan.FromSeconds(10 * 60),
powAllowMinDifficultyBlocks: false,
powNoRetargeting: false,
powLimit: new Target(new uint256("00000fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff")),
minimumChainWork: null,
isProofOfStake: true,
lastPowBlock: 12500,
proofOfStakeLimit: new BigInteger(uint256.Parse("00000fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff").ToBytes(false)),
proofOfStakeLimitV2: new BigInteger(uint256.Parse("000000000000ffffffffffffffffffffffffffffffffffffffffffffffffffff").ToBytes(false)),
proofOfStakeReward: Money.Zero
);
this.Base58Prefixes = new byte[12][];
this.Base58Prefixes[(int) Base58Type.PUBKEY_ADDRESS] = new byte[] {66};
this.Base58Prefixes[(int) Base58Type.SCRIPT_ADDRESS] = new byte[] {128};
this.Base58Prefixes[(int) Base58Type.SECRET_KEY] = new byte[] {66 + 128};
this.Base58Prefixes[(int) Base58Type.ENCRYPTED_SECRET_KEY_NO_EC] = new byte[] {0x01, 0x42};
this.Base58Prefixes[(int) Base58Type.ENCRYPTED_SECRET_KEY_EC] = new byte[] {0x01, 0x43};
this.Base58Prefixes[(int) Base58Type.EXT_PUBLIC_KEY] = new byte[] {0x04, 0x88, 0xB2, 0x1E};
this.Base58Prefixes[(int) Base58Type.EXT_SECRET_KEY] = new byte[] {0x04, 0x88, 0xAD, 0xE4};
this.Base58Prefixes[(int) Base58Type.PASSPHRASE_CODE] =
new byte[] {0x2C, 0xE9, 0xB3, 0xE1, 0xFF, 0x39, 0xE2};
this.Base58Prefixes[(int) Base58Type.CONFIRMATION_CODE] = new byte[] {0x64, 0x3B, 0xF6, 0xA8, 0x9A};
this.Base58Prefixes[(int) Base58Type.STEALTH_ADDRESS] = new byte[] {0x2a};
this.Base58Prefixes[(int) Base58Type.ASSET_ID] = new byte[] {23};
this.Base58Prefixes[(int) Base58Type.COLORED_ADDRESS] = new byte[] {0x13};
this.Checkpoints = new Dictionary<int, CheckpointInfo>();
// TODO: Add genesis and premine block to Checkpoints
// First parameter - block height
// { 0, new CheckpointInfo(new uint256("0x00000e246d7b73b88c9ab55f2e5e94d9e22d471def3df5ea448f5576b1d156b9"), new uint256("0x0000000000000000000000000000000000000000000000000000000000000000")) },
var encoder = new Bech32Encoder("bc");
this.Bech32Encoders = new Bech32Encoder[2];
this.Bech32Encoders[(int) Bech32Type.WITNESS_PUBKEY_ADDRESS] = encoder;
this.Bech32Encoders[(int) Bech32Type.WITNESS_SCRIPT_ADDRESS] = encoder;
this.DNSSeeds = new List<DNSSeedData>
{
new DNSSeedData("testnode1.destream.io", "testnode1.destream.io")
};
this.SeedNodes = new List<NetworkAddress>();
this.DeStreamWallets = new LinkedList<string>(new[]
{
......@@ -57,79 +187,50 @@ namespace NBitcoin.Networks
"ThRCqMSWZmp5VWVzob1pfjqje6SqosP8Uw",
"TxMpDfwHb5SZ9fzNMmeLthTd1D4BZ1EGyQ"
}.OrderBy(p => Guid.NewGuid()));
Assert(this.Consensus.HashGenesisBlock ==
uint256.Parse("95dfb30e229e18197a812ece5d8d6c03efc9b9b65a9122a73f17d99613841b1b"));
Assert(this.Genesis.Header.HashMerkleRoot ==
uint256.Parse("6598d7cc968eae6d6e66e7ac88707f5e0948b816dc8ba52433d7edc1a1f2c6a3"));
}
// The message start string is designed to be unlikely to occur in normal data.
// The characters are rarely used upper ASCII, not valid as UTF-8, and produce
// a large 4-byte int at any alignment.
var messageStart = new byte[4];
messageStart[0] = 0xFD;
messageStart[1] = 0xFC;
messageStart[2] = 0xFC;
messageStart[3] = 0xFD;
uint magic = BitConverter.ToUInt32(messageStart, 0); // 0x11213171;
this.Name = "DeStreamTest";
this.Magic = magic;
this.DefaultPort = 0xDE11; // 56849,
this.RPCPort = 0xDE10; // 56848,
this.CoinTicker = "TDST";
this.Consensus.PowLimit =
new Target(new uint256("0000ffff00000000000000000000000000000000000000000000000000000000"));
this.Consensus.PowTargetTimespan = TimeSpan.FromSeconds(14 * 24 * 60 * 60); // two weeks
this.Consensus.PowTargetSpacing = TimeSpan.FromSeconds(10 * 60);
this.Consensus.PowAllowMinDifficultyBlocks = false;
this.Consensus.PowNoRetargeting = false;
this.Consensus.RuleChangeActivationThreshold = 1916; // 95% of 2016
this.Consensus.MinerConfirmationWindow = 2016; // nPowTargetTimespan / nPowTargetSpacing
this.Consensus.LastPOWBlock = 12500;
this.Consensus.DefaultAssumeValid =
new uint256("0x98fa6ef0bca5b431f15fd79dc6f879dc45b83ed4b1bbe933a383ef438321958e"); // 372652
this.Consensus.CoinbaseMaturity = 10;
this.Consensus.MaxMoney = long.MaxValue;
this.Consensus.ProofOfWorkReward = Money.Zero;
this.Consensus.ProofOfStakeReward = Money.Zero;
this.Consensus.LastPOWBlock = 12500;
this.Consensus.CoinType = 1;
this.DeStreamFeePart = 0.9;
this.FeeRate = 0.0077;
this.Base58Prefixes[(int) Base58Type.PUBKEY_ADDRESS] = new byte[] {66};
this.Base58Prefixes[(int) Base58Type.SCRIPT_ADDRESS] = new byte[] {128};
this.Base58Prefixes[(int) Base58Type.SECRET_KEY] = new byte[] {66 + 128};
this.Checkpoints = new Dictionary<int, CheckpointInfo>();
// TODO: Add genesis and premine block to Checkpoints
// First parameter - block height
// { 0, new CheckpointInfo(new uint256("0x00000e246d7b73b88c9ab55f2e5e94d9e22d471def3df5ea448f5576b1d156b9"), new uint256("0x0000000000000000000000000000000000000000000000000000000000000000")) },
protected Block CreateDeStreamGenesisBlock(ConsensusFactory consensusFactory, uint nTime, uint nNonce,
uint nBits, int nVersion, Money initialCoins, string[] initialWalletAddresses)
{
const string pszTimestamp =
"DESTREAM IS THE FIRST DECENTRALIZED GLOBAL FINANCIAL ECOSYSTEM FOR STREAMERS " +
"https://sputniknews.com/science/201810281069300462-ai-cyborg-sophia-gets-robot-visa/";
this.DNSSeeds = new List<DNSSeedData>
Transaction txNew = consensusFactory.CreateTransaction();
txNew.Version = 1;
txNew.Time = nTime;
txNew.AddInput(new TxIn
{
new DNSSeedData("testnode1.destream.io", "testnode1.destream.io")
};
ScriptSig = new Script(Op.GetPushOp(0), new Op
{
Code = (OpcodeType) 0x1,
PushData = new[] {(byte) 42}
}, Op.GetPushOp(Encoders.ASCII.DecodeData(pszTimestamp)))
});
this.SeedNodes = new List<NetworkAddress>();
// Create the genesis block.
this.GenesisTime = 1470467000;
this.GenesisNonce = 1831645;
this.GenesisBits = 0x1e0fffff;
this.GenesisVersion = 1;
this.GenesisReward = Money.Coins(initialCoins);
this.GenesisWalletAddress = initialWalletAddresses.First();
this.Genesis = this.CreateDeStreamGenesisBlock(this.Consensus.ConsensusFactory, this.GenesisTime,
this.GenesisNonce, this.GenesisBits, this.GenesisVersion, this.GenesisReward,
initialWalletAddresses);
this.Genesis.Header.Time =
(uint) new DateTimeOffset(2018, 09, 24, 16, 13, 00, TimeSpan.FromHours(3)).ToUnixTimeSeconds();
this.Genesis.Header.Nonce = 2433759;
this.Genesis.Header.Bits = this.Consensus.PowLimit;
this.Consensus.HashGenesisBlock = this.Genesis.GetHash();
byte[] prefix = this.Base58Prefixes[(int) Base58Type.PUBKEY_ADDRESS];
foreach (string initialWalletAddress in initialWalletAddresses)
{
byte[] destinationPublicKey =
Encoders.Base58Check.DecodeData(initialWalletAddress).Skip(prefix.Length).ToArray();
Script destination = new KeyId(new uint160(destinationPublicKey)).ScriptPubKey;
txNew.AddOutput(new TxOut(initialCoins / initialWalletAddresses.Length, destination));
}
// Assert(this.Consensus.HashGenesisBlock == uint256.Parse("c5974b227ccb19ebd97578285a5937bb4bfb6dcdbf473966d8a2f9c714a8dbb0"));
// Assert(this.Genesis.Header.HashMerkleRoot == uint256.Parse("9e3fff58fb1ba15a69198e22d99572fa024afb754bfe1d3b8d28b86fd9de62df"));
Block genesis = consensusFactory.CreateBlock();
genesis.Header.BlockTime = Utils.UnixTimeToDateTime(nTime);
genesis.Header.Bits = nBits;
genesis.Header.Nonce = nNonce;
genesis.Header.Version = nVersion;
genesis.Transactions.Add(txNew);
genesis.Header.HashPrevBlock = uint256.Zero;
genesis.UpdateMerkleRoot();
return genesis;
}
}
}
\ No newline at end of file
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<Description>Stratis Bitcoin FullNode</Description>
<AssemblyTitle>Stratis.Bitcoin.Networks</AssemblyTitle>
......@@ -16,11 +15,9 @@
<GenerateAssemblyFileVersionAttribute>false</GenerateAssemblyFileVersionAttribute>
<Version>3.0.0.0</Version>
<GeneratePackageOnBuild>False</GeneratePackageOnBuild>
<CodeAnalysisRuleSet>..\None.ruleset</CodeAnalysisRuleSet>
<CodeAnalysisRuleSet>..\None.ruleset</CodeAnalysisRuleSet>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\NBitcoin\NBitcoin.csproj" />
</ItemGroup>
</Project>
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment