示例#1
0
        public ChainSpec Load(byte[] data)
        {
            try
            {
                string jsonData      = System.Text.Encoding.UTF8.GetString(data);
                var    chainSpecJson = _serializer.Deserialize <ChainSpecJson>(jsonData);
                var    chainSpec     = new ChainSpec();

                chainSpec.ChainId = (int)chainSpecJson.Params.NetworkId;
                chainSpec.Name    = chainSpecJson.Name;
                chainSpec.DataDir = chainSpecJson.DataDir;
                LoadGenesis(chainSpecJson, chainSpec);
                LoadEngine(chainSpecJson, chainSpec);
                LoadAllocations(chainSpecJson, chainSpec);
                LoadBootnodes(chainSpecJson, chainSpec);
                LoadTransitions(chainSpecJson, chainSpec);
                LoadParameters(chainSpecJson, chainSpec);

                return(chainSpec);
            }
            catch (Exception e)
            {
                throw new InvalidDataException($"Error when loading chainspec ({e.Message})", e);
            }
        }
示例#2
0
 private void LoadParameters(ChainSpecJson chainSpecJson, ChainSpec chainSpec)
 {
     chainSpec.Parameters = new ChainParameters();
     chainSpec.Parameters.AccountStartNonce        = chainSpecJson.Params.AccountStartNonce ?? UInt256.Zero;
     chainSpec.Parameters.GasLimitBoundDivisor     = chainSpecJson.Params.GasLimitBoundDivisor ?? 0x0400;
     chainSpec.Parameters.MaximumExtraDataSize     = chainSpecJson.Params.MaximumExtraDataSize ?? 32;
     chainSpec.Parameters.MinGasLimit              = chainSpecJson.Params.MinGasLimit ?? 5000;
     chainSpec.Parameters.MaxCodeSize              = chainSpecJson.Params.MaxCodeSize ?? 24576;
     chainSpec.Parameters.MaxCodeSizeTransition    = chainSpecJson.Params.MaxCodeSizeTransition ?? 0;
     chainSpec.Parameters.Registrar                = chainSpecJson.Params.EnsRegistrar;
     chainSpec.Parameters.ForkBlock                = chainSpecJson.Params.ForkBlock;
     chainSpec.Parameters.ForkCanonHash            = chainSpecJson.Params.ForkCanonHash;
     chainSpec.Parameters.Eip150Transition         = chainSpecJson.Params.Eip150Transition;
     chainSpec.Parameters.Eip160Transition         = chainSpecJson.Params.Eip160Transition;
     chainSpec.Parameters.Eip161abcTransition      = chainSpecJson.Params.Eip161abcTransition;
     chainSpec.Parameters.Eip161dTransition        = chainSpecJson.Params.Eip161dTransition;
     chainSpec.Parameters.Eip155Transition         = chainSpecJson.Params.Eip155Transition;
     chainSpec.Parameters.Eip140Transition         = chainSpecJson.Params.Eip140Transition;
     chainSpec.Parameters.Eip211Transition         = chainSpecJson.Params.Eip211Transition;
     chainSpec.Parameters.Eip214Transition         = chainSpecJson.Params.Eip214Transition;
     chainSpec.Parameters.Eip658Transition         = chainSpecJson.Params.Eip658Transition;
     chainSpec.Parameters.Eip145Transition         = chainSpecJson.Params.Eip145Transition;
     chainSpec.Parameters.Eip1014Transition        = chainSpecJson.Params.Eip1014Transition;
     chainSpec.Parameters.Eip1052Transition        = chainSpecJson.Params.Eip1052Transition;
     chainSpec.Parameters.Eip1283Transition        = chainSpecJson.Params.Eip1283Transition;
     chainSpec.Parameters.Eip1283DisableTransition = chainSpecJson.Params.Eip1283DisableTransition;
 }
        private static void LoadGenesis(GenesisFileJson genesisJson, ChainSpec chainSpec)
        {
            var nonce       = genesisJson.Nonce;
            var mixHash     = genesisJson.MixHash;
            var parentHash  = genesisJson.ParentHash ?? Keccak.Zero;
            var timestamp   = genesisJson.Timestamp;
            var difficulty  = genesisJson.Difficulty;
            var extraData   = genesisJson.ExtraData;
            var gasLimit    = genesisJson.GasLimit;
            var beneficiary = genesisJson.Author ?? Address.Zero;

            BlockHeader genesisHeader = new BlockHeader(
                parentHash,
                Keccak.OfAnEmptySequenceRlp,
                beneficiary,
                difficulty,
                0,
                (long)gasLimit,
                timestamp,
                extraData);

            genesisHeader.Author       = beneficiary;
            genesisHeader.Hash         = Keccak.Zero; // need to run the block to know the actual hash
            genesisHeader.Bloom        = new Bloom();
            genesisHeader.GasUsed      = 0;
            genesisHeader.MixHash      = mixHash;
            genesisHeader.Nonce        = (ulong)nonce;
            genesisHeader.ReceiptsRoot = Keccak.EmptyTreeHash;
            genesisHeader.StateRoot    = Keccak.EmptyTreeHash;
            genesisHeader.TxRoot       = Keccak.EmptyTreeHash;

            chainSpec.Genesis = new Block(genesisHeader);
        }
        public ChainSpec Load(byte[] data)
        {
            try
            {
                string jsonData    = System.Text.Encoding.UTF8.GetString(data);
                var    genesisJson = _serializer.Deserialize <GenesisFileJson>(jsonData);
                var    chainSpec   = new ChainSpec();

                chainSpec.ChainId = (int)genesisJson.Config.ChainId;
                LoadGenesis(genesisJson, chainSpec);
                LoadEngine(genesisJson, chainSpec);
                LoadAllocations(genesisJson, chainSpec);

                chainSpec.HomesteadBlockNumber        = genesisJson.Config.HomesteadBlock;
                chainSpec.TangerineWhistleBlockNumber = genesisJson.Config.Eip150Block;
                chainSpec.SpuriousDragonBlockNumber   = genesisJson.Config.Eip158Block;
                chainSpec.ByzantiumBlockNumber        = genesisJson.Config.ByzantiumBlock;
                chainSpec.ConstantinopleBlockNumber   = genesisJson.Config.ConstantinopleBlock;

                return(chainSpec);
            }
            catch (Exception e)
            {
                throw new InvalidDataException($"Error when loading chainspec ({e.Message})", e);
            }
        }
        private static void LoadAllocations(GenesisFileJson genesisJson, ChainSpec chainSpec)
        {
            if (genesisJson.Alloc == null)
            {
                return;
            }

            chainSpec.Allocations = new Dictionary <Address, (UInt256 Balance, byte[] Code)>();
            foreach (KeyValuePair <string, AllocationJson> account in genesisJson.Alloc)
            {
                if (account.Value.Balance != null)
                {
                    bool result = UInt256.TryParse(account.Value.Balance, out UInt256 allocationValue);
                    if (!result)
                    {
                        result = UInt256.TryParse(account.Value.Balance.Replace("0x", string.Empty), NumberStyles.HexNumber, CultureInfo.InvariantCulture, out allocationValue);
                    }

                    if (!result)
                    {
                        throw new InvalidDataException($"Cannot recognize allocation value format in {account.Value.Balance}");
                    }

                    // todo: handle code like in chainspec
                    chainSpec.Allocations[new Address(account.Key)] = (allocationValue, null);
                }
            }
        }
