Skip to content

Commit 92f796d

Browse files
CybitsBlockchainJimmy Savvadimsavva
authored
Cybits Network Implementation (#362)
* Cybits Network Implementation * Update launchsettings * Updated Maximum block size and seed nodes * Update test net * Updated MaxOpReturnRelay Co-authored-by: Jimmy Savva <jimmy.savva@entelect.co.za> Co-authored-by: dimsavva <dimsavva@gmail.com>
1 parent f1f12fb commit 92f796d

17 files changed

Lines changed: 968 additions & 0 deletions
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
<Project Sdk="Microsoft.NET.Sdk">
2+
3+
<PropertyGroup>
4+
<OutputType>Library</OutputType>
5+
<TargetFramework>netcoreapp3.1</TargetFramework>
6+
<ApplicationIcon />
7+
<StartupObject />
8+
</PropertyGroup>
9+
10+
<ItemGroup>
11+
<ProjectReference Include="..\Blockcore\Blockcore.csproj" />
12+
<ProjectReference Include="..\Features\Blockcore.Features.Consensus\Blockcore.Features.Consensus.csproj" />
13+
<ProjectReference Include="..\Features\Blockcore.Features.MemoryPool\Blockcore.Features.MemoryPool.csproj" />
14+
</ItemGroup>
15+
16+
</Project>
Lines changed: 272 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,272 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using Blockcore.Features.Consensus.Rules.CommonRules;
4+
using Blockcore.Features.Consensus.Rules.ProvenHeaderRules;
5+
using Blockcore.Features.Consensus.Rules.UtxosetRules;
6+
using Blockcore.Features.MemoryPool.Rules;
7+
using Blockcore.Networks.Cybits.Policies;
8+
using Blockcore.Networks.Cybits.Rules;
9+
using NBitcoin;
10+
using NBitcoin.BouncyCastle.Math;
11+
using NBitcoin.DataEncoders;
12+
using System.Linq;
13+
using System.Net;
14+
using Blockcore.Networks.Cybits.Setup;
15+
using Blockcore.Base.Deployments;
16+
using Blockcore.Consensus.BlockInfo;
17+
using Blockcore.Consensus;
18+
using Blockcore.P2P;
19+
using Blockcore.Consensus.TransactionInfo;
20+
using Blockcore.Consensus.ScriptInfo;
21+
using Blockcore.Networks.Cybits.Deployments;
22+
23+
namespace Blockcore.Networks.Cybits
24+
{
25+
public class CybitsMain : Network
26+
{
27+
public CybitsMain()
28+
{
29+
CoinSetup setup = CybitsSetup.Instance.Setup;
30+
NetworkSetup network = CybitsSetup.Instance.Main;
31+
32+
this.NetworkType = NetworkType.Mainnet;
33+
this.DefaultConfigFilename = setup.ConfigFileName; // The default name used for the Cybits configuration file.
34+
35+
this.Name = network.Name;
36+
this.CoinTicker = network.CoinTicker;
37+
this.Magic = ConversionTools.ConvertToUInt32(setup.Magic);
38+
this.RootFolderName = network.RootFolderName;
39+
this.DefaultPort = network.DefaultPort;
40+
this.DefaultRPCPort = network.DefaultRPCPort;
41+
this.DefaultAPIPort = network.DefaultAPIPort;
42+
43+
this.DefaultMaxOutboundConnections = 16;
44+
this.DefaultMaxInboundConnections = 109;
45+
this.MaxTipAge = 2 * 60 * 60;
46+
this.MinTxFee = 0;
47+
this.MaxTxFee = 0;
48+
this.FallbackFee = 0;
49+
this.MinRelayTxFee = 0;
50+
this.MaxTimeOffsetSeconds = 25 * 60;
51+
this.DefaultBanTimeSeconds = 16000; // 500 (MaxReorg) * 64 (TargetSpacing) / 2 = 4 hours, 26 minutes and 40 seconds
52+
53+
var consensusFactory = new PosConsensusFactory();
54+
55+
// Create the genesis block.
56+
this.GenesisTime = network.GenesisTime;
57+
this.GenesisNonce = network.GenesisNonce;
58+
this.GenesisBits = network.GenesisBits;
59+
this.GenesisVersion = network.GenesisVersion;
60+
this.GenesisReward = network.GenesisReward;
61+
62+
Block genesisBlock = CreateGenesisBlock(consensusFactory,
63+
this.GenesisTime,
64+
this.GenesisNonce,
65+
this.GenesisBits,
66+
this.GenesisVersion,
67+
this.GenesisReward,
68+
setup.GenesisText);
69+
70+
this.Genesis = genesisBlock;
71+
72+
var consensusOptions = new PosConsensusOptions
73+
{
74+
MaxBlockBaseSize = 4_000_000,
75+
MaxStandardVersion = 2,
76+
MaxStandardTxWeight = 100_000,
77+
MaxBlockSigopsCost = 20_000,
78+
MaxStandardTxSigopsCost = 20_000 / 5,
79+
WitnessScaleFactor = 4,
80+
MinBlockFeeRate = Money.Zero
81+
};
82+
83+
var buriedDeployments = new BuriedDeploymentsArray
84+
{
85+
[BuriedDeployments.BIP34] = 0,
86+
[BuriedDeployments.BIP65] = 0,
87+
[BuriedDeployments.BIP66] = 0
88+
};
89+
90+
var bip9Deployments = new CybitsBIP9Deployments()
91+
{
92+
[CybitsBIP9Deployments.ColdStaking] = new BIP9DeploymentsParameters("ColdStaking", 27, BIP9DeploymentsParameters.AlwaysActive, 999999999, BIP9DeploymentsParameters.DefaultMainnetThreshold),
93+
[CybitsBIP9Deployments.CSV] = new BIP9DeploymentsParameters("CSV", 0, BIP9DeploymentsParameters.AlwaysActive, 999999999, BIP9DeploymentsParameters.DefaultMainnetThreshold),
94+
[CybitsBIP9Deployments.Segwit] = new BIP9DeploymentsParameters("Segwit", 1, BIP9DeploymentsParameters.AlwaysActive, 999999999, BIP9DeploymentsParameters.DefaultMainnetThreshold)
95+
};
96+
97+
this.Consensus = new Blockcore.Consensus.Consensus(
98+
consensusFactory: consensusFactory,
99+
consensusOptions: consensusOptions,
100+
coinType: setup.CoinType,
101+
hashGenesisBlock: genesisBlock.GetHash(),
102+
subsidyHalvingInterval: 500000000,
103+
majorityEnforceBlockUpgrade: 750,
104+
majorityRejectBlockOutdated: 950,
105+
majorityWindow: 1000,
106+
buriedDeployments: buriedDeployments,
107+
bip9Deployments: bip9Deployments,
108+
bip34Hash: null,
109+
minerConfirmationWindow: 2016, // nPowTargetTimespan / nPowTargetSpacing
110+
maxReorgLength: 500,
111+
defaultAssumeValid: null,
112+
maxMoney: long.MaxValue,
113+
coinbaseMaturity: 50,
114+
premineHeight: 2,
115+
premineReward: Money.Coins(setup.PremineReward),
116+
proofOfWorkReward: Money.Coins(setup.PoWBlockReward),
117+
targetTimespan: TimeSpan.FromSeconds(14 * 24 * 60 * 60), // two weeks
118+
targetSpacing: setup.TargetSpacing,
119+
powAllowMinDifficultyBlocks: false,
120+
posNoRetargeting: false,
121+
powNoRetargeting: false,
122+
powLimit: new Target(new uint256("00000fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff")),
123+
minimumChainWork: null,
124+
isProofOfStake: true,
125+
lastPowBlock: setup.LastPowBlock,
126+
proofOfStakeLimit: new BigInteger(uint256.Parse("00000fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff").ToBytes(false)),
127+
proofOfStakeLimitV2: new BigInteger(uint256.Parse("000000000000ffffffffffffffffffffffffffffffffffffffffffffffffffff").ToBytes(false)),
128+
proofOfStakeReward: Money.Coins(setup.PoSBlockReward),
129+
proofOfStakeTimestampMask: setup.ProofOfStakeTimestampMask
130+
);
131+
132+
this.Consensus.PosEmptyCoinbase = CybitsSetup.Instance.IsPoSv3();
133+
this.Consensus.PosUseTimeFieldInKernalHash = CybitsSetup.Instance.IsPoSv3();
134+
135+
// TODO: Set your Base58Prefixes
136+
this.Base58Prefixes = new byte[12][];
137+
this.Base58Prefixes[(int)Base58Type.PUBKEY_ADDRESS] = new byte[] { (byte)network.PubKeyAddress };
138+
this.Base58Prefixes[(int)Base58Type.SCRIPT_ADDRESS] = new byte[] { (byte)network.ScriptAddress };
139+
this.Base58Prefixes[(int)Base58Type.SECRET_KEY] = new byte[] { (byte)network.SecretAddress };
140+
141+
this.Base58Prefixes[(int)Base58Type.ENCRYPTED_SECRET_KEY_NO_EC] = new byte[] { 0x01, 0x42 };
142+
this.Base58Prefixes[(int)Base58Type.ENCRYPTED_SECRET_KEY_EC] = new byte[] { 0x01, 0x43 };
143+
this.Base58Prefixes[(int)Base58Type.EXT_PUBLIC_KEY] = new byte[] { (0x04), (0x88), (0xB2), (0x1E) };
144+
this.Base58Prefixes[(int)Base58Type.EXT_SECRET_KEY] = new byte[] { (0x04), (0x88), (0xAD), (0xE4) };
145+
this.Base58Prefixes[(int)Base58Type.PASSPHRASE_CODE] = new byte[] { 0x2C, 0xE9, 0xB3, 0xE1, 0xFF, 0x39, 0xE2 };
146+
this.Base58Prefixes[(int)Base58Type.CONFIRMATION_CODE] = new byte[] { 0x64, 0x3B, 0xF6, 0xA8, 0x9A };
147+
this.Base58Prefixes[(int)Base58Type.ASSET_ID] = new byte[] { 23 };
148+
149+
this.Bech32Encoders = new Bech32Encoder[2];
150+
var encoder = new Bech32Encoder(network.CoinTicker.ToLowerInvariant());
151+
this.Bech32Encoders[(int)Bech32Type.WITNESS_PUBKEY_ADDRESS] = encoder;
152+
this.Bech32Encoders[(int)Bech32Type.WITNESS_SCRIPT_ADDRESS] = encoder;
153+
154+
this.Checkpoints = network.Checkpoints;
155+
this.DNSSeeds = network.DNS.Select(dns => new DNSSeedData(dns, dns)).ToList();
156+
this.SeedNodes = network.Nodes.Select(node => new NBitcoin.Protocol.NetworkAddress(IPAddress.Parse(node), network.DefaultPort)).ToList();
157+
158+
this.StandardScriptsRegistry = new CybitsStandardScriptsRegistry();
159+
160+
// 64 below should be changed to TargetSpacingSeconds when we move that field.
161+
Assert(this.DefaultBanTimeSeconds <= this.Consensus.MaxReorgLength * 64 / 2);
162+
163+
Assert(this.Consensus.HashGenesisBlock == uint256.Parse(network.HashGenesisBlock));
164+
Assert(this.Genesis.Header.HashMerkleRoot == uint256.Parse(network.HashMerkleRoot));
165+
166+
RegisterRules(this.Consensus);
167+
RegisterMempoolRules(this.Consensus);
168+
}
169+
170+
protected void RegisterRules(IConsensus consensus)
171+
{
172+
consensus.ConsensusRules
173+
.Register<HeaderTimeChecksRule>()
174+
.Register<HeaderTimeChecksPosRule>()
175+
.Register<PosFutureDriftRule>()
176+
.Register<CheckDifficultyPosRule>()
177+
.Register<CybitsHeaderVersionRule>()
178+
.Register<ProvenHeaderSizeRule>()
179+
.Register<ProvenHeaderCoinstakeRule>();
180+
181+
consensus.ConsensusRules
182+
.Register<BlockMerkleRootRule>()
183+
.Register<PosBlockSignatureRepresentationRule>()
184+
.Register<PosBlockSignatureRule>();
185+
186+
consensus.ConsensusRules
187+
.Register<SetActivationDeploymentsPartialValidationRule>()
188+
.Register<PosTimeMaskRule>()
189+
190+
// rules that are inside the method ContextualCheckBlock
191+
.Register<TransactionLocktimeActivationRule>()
192+
.Register<CoinbaseHeightActivationRule>()
193+
.Register<WitnessCommitmentsRule>()
194+
.Register<BlockSizeRule>()
195+
196+
// rules that are inside the method CheckBlock
197+
.Register<EnsureCoinbaseRule>()
198+
.Register<CheckPowTransactionRule>()
199+
.Register<CheckPosTransactionRule>()
200+
.Register<CheckSigOpsRule>()
201+
.Register<PosCoinstakeRule>();
202+
203+
consensus.ConsensusRules
204+
.Register<SetActivationDeploymentsFullValidationRule>()
205+
206+
.Register<CheckDifficultyHybridRule>()
207+
208+
// rules that require the store to be loaded (coinview)
209+
.Register<FetchUtxosetRule>()
210+
.Register<TransactionDuplicationActivationRule>()
211+
.Register<CheckPosUtxosetRule>() // implements BIP68, MaxSigOps and BlockReward calculation
212+
// Place the PosColdStakingRule after the PosCoinviewRule to ensure that all input scripts have been evaluated
213+
// and that the "IsColdCoinStake" flag would have been set by the OP_CHECKCOLDSTAKEVERIFY opcode if applicable.
214+
.Register<PosColdStakingRule>()
215+
.Register<PushUtxosetRule>()
216+
.Register<FlushUtxosetRule>();
217+
}
218+
219+
protected void RegisterMempoolRules(IConsensus consensus)
220+
{
221+
consensus.MempoolRules = new List<Type>()
222+
{
223+
typeof(CheckConflictsMempoolRule),
224+
typeof(CheckCoinViewMempoolRule),
225+
typeof(CreateMempoolEntryMempoolRule),
226+
typeof(CheckSigOpsMempoolRule),
227+
typeof(CheckFeeMempoolRule),
228+
typeof(CheckRateLimitMempoolRule),
229+
typeof(CheckAncestorsMempoolRule),
230+
typeof(CheckReplacementMempoolRule),
231+
typeof(CheckAllInputsMempoolRule),
232+
typeof(CheckTxOutDustRule)
233+
};
234+
}
235+
236+
protected static Block CreateGenesisBlock(ConsensusFactory consensusFactory, uint nTime, uint nNonce, uint nBits, int nVersion, Money genesisReward, string genesisText)
237+
{
238+
Transaction txNew = consensusFactory.CreateTransaction();
239+
txNew.Version = 1;
240+
241+
if (txNew is IPosTransactionWithTime posTx)
242+
{
243+
posTx.Time = nTime;
244+
}
245+
246+
txNew.AddInput(new TxIn()
247+
{
248+
ScriptSig = new Script(Op.GetPushOp(0), new Op()
249+
{
250+
Code = (OpcodeType)0x1,
251+
PushData = new[] { (byte)42 }
252+
}, Op.GetPushOp(Encoders.ASCII.DecodeData(genesisText)))
253+
});
254+
255+
txNew.AddOutput(new TxOut()
256+
{
257+
Value = genesisReward,
258+
});
259+
260+
Block genesis = consensusFactory.CreateBlock();
261+
genesis.Header.BlockTime = Utils.UnixTimeToDateTime(nTime);
262+
genesis.Header.Bits = nBits;
263+
genesis.Header.Nonce = nNonce;
264+
genesis.Header.Version = nVersion;
265+
genesis.Transactions.Add(txNew);
266+
genesis.Header.HashPrevBlock = uint256.Zero;
267+
genesis.UpdateMerkleRoot();
268+
269+
return genesis;
270+
}
271+
}
272+
}

0 commit comments

Comments
 (0)