示例#6
0
 private void LoadParameters(ChainSpecJson chainSpecJson, ChainSpec chainSpec)
 {
     chainSpec.Parameters = new ChainParameters
     {
         AccountStartNonce        = chainSpecJson.Params.AccountStartNonce ?? UInt256.Zero,
         GasLimitBoundDivisor     = chainSpecJson.Params.GasLimitBoundDivisor ?? 0x0400,
         MaximumExtraDataSize     = chainSpecJson.Params.MaximumExtraDataSize ?? 32,
         MinGasLimit              = chainSpecJson.Params.MinGasLimit ?? 5000,
         MaxCodeSize              = chainSpecJson.Params.MaxCodeSize ?? long.MaxValue,
         MaxCodeSizeTransition    = chainSpecJson.Params.MaxCodeSizeTransition ?? 0,
         Registrar                = chainSpecJson.Params.EnsRegistrar,
         ForkBlock                = chainSpecJson.Params.ForkBlock,
         ForkCanonHash            = chainSpecJson.Params.ForkCanonHash,
         Eip150Transition         = chainSpecJson.Params.Eip150Transition ?? 0,
         Eip152Transition         = chainSpecJson.Params.Eip152Transition,
         Eip160Transition         = chainSpecJson.Params.Eip160Transition ?? 0,
         Eip161abcTransition      = chainSpecJson.Params.Eip161abcTransition ?? 0,
         Eip161dTransition        = chainSpecJson.Params.Eip161dTransition ?? 0,
         Eip155Transition         = chainSpecJson.Params.Eip155Transition ?? 0,
         Eip140Transition         = chainSpecJson.Params.Eip140Transition,
         Eip211Transition         = chainSpecJson.Params.Eip211Transition,
         Eip214Transition         = chainSpecJson.Params.Eip214Transition,
         Eip658Transition         = chainSpecJson.Params.Eip658Transition,
         Eip145Transition         = chainSpecJson.Params.Eip145Transition,
         Eip1014Transition        = chainSpecJson.Params.Eip1014Transition,
         Eip1052Transition        = chainSpecJson.Params.Eip1052Transition,
         Eip1108Transition        = chainSpecJson.Params.Eip1108Transition,
         Eip1283Transition        = chainSpecJson.Params.Eip1283Transition,
         Eip1283DisableTransition = chainSpecJson.Params.Eip1283DisableTransition,
         Eip1344Transition        = chainSpecJson.Params.Eip1344Transition,
         Eip1884Transition        = chainSpecJson.Params.Eip1884Transition,
         Eip2028Transition        = chainSpecJson.Params.Eip2028Transition,
         Eip2200Transition        = chainSpecJson.Params.Eip2200Transition,
     };
 }
示例#7
0
        private void LoadTransitions(ChainSpecJson chainSpecJson, ChainSpec chainSpec)
        {
            if (chainSpecJson.Engine?.Ethash != null)
            {
                chainSpec.HomesteadBlockNumber = chainSpecJson.Engine.Ethash.HomesteadTransition;
                chainSpec.DaoForkBlockNumber   = chainSpecJson.Engine.Ethash.DaoHardForkTransition;
            }

            chainSpec.TangerineWhistleBlockNumber = chainSpecJson.Params.Eip150Transition;
            chainSpec.SpuriousDragonBlockNumber   = chainSpecJson.Params.Eip160Transition;
            chainSpec.ByzantiumBlockNumber        = chainSpecJson.Params.Eip140Transition;
            chainSpec.ConstantinopleBlockNumber   = chainSpecJson.Params.Eip145Transition;
        }
示例#8
0
        private static void LoadBootnodes(ChainSpecJson chainSpecJson, ChainSpec chainSpec)
        {
            if (chainSpecJson.Nodes == null)
            {
                chainSpec.Bootnodes = new NetworkNode[0];
                return;
            }

            chainSpec.Bootnodes = new NetworkNode[chainSpecJson.Nodes.Length];
            for (int i = 0; i < chainSpecJson.Nodes.Length; i++)
            {
                chainSpec.Bootnodes[i] = new NetworkNode(chainSpecJson.Nodes[i]);
            }
        }
 private void LoadEngine(GenesisFileJson genesisJson, ChainSpec chainSpec)
 {
     if (genesisJson.Config.Clique != null)
     {
         chainSpec.SealEngineType = SealEngineType.Clique;
         chainSpec.Clique         = new CliqueParameters();
         chainSpec.Clique.Period  = genesisJson.Config.Clique.Period;
         chainSpec.Clique.Epoch   = genesisJson.Config.Clique.Epoch;
         chainSpec.Clique.Reward  = 0;
     }
     else
     {
         chainSpec.SealEngineType = SealEngineType.Ethash;
     }
 }
示例#10
0
        private void LoadEngine(ChainSpecJson chainSpecJson, ChainSpec chainSpec)
        {
            if (chainSpecJson.Engine?.AuthorityRound != null)
            {
                chainSpec.SealEngineType = SealEngineType.AuRa;
            }
            else if (chainSpecJson.Engine?.Clique != null)
            {
                chainSpec.SealEngineType = SealEngineType.Clique;
                chainSpec.Clique         = new CliqueParameters();
                chainSpec.Clique.Epoch   = chainSpecJson.Engine.Clique.Epoch;
                chainSpec.Clique.Period  = chainSpecJson.Engine.Clique.Period;
                chainSpec.Clique.Reward  = chainSpecJson.Engine.Clique.BlockReward ?? UInt256.Zero;
            }
            else if (chainSpecJson.Engine?.Ethash != null)
            {
                chainSpec.SealEngineType                = SealEngineType.Ethash;
                chainSpec.Ethash                        = new EthashParameters();
                chainSpec.Ethash.MinimumDifficulty      = chainSpecJson.Engine.Ethash.MinimumDifficulty ?? 0L;
                chainSpec.Ethash.DifficultyBoundDivisor = chainSpecJson.Engine.Ethash.DifficultyBoundDivisor ?? 0x0800L;
                chainSpec.Ethash.DurationLimit          = chainSpecJson.Engine.Ethash.DurationLimit ?? 13L;
                chainSpec.Ethash.HomesteadTransition    = chainSpecJson.Engine.Ethash.HomesteadTransition ?? 0;
                chainSpec.Ethash.DaoHardforkTransition  = chainSpecJson.Engine.Ethash.DaoHardforkTransition;
                chainSpec.Ethash.DaoHardforkBeneficiary = chainSpecJson.Engine.Ethash.DaoHardforkBeneficiary;
                chainSpec.Ethash.DaoHardforkAccounts    = chainSpecJson.Engine.Ethash.DaoHardforkAccounts ?? new Address[0];
                chainSpec.Ethash.Eip100bTransition      = chainSpecJson.Engine.Ethash.Eip100bTransition ?? 0L;

                chainSpec.Ethash.BlockRewards = new Dictionary <long, UInt256>();
                foreach (KeyValuePair <string, UInt256> reward in chainSpecJson.Engine.Ethash.BlockReward)
                {
                    chainSpec.Ethash.BlockRewards.Add(LongConverter.FromString(reward.Key), reward.Value);
                }

                chainSpec.Ethash.DifficultyBombDelays = new Dictionary <long, long>();
                foreach (KeyValuePair <string, long> reward in chainSpecJson.Engine.Ethash.DifficultyBombDelays)
                {
                    chainSpec.Ethash.DifficultyBombDelays.Add(LongConverter.FromString(reward.Key), reward.Value);
                }
            }
            else if (chainSpecJson.Engine?.NethDev != null)
            {
                chainSpec.SealEngineType = SealEngineType.NethDev;
            }
            else
            {
                throw new NotSupportedException("unknown seal engine in chainspec");
            }
        }
示例#11
0
        private static void LoadGenesis(ChainSpecJson chainSpecJson, ChainSpec chainSpec)
        {
            if (chainSpecJson.Genesis == null)
            {
                return;
            }

            var nonce   = chainSpecJson.Genesis.Seal.Ethereum?.Nonce ?? 0;
            var mixHash = chainSpecJson.Genesis.Seal.Ethereum?.MixHash ?? Keccak.Zero;

            var auRaSignature = chainSpecJson.Genesis.Seal.AuthorityRound?.Signature;
            var step          = chainSpecJson.Genesis.Seal.AuthorityRound?.Step;

            var parentHash  = chainSpecJson.Genesis.ParentHash ?? Keccak.Zero;
            var timestamp   = chainSpecJson.Genesis.Timestamp;
            var difficulty  = chainSpecJson.Genesis.Difficulty;
            var extraData   = chainSpecJson.Genesis.ExtraData ?? new byte[0];
            var gasLimit    = chainSpecJson.Genesis.GasLimit;
            var beneficiary = chainSpecJson.Genesis.Author ?? Address.Zero;

            BlockHeader genesisHeader = new BlockHeader(
                parentHash,
                Keccak.OfAnEmptySequenceRlp,
                beneficiary,
                difficulty,
                0,
                (long)gasLimit,
                timestamp,
                extraData);

            genesisHeader.Author       = beneficiary;
            genesisHeader.Hash         = Keccak.Zero; // need to run the block to know the actual hash
            genesisHeader.Bloom        = new Bloom();
            genesisHeader.GasUsed      = 0;
            genesisHeader.MixHash      = mixHash;
            genesisHeader.Nonce        = (ulong)nonce;
            genesisHeader.ReceiptsRoot = Keccak.EmptyTreeHash;
            genesisHeader.StateRoot    = Keccak.EmptyTreeHash;
            genesisHeader.TxRoot       = Keccak.EmptyTreeHash;

            genesisHeader.AuRaStep      = step;
            genesisHeader.AuRaSignature = auRaSignature;

            chainSpec.Genesis = new Block(genesisHeader);
        }
示例#12
0
        private static void LoadAllocations(ChainSpecJson chainSpecJson, ChainSpec chainSpec)
        {
            if (chainSpecJson.Accounts == null)
            {
                return;
            }

            chainSpec.Allocations = new Dictionary <Address, ChainSpecAllocation>();
            foreach (KeyValuePair <string, AllocationJson> account in chainSpecJson.Accounts)
            {
                if (account.Value.BuiltIn != null && account.Value.Balance == UInt256.Zero)
                {
                    continue;
                }

                chainSpec.Allocations[new Address(account.Key)] = new ChainSpecAllocation(
                    account.Value.Balance,
                    account.Value.Code,
                    account.Value.Constructor);
            }
        }
示例#13
0
        private static void LoadAllocations(ChainSpecJson chainSpecJson, ChainSpec chainSpec)
        {
            if (chainSpecJson.Accounts == null)
            {
                return;
            }

            chainSpec.Allocations = new Dictionary <Address, (UInt256 Balance, byte[] Code)>();
            foreach (KeyValuePair <string, AllocationJson> account in chainSpecJson.Accounts)
            {
                byte[]  codeValue       = null;
                UInt256 allocationValue = UInt256.Zero;
                if (account.Value.Balance != null)
                {
                    bool balanceParsingResult = UInt256.TryParse(account.Value.Balance, out allocationValue);
                    if (!balanceParsingResult)
                    {
                        balanceParsingResult = UInt256.TryParse(account.Value.Balance.Replace("0x", string.Empty), NumberStyles.HexNumber, CultureInfo.InvariantCulture, out allocationValue);
                    }

                    if (!balanceParsingResult)
                    {
                        throw new InvalidDataException($"Cannot recognize allocation value format in {account.Value.Balance}");
                    }
                }

                if (account.Value.Code != null)
                {
                    codeValue = Bytes.FromHexString(account.Value.Code);
                }

                if (account.Value.Balance != null || account.Value.Code != null)
                {
                    chainSpec.Allocations[new Address(account.Key)] = (allocationValue, codeValue);
                }
            }
        }
示例#14
0
        private void LoadEngine(ChainSpecJson chainSpecJson, ChainSpec chainSpec)
        {
            AuRaParameters.Validator LoadValidator(ChainSpecJson.AuRaValidatorJson validatorJson, int level = 0)
            {
                var validatorType = validatorJson.GetValidatorType();
                var validator     = new AuRaParameters.Validator()
                {
                    ValidatorType = validatorType
                };

                switch (validator.ValidatorType)
                {
                case AuRaParameters.ValidatorType.List:
                    validator.Addresses = validatorJson.List;
                    break;

                case AuRaParameters.ValidatorType.Contract:
                    validator.Addresses = new[] { validatorJson.SafeContract };
                    break;

                case AuRaParameters.ValidatorType.ReportingContract:
                    validator.Addresses = new[] { validatorJson.Contract };
                    break;

                case AuRaParameters.ValidatorType.Multi:
                    if (level != 0)
                    {
                        throw new ArgumentException("AuRa multi validator cannot be inner validator.");
                    }
                    validator.Validators = validatorJson.Multi
                                           .ToDictionary(kvp => kvp.Key, kvp => LoadValidator(kvp.Value, level + 1))
                                           .ToImmutableSortedDictionary();
                    break;

                default:
                    throw new ArgumentOutOfRangeException();
                }

                return(validator);
            }

            if (chainSpecJson.Engine?.AuthorityRound != null)
            {
                chainSpec.SealEngineType = SealEngineType.AuRa;
                chainSpec.AuRa           = new AuRaParameters
                {
                    MaximumUncleCount           = chainSpecJson.Engine.AuthorityRound.MaximumUncleCount,
                    MaximumUncleCountTransition = chainSpecJson.Engine.AuthorityRound.MaximumUncleCountTransition,
                    StepDuration = chainSpecJson.Engine.AuthorityRound.StepDuration,
                    BlockReward  = chainSpecJson.Engine.AuthorityRound.BlockReward,
                    BlockRewardContractAddress    = chainSpecJson.Engine.AuthorityRound.BlockRewardContractAddress,
                    BlockRewardContractTransition = chainSpecJson.Engine.AuthorityRound.BlockRewardContractTransition,
                    Validators = LoadValidator(chainSpecJson.Engine.AuthorityRound.Validator)
                };
            }
            else if (chainSpecJson.Engine?.Clique != null)
            {
                chainSpec.SealEngineType = SealEngineType.Clique;
                chainSpec.Clique         = new CliqueParameters
                {
                    Epoch  = chainSpecJson.Engine.Clique.Epoch,
                    Period = chainSpecJson.Engine.Clique.Period,
                    Reward = chainSpecJson.Engine.Clique.BlockReward ?? UInt256.Zero
                };
            }
            else if (chainSpecJson.Engine?.Ethash != null)
            {
                chainSpec.SealEngineType = SealEngineType.Ethash;
                chainSpec.Ethash         = new EthashParameters
                {
                    MinimumDifficulty      = chainSpecJson.Engine.Ethash.MinimumDifficulty ?? 0L,
                    DifficultyBoundDivisor = chainSpecJson.Engine.Ethash.DifficultyBoundDivisor ?? 0x0800L,
                    DurationLimit          = chainSpecJson.Engine.Ethash.DurationLimit ?? 13L,
                    HomesteadTransition    = chainSpecJson.Engine.Ethash.HomesteadTransition ?? 0,
                    DaoHardforkTransition  = chainSpecJson.Engine.Ethash.DaoHardforkTransition,
                    DaoHardforkBeneficiary = chainSpecJson.Engine.Ethash.DaoHardforkBeneficiary,
                    DaoHardforkAccounts    = chainSpecJson.Engine.Ethash.DaoHardforkAccounts ?? new Address[0],
                    Eip100bTransition      = chainSpecJson.Engine.Ethash.Eip100bTransition ?? 0L,
                    BlockRewards           = new Dictionary <long, UInt256>()
                };

                foreach (KeyValuePair <string, UInt256> reward in chainSpecJson.Engine.Ethash.BlockReward)
                {
                    chainSpec.Ethash.BlockRewards.Add(LongConverter.FromString(reward.Key), reward.Value);
                }

                chainSpec.Ethash.DifficultyBombDelays = new Dictionary <long, long>();
                foreach (KeyValuePair <string, long> reward in chainSpecJson.Engine.Ethash.DifficultyBombDelays)
                {
                    chainSpec.Ethash.DifficultyBombDelays.Add(LongConverter.FromString(reward.Key), reward.Value);
                }
            }
            else if (chainSpecJson.Engine?.NethDev != null)
            {
                chainSpec.SealEngineType = SealEngineType.NethDev;
            }
            else
            {
                throw new NotSupportedException("unknown seal engine in chainspec");
            }
        }