Exemplo n.º 1
0
        public void GenesisBlock()
        {
            var owner = KeyPair.Generate();
            var nexus = new Nexus();

            Assert.IsTrue(nexus.CreateGenesisBlock("simnet", owner, DateTime.Now));

            Assert.IsTrue(nexus.GenesisHash != Hash.Null);

            var rootChain = nexus.RootChain;

            var symbol = Nexus.FuelTokenSymbol;

            Assert.IsTrue(nexus.TokenExists(symbol));
            var token = nexus.GetTokenInfo(symbol);

            Assert.IsTrue(token.MaxSupply > 0);

            var supply = nexus.GetTokenSupply(symbol);

            Assert.IsTrue(supply > 0);

            Assert.IsTrue(rootChain != null);
            Assert.IsTrue(rootChain.BlockHeight > 0);
            Assert.IsTrue(rootChain.ChildChains.Any());

            Assert.IsTrue(nexus.IsValidator(owner.Address));

            var randomKey = KeyPair.Generate();

            Assert.IsFalse(nexus.IsValidator(randomKey.Address));

            /*var txCount = nexus.GetTotalTransactionCount();
             * Assert.IsTrue(txCount > 0);*/
        }
Exemplo n.º 2
0
        public void GenesisBlock()
        {
            var owner = KeyPair.Generate();
            var nexus = new Nexus("tests", owner.Address);

            Assert.IsTrue(nexus.CreateGenesisBlock(owner, DateTime.Now));

            var rootChain = nexus.RootChain;
            var token     = nexus.FuelToken;

            Assert.IsTrue(token != null);
            Assert.IsTrue(token.CurrentSupply > 0);
            Assert.IsTrue(token.MaxSupply > 0);

            Assert.IsTrue(rootChain != null);
            Assert.IsTrue(rootChain.BlockHeight > 0);
            Assert.IsTrue(rootChain.ChildChains.Any());

            Assert.IsTrue(nexus.IsValidator(owner.Address));

            var randomKey = KeyPair.Generate();

            Assert.IsFalse(nexus.IsValidator(randomKey.Address));

            var txCount = nexus.GetTotalTransactionCount();

            Assert.IsTrue(txCount > 0);
        }
Exemplo n.º 3
0
        public static void Rescan(Nexus oldNexus, PhantasmaKeys owner, string[] args)
        {
            /*if (args.Length != 1)
             * {
             *  throw new CommandException("Expected args: file_path");
             * }*/

            var genesisAddress = oldNexus.GetGenesisAddress(oldNexus.RootStorage);

            if (owner.Address != genesisAddress)
            {
                throw new CommandException("Invalid owner key");
            }

            var oldGenesisBlock = oldNexus.GetGenesisBlock();

            var newNexus = new Nexus(oldNexus.Name);

            newNexus.CreateGenesisBlock(owner, oldGenesisBlock.Timestamp, DomainSettings.LatestKnownProtocol);

            var oldRootChain = oldNexus.RootChain;
            var newRootChain = newNexus.RootChain;

            var        height       = oldRootChain.Height;
            BigInteger minFee       = 0;
            Hash       previousHash = Hash.Null;

            for (int i = 1; i <= height; i++)
            {
                logger.Message($"Processing block {i} out of {height}");
                var oldBlockHash = oldRootChain.GetBlockHashAtHeight(i);
                var oldBlock     = oldRootChain.GetBlockByHash(oldBlockHash);

                var transactions = oldBlock.TransactionHashes.Select(x => oldRootChain.GetTransactionByHash(x));

                try
                {
                    var         newBlock    = new Block(oldBlock.Height, oldBlock.ChainAddress, oldBlock.Timestamp, oldBlock.TransactionHashes, previousHash, oldBlock.Protocol, owner.Address, oldBlock.Payload);
                    Transaction inflationTx = null;
                    var         changeSet   = newRootChain.ProcessBlock(newBlock, transactions, minFee, out inflationTx, null);
                    if (inflationTx != null)
                    {
                        transactions = transactions.Concat(new [] { inflationTx });
                    }
                    newBlock.Sign(owner);
                    newRootChain.AddBlock(newBlock, transactions, minFee, changeSet);
                }
                catch (Exception e)
                {
                    throw new CommandException("Block validation failed: " + e.Message);
                }
            }
        }
Exemplo n.º 4
0
        //public NexusSimulator(PhantasmaKeys ownerKey, int seed, Logger logger = null) : this(new Nexus("simnet", null, null), ownerKey, seed, logger)
        //{
        //    this.Nexus.SetOracleReader(new OracleSimulator(this.Nexus));
        //}

        public NexusSimulator(Nexus nexus, PhantasmaKeys ownerKey, int seed, Logger logger = null)
        {
            this.Logger = logger != null ? logger : new DummyLogger();

            _owner     = ownerKey;
            this.Nexus = nexus;

            CurrentTime = new DateTime(2018, 8, 26, 0, 0, 0, DateTimeKind.Utc);

            if (!Nexus.HasGenesis)
            {
                if (!Nexus.CreateGenesisBlock(_owner, CurrentTime, 4))
                {
                    throw new ChainException("Genesis block failure");
                }
            }
            else
            {
                var lastBlockHash = Nexus.RootChain.GetLastBlockHash();
                var lastBlock     = Nexus.RootChain.GetBlockByHash(lastBlockHash);
                CurrentTime = new Timestamp(lastBlock.Timestamp.Value + 1);
                DateTime.SpecifyKind(CurrentTime, DateTimeKind.Utc);
            }

            _rnd = new Random(seed);
            _keys.Add(_owner);

            var oneFuel      = UnitConversion.ToBigInteger(1, DomainSettings.FuelTokenDecimals);
            var token        = Nexus.GetTokenInfo(Nexus.RootStorage, DomainSettings.FuelTokenSymbol);
            var localBalance = Nexus.RootChain.GetTokenBalance(Nexus.RootStorage, token, _owner.Address);

            if (localBalance < oneFuel)
            {
                throw new Exception("Funds missing oops");
            }

            var neoPlatform = Pay.Chains.NeoWallet.NeoPlatform;
            var neoKeys     = InteropUtils.GenerateInteropKeys(_owner, Nexus.GetGenesisHash(Nexus.RootStorage), neoPlatform);
            var neoText     = Phantasma.Neo.Core.NeoKeys.FromWIF(neoKeys.ToWIF()).Address;
            var neoAddress  = Phantasma.Pay.Chains.NeoWallet.EncodeAddress(neoText);

            var ethPlatform = Pay.Chains.EthereumWallet.EthereumPlatform;
            var ethKeys     = InteropUtils.GenerateInteropKeys(_owner, Nexus.GetGenesisHash(Nexus.RootStorage), ethPlatform);
            var ethText     = Phantasma.Ethereum.EthereumKey.FromWIF(ethKeys.ToWIF()).Address;
            var ethAddress  = Phantasma.Pay.Chains.EthereumWallet.EncodeAddress(ethText);

            // only create all this stuff once
            if (!nexus.PlatformExists(nexus.RootStorage, neoPlatform))
            {
                /*BeginBlock();
                 * GenerateCustomTransaction(_owner, ProofOfWork.None, () =>
                 * {
                 *  return new ScriptBuilder().AllowGas(_owner.Address, Address.Null, 1, 99999).
                 *  CallContract(NativeContractKind.Governance, nameof(GovernanceContract.SetValue), Nexus.NexusProtocolVersionTag, 3).
                 *  SpendGas(_owner.Address).
                 *  EndScript();
                 * });
                 * EndBlock();*/

                BeginBlock();
                GenerateCustomTransaction(_owner, 0, () => new ScriptBuilder().AllowGas(_owner.Address, Address.Null, MinimumFee, 9999).
                                          CallInterop("Nexus.CreatePlatform", _owner.Address, neoPlatform, neoText, neoAddress, "GAS").
                                          CallInterop("Nexus.CreatePlatform", _owner.Address, ethPlatform, ethText, ethAddress, "ETH").
                                          SpendGas(_owner.Address).EndScript());

                var orgFunding = UnitConversion.ToBigInteger(1863626, DomainSettings.StakingTokenDecimals);
                var orgScript  = new byte[0];
                var orgID      = DomainSettings.PhantomForceOrganizationName;
                var orgAddress = Address.FromHash(orgID);

                GenerateCustomTransaction(_owner, ProofOfWork.None, () =>
                {
                    return(new ScriptBuilder().AllowGas(_owner.Address, Address.Null, 1, 99999).
                           CallInterop("Nexus.CreateOrganization", _owner.Address, orgID, "Phantom Force", orgScript).
                           CallInterop("Organization.AddMember", _owner.Address, orgID, _owner.Address).
                           TransferTokens(DomainSettings.StakingTokenSymbol, _owner.Address, orgAddress, orgFunding).
                           CallContract(NativeContractKind.Swap, nameof(SwapContract.SwapFee), orgAddress, DomainSettings.StakingTokenSymbol, 500000).
                           CallContract(NativeContractKind.Stake, nameof(StakeContract.Stake), orgAddress, orgFunding - (5000)).
                           SpendGas(_owner.Address).
                           EndScript());
                });
                EndBlock();

                BeginBlock();
                var communitySupply = 100000;
                GenerateToken(_owner, "MKNI", "Mankini Token", UnitConversion.ToBigInteger(communitySupply, 0), 0, TokenFlags.Fungible | TokenFlags.Transferable | TokenFlags.Finite);
                MintTokens(_owner, _owner.Address, "MKNI", communitySupply);
                EndBlock();

                //TODO add SOUL/KCAL on ethereum, removed for now because hash is not fixed yet
                //BeginBlock();
                //GenerateCustomTransaction(_owner, ProofOfWork.Minimal, () =>
                //{
                //    return new ScriptBuilder().AllowGas(_owner.Address, Address.Null, 1, 99999).
                //    CallInterop("Nexus.SetTokenPlatformHash", "SOUL", ethPlatform, Hash.FromUnpaddedHex("53d5bdb2c8797218f8a0e11e997c4ab84f0b40ce")). // eth ropsten testnet hash
                //    CallInterop("Nexus.SetTokenPlatformHash", "KCAL", ethPlatform, Hash.FromUnpaddedHex("67B132A32E7A3c4Ba7dEbedeFf6290351483008f")). // eth ropsten testnet hash
                //    SpendGas(_owner.Address).
                //    EndScript();
                //});
                //EndBlock();
            }

            /*
             * var market = Nexus.FindChainByName("market");
             * var nftSales = new List<KeyValuePair<KeyPair, BigInteger>>();
             *
             * BeginBlock();
             * for (int i = 1; i < 7; i++)
             * {
             *  BigInteger ID = i + 100;
             *  TokenContent info;
             *  try
             *  {
             *      info = Nexus.GetNFT(nachoSymbol, ID);
             *  }
             *  catch
             *  {
             *      continue;
             *  }
             *
             *  var chain = Nexus.FindChainByAddress(info.CurrentChain);
             *  if (chain == null)
             *  {
             *      continue;
             *  }
             *
             *  var nftOwner = chain.GetTokenOwner(nachoSymbol, ID);
             *
             *  if (nftOwner == Address.Null)
             *  {
             *      continue;
             *  }
             *
             *  foreach (var key in _keys)
             *  {
             *      if (key.Address == nftOwner)
             *      {
             *          nftSales.Add(new KeyValuePair<KeyPair, BigInteger>(key, ID));
             *          // send some gas to the sellers
             *          GenerateTransfer(_owner, key.Address, Nexus.RootChain, Nexus.FuelTokenSymbol, UnitConversion.ToBigInteger(0.01m, Nexus.FuelTokenDecimals));
             *      }
             *  }
             * }
             *
             * EndBlock();
             *
             * BeginBlock();
             * foreach (var sale in nftSales)
             * {
             *  // TODO this later should be the market chain instead of root
             *  GenerateNftSale(sale.Key, Nexus.RootChain, nachoSymbol, sale.Value, UnitConversion.ToBigInteger(100 + 5 * _rnd.Next() % 50, Nexus.FuelTokenDecimals));
             * }
             * EndBlock();
             */
        }
Exemplo n.º 5
0
        public NexusSimulator(Nexus nexus, PhantasmaKeys ownerKey, int seed, Logger logger = null)
        {
            this.Logger = logger != null ? logger : new DummyLogger();

            _owner = ownerKey;
            this.Nexus = nexus;

            CurrentTime = new DateTime(2018, 8, 26);

            if (!Nexus.HasGenesis)
            {
                if (!Nexus.CreateGenesisBlock("simnet", _owner, CurrentTime))
                {
                    throw new ChainException("Genesis block failure");
                }
            }
            else
            {
                var genesisBlock = Nexus.GetGenesisBlock();
                CurrentTime = new Timestamp(genesisBlock.Timestamp.Value + 1);
            }

            _rnd = new Random(seed);
            _keys.Add(_owner);

            var oneFuel = UnitConversion.ToBigInteger(1, DomainSettings.FuelTokenDecimals);
            var token = Nexus.GetTokenInfo(Nexus.RootStorage, DomainSettings.FuelTokenSymbol);
            var localBalance = Nexus.RootChain.GetTokenBalance(Nexus.RootStorage, token, _owner.Address);

            if (localBalance < oneFuel)
            {
                throw new Exception("Funds missing oops");
            }

            var neoPlatform = Pay.Chains.NeoWallet.NeoPlatform;
            var neoKeys = InteropUtils.GenerateInteropKeys(_owner, Nexus.GetGenesisHash(Nexus.RootStorage), neoPlatform);
            var neoText = Phantasma.Neo.Core.NeoKeys.FromWIF(neoKeys.ToWIF()).Address;
            var neoAddress = Phantasma.Pay.Chains.NeoWallet.EncodeAddress(neoText);

            var ethPlatform = Pay.Chains.EthereumWallet.EthereumPlatform;
            var ethKeys = InteropUtils.GenerateInteropKeys(_owner, Nexus.GetGenesisHash(Nexus.RootStorage), ethPlatform);
            var ethText = Phantasma.Ethereum.EthereumKey.FromWIF(ethKeys.ToWIF()).Address;
            var ethAddress = Phantasma.Pay.Chains.EthereumWallet.EncodeAddress(ethText);

            BeginBlock();
            
            GenerateCustomTransaction(_owner, 0, () => new ScriptBuilder().AllowGas(_owner.Address, Address.Null, MinimumFee, 9999).
                CallInterop("Nexus.CreatePlatform", _owner.Address, neoPlatform, neoText, neoAddress, "GAS").
                CallInterop("Nexus.CreatePlatform", _owner.Address, ethPlatform, ethText, ethAddress, "ETH").
            SpendGas(_owner.Address).EndScript());

            var orgFunding = UnitConversion.ToBigInteger(1863626, DomainSettings.StakingTokenDecimals);
            var orgScript = new byte[0];
            var orgID = DomainSettings.PhantomForceOrganizationName;
            var orgAddress = Address.FromHash(orgID);
            GenerateCustomTransaction(_owner, ProofOfWork.None, () =>
            {
                return new ScriptBuilder().AllowGas(_owner.Address, Address.Null, 1, 99999).
                CallInterop("Nexus.CreateOrganization", _owner.Address, orgID, "Phantom Force", orgScript).
                CallInterop("Organization.AddMember", _owner.Address, orgID, _owner.Address).
                TransferTokens(DomainSettings.StakingTokenSymbol, _owner.Address, orgAddress, orgFunding).
                CallContract("swap", "SwapFee", orgAddress, DomainSettings.StakingTokenSymbol, 50000).
                CallContract("stake", "Stake", orgAddress, orgFunding - (5000)).
                SpendGas(_owner.Address).
                EndScript();
            });
            EndBlock();

            BeginBlock();
            var communitySupply = 100000;
            GenerateToken(_owner, "MKNI", "Mankini Token", UnitConversion.ToBigInteger(communitySupply, 0), 0, TokenFlags.Fungible | TokenFlags.Transferable | TokenFlags.Finite);
            MintTokens(_owner, _owner.Address, "MKNI", communitySupply);
            EndBlock();

            /*
            var market = Nexus.FindChainByName("market");
            var nftSales = new List<KeyValuePair<KeyPair, BigInteger>>();

            BeginBlock();
            for (int i = 1; i < 7; i++)
            {
                BigInteger ID = i + 100;
                TokenContent info;
                try
                {
                    info = Nexus.GetNFT(nachoSymbol, ID);
                }
                catch  
                {
                    continue;
                }

                var chain = Nexus.FindChainByAddress(info.CurrentChain);
                if (chain == null)
                {
                    continue;
                }

                var nftOwner = chain.GetTokenOwner(nachoSymbol, ID);

                if (nftOwner == Address.Null)
                {
                    continue;
                }

                foreach (var key in _keys)
                {
                    if (key.Address == nftOwner)
                    {
                        nftSales.Add(new KeyValuePair<KeyPair, BigInteger>(key, ID));
                        // send some gas to the sellers
                        GenerateTransfer(_owner, key.Address, Nexus.RootChain, Nexus.FuelTokenSymbol, UnitConversion.ToBigInteger(0.01m, Nexus.FuelTokenDecimals));
                    }
                }
            }

            EndBlock();

            BeginBlock();
            foreach (var sale in nftSales)
            {
                // TODO this later should be the market chain instead of root
                GenerateNftSale(sale.Key, Nexus.RootChain, nachoSymbol, sale.Value, UnitConversion.ToBigInteger(100 + 5 * _rnd.Next() % 50, Nexus.FuelTokenDecimals));
            }
            EndBlock();
            */
        }
Exemplo n.º 6
0
        public ChainSimulator(KeyPair ownerKey, int seed, Logger logger = null)
        {
            this.Logger = logger != null ? logger : new DummyLogger();

            _owner     = ownerKey;
            this.Nexus = new Nexus();

            CurrentTime = new DateTime(2018, 8, 26);

            if (!Nexus.CreateGenesisBlock("simnet", _owner, CurrentTime))
            {
                throw new ChainException("Genesis block failure");
            }

            this.bankChain = Nexus.FindChainByName("bank");

            _rnd = new System.Random(seed);
            _keys.Add(_owner);

            var oneFuel      = UnitConversion.ToBigInteger(1, Nexus.FuelTokenDecimals);
            var localBalance = Nexus.RootChain.GetTokenBalance(Nexus.FuelTokenSymbol, _owner.Address);

            if (localBalance < oneFuel)
            {
                throw new Exception("Funds missing oops");
            }

            var nachoAddress = Address.FromText("PGasVpbFYdu7qERihCsR22nTDQp1JwVAjfuJ38T8NtrCB");
            var nachoFuel    = UnitConversion.ToBigInteger(5, Nexus.FuelTokenDecimals);
            var nachoChain   = Nexus.FindChainByName("nacho");

            var appsChain = Nexus.FindChainByName("apps");

            BeginBlock();
            GenerateSideChainSend(_owner, Nexus.FuelTokenSymbol, Nexus.RootChain, _owner.Address, appsChain, oneFuel, 0);
            GenerateSideChainSend(_owner, Nexus.FuelTokenSymbol, Nexus.RootChain, nachoAddress, nachoChain, nachoFuel, 9999);
            GenerateSideChainSend(_owner, Nexus.FuelTokenSymbol, Nexus.RootChain, Address.FromText("P27j1vgY1cjVYPnPDqjAVvqtxMmK9qjYvqz99EFp8vrPQ"), nachoChain, nachoFuel, 9999);
            var blockTx = EndBlock().First();

            BeginBlock();
            GenerateSideChainSettlement(_owner, Nexus.RootChain, appsChain, blockTx.Hash);
            GenerateSideChainSettlement(_owner, Nexus.RootChain, nachoChain, blockTx.Hash);
            EndBlock();

            BeginBlock();
            GenerateChain(_owner, Nexus.RootChain, "dex");
            GenerateChain(_owner, Nexus.RootChain, "market");
            EndBlock();

            BeginBlock();
            GenerateAppRegistration(_owner, "nachomen", "https://nacho.men", "Collect, train and battle against other players in Nacho Men!");
            GenerateAppRegistration(_owner, "mystore", "https://my.store", "The future of digital content distribution!");
            GenerateAppRegistration(_owner, "nftbazar", "https://nft.bazar", "A decentralized NFT market");

            GenerateToken(_owner, Constants.NACHO_SYMBOL, "Nachomen", 0, 0, TokenFlags.Transferable);
            GenerateToken(_owner, Constants.WRESTLER_SYMBOL, "Nachomen Luchador", 0, 0, TokenFlags.Transferable);
            GenerateToken(_owner, Constants.ITEM_SYMBOL, "Nachomen Item", 0, 0, TokenFlags.Transferable);
            EndBlock();

            var market = Nexus.FindChainByName("market");

            BeginBlock();

            var nachoSymbol = "NACHO";

            RandomSpreadNFT(nachoSymbol, 150);

            GenerateSetTokenMetadata(_owner, nachoSymbol, "details", "https://nacho.men/luchador/*");
            GenerateSetTokenMetadata(_owner, nachoSymbol, "viewer", "https://nacho.men/luchador/body/*");
            EndBlock();

            var nftSales = new List <KeyValuePair <KeyPair, BigInteger> >();

            BeginBlock();
            for (int i = 1; i < 7; i++)
            {
                BigInteger   ID = i + 100;
                TokenContent info;
                try
                {
                    info = Nexus.GetNFT(nachoSymbol, ID);
                }
                catch
                {
                    continue;
                }

                var chain = Nexus.FindChainByAddress(info.CurrentChain);
                if (chain == null)
                {
                    continue;
                }

                var nftOwner = chain.GetTokenOwner(nachoSymbol, ID);

                if (nftOwner == Address.Null)
                {
                    continue;
                }

                foreach (var key in _keys)
                {
                    if (key.Address == nftOwner)
                    {
                        nftSales.Add(new KeyValuePair <KeyPair, BigInteger>(key, ID));
                        // send some gas to the sellers
                        GenerateTransfer(_owner, key.Address, Nexus.RootChain, Nexus.FuelTokenSymbol, UnitConversion.ToBigInteger(0.01m, Nexus.FuelTokenDecimals));
                    }
                }
            }

            EndBlock();

            BeginBlock();
            foreach (var sale in nftSales)
            {
                // TODO this later should be the market chain instead of root
                GenerateNftSale(sale.Key, Nexus.RootChain, nachoSymbol, sale.Value, UnitConversion.ToBigInteger(100 + 5 * _rnd.Next() % 50, Nexus.FuelTokenDecimals));
            }
            EndBlock();

            BeginBlock();

            var newWrestler = new NachoWrestler()
            {
                auctionID          = 0,
                battleCount        = 0,
                comments           = new string[0],
                currentMojo        = 10,
                experience         = 10000,
                flags              = WrestlerFlags.None,
                genes              = new byte[] { 115, 169, 73, 21, 111, 3, 174, 90, 137, 58 }, //"Piece, 115, 169, 73, 21, 111, 3, 174, 90, 137, 58"
                gymBoostAtk        = byte.MaxValue,
                gymBoostDef        = byte.MaxValue,
                gymBoostStamina    = byte.MaxValue,
                gymTime            = 0,
                itemID             = 0,
                location           = WrestlerLocation.None,
                maskOverrideCheck  = byte.MaxValue,
                maskOverrideID     = byte.MaxValue,
                maskOverrideRarity = byte.MaxValue,
                maxMojo            = 10,
                mojoTime           = 0,
                moveOverrides      = new byte[0],
                nickname           = "testname",
                owner              = nachoAddress,
                perfumeTime        = 0,
                praticeLevel       = PraticeLevel.Gold,
                roomTime           = 0,
                score              = 0,
                stakeAmount        = 0,
                trainingStat       = StatKind.None,
                ua1 = byte.MaxValue,
                ua2 = byte.MaxValue,
                ua3 = byte.MaxValue,
                us1 = byte.MaxValue,
                us2 = byte.MaxValue,
                us3 = byte.MaxValue
            };

            var wrestlerBytes = newWrestler.Serialize();

            GenerateNft(_owner, nachoAddress, nachoSymbol, new byte[0], wrestlerBytes);

            EndBlock();
        }
Exemplo n.º 7
0
        public ChainSimulator(Nexus nexus, KeyPair ownerKey, int seed, Logger logger = null)
        {
            this.Logger = logger != null ? logger : new DummyLogger();

            _owner     = ownerKey;
            this.Nexus = nexus;

            CurrentTime = new DateTime(2018, 8, 26);

            if (!Nexus.Ready)
            {
                if (!Nexus.CreateGenesisBlock("simnet", _owner, CurrentTime))
                {
                    throw new ChainException("Genesis block failure");
                }
            }

            this.bankChain = Nexus.FindChainByName("bank");

            _rnd = new Random(seed);
            _keys.Add(_owner);

            var oneFuel      = UnitConversion.ToBigInteger(1, Nexus.FuelTokenDecimals);
            var localBalance = Nexus.RootChain.GetTokenBalance(Nexus.FuelTokenSymbol, _owner.Address);

            if (localBalance < oneFuel)
            {
                throw new Exception("Funds missing oops");
            }

            BeginBlock();
            GenerateAppRegistration(_owner, "mystore", "https://my.store", "The future of digital content distribution!");
            EndBlock();

            /*
             * var market = Nexus.FindChainByName("market");
             * var nftSales = new List<KeyValuePair<KeyPair, BigInteger>>();
             *
             * BeginBlock();
             * for (int i = 1; i < 7; i++)
             * {
             *  BigInteger ID = i + 100;
             *  TokenContent info;
             *  try
             *  {
             *      info = Nexus.GetNFT(nachoSymbol, ID);
             *  }
             *  catch
             *  {
             *      continue;
             *  }
             *
             *  var chain = Nexus.FindChainByAddress(info.CurrentChain);
             *  if (chain == null)
             *  {
             *      continue;
             *  }
             *
             *  var nftOwner = chain.GetTokenOwner(nachoSymbol, ID);
             *
             *  if (nftOwner == Address.Null)
             *  {
             *      continue;
             *  }
             *
             *  foreach (var key in _keys)
             *  {
             *      if (key.Address == nftOwner)
             *      {
             *          nftSales.Add(new KeyValuePair<KeyPair, BigInteger>(key, ID));
             *          // send some gas to the sellers
             *          GenerateTransfer(_owner, key.Address, Nexus.RootChain, Nexus.FuelTokenSymbol, UnitConversion.ToBigInteger(0.01m, Nexus.FuelTokenDecimals));
             *      }
             *  }
             * }
             *
             * EndBlock();
             *
             * BeginBlock();
             * foreach (var sale in nftSales)
             * {
             *  // TODO this later should be the market chain instead of root
             *  GenerateNftSale(sale.Key, Nexus.RootChain, nachoSymbol, sale.Value, UnitConversion.ToBigInteger(100 + 5 * _rnd.Next() % 50, Nexus.FuelTokenDecimals));
             * }
             * EndBlock();
             */
        }
Exemplo n.º 8
0
        public NexusSimulator(Nexus nexus, KeyPair ownerKey, int seed, Logger logger = null)
        {
            this.Logger = logger != null ? logger : new DummyLogger();

            _owner     = ownerKey;
            this.Nexus = nexus;

            CurrentTime = new DateTime(2018, 8, 26);

            if (!Nexus.HasGenesis)
            {
                if (!Nexus.CreateGenesisBlock("simnet", _owner, CurrentTime))
                {
                    throw new ChainException("Genesis block failure");
                }
            }

            this.bankChain = Nexus.FindChainByName("bank");

            _rnd = new Random(seed);
            _keys.Add(_owner);

            var oneFuel      = UnitConversion.ToBigInteger(1, Nexus.FuelTokenDecimals);
            var localBalance = Nexus.RootChain.GetTokenBalance(Nexus.FuelTokenSymbol, _owner.Address);

            if (localBalance < oneFuel)
            {
                throw new Exception("Funds missing oops");
            }

            var neoPlatform = Pay.Chains.NeoWallet.NeoPlatform;
            var neoKeys     = InteropUtils.GenerateInteropKeys(_owner, neoPlatform);
            var neoText     = Phantasma.Neo.Core.NeoKey.FromWIF(neoKeys.ToWIF()).address;
            var neoAddress  = Phantasma.Pay.Chains.NeoWallet.EncodeAddress(neoText);

            var ethPlatform = Pay.Chains.EthereumWallet.EthereumPlatform;
            var ethKeys     = InteropUtils.GenerateInteropKeys(_owner, ethPlatform);
            var ethText     = Phantasma.Ethereum.EthereumKey.FromWIF(ethKeys.ToWIF()).address;
            var ethAddress  = Phantasma.Pay.Chains.EthereumWallet.EncodeAddress(ethText);

            BeginBlock();
            GenerateAppRegistration(_owner, "mystore", "https://my.store", "The future of digital content distribution!");

            GenerateCustomTransaction(_owner, 0, () => new ScriptBuilder().AllowGas(_owner.Address, Address.Null, MinimumFee, 9999).
                                      CallContract("nexus", "CreatePlatform", neoAddress, "GAS").
                                      CallContract("nexus", "CreatePlatform", ethAddress, "ETH").
                                      SpendGas(_owner.Address).EndScript());

            GenerateToken(_owner, "NEO", "NEO", neoPlatform, Hash.FromUnpaddedHex("c56f33fc6ecfcd0c225c4ab356fee59390af8560be0e930faebe74a6daff7c9b"), UnitConversion.ToBigInteger(100000000, 0), 0, TokenFlags.Fungible | TokenFlags.Transferable | TokenFlags.Finite | TokenFlags.External);
            GenerateToken(_owner, "GAS", "GAS", neoPlatform, Hash.FromUnpaddedHex("602c79718b16e442de58778e148d0b1084e3b2dffd5de6b7b16cee7969282de7"), UnitConversion.ToBigInteger(100000000, 8), 8, TokenFlags.Fungible | TokenFlags.Transferable | TokenFlags.Divisible | TokenFlags.Finite | TokenFlags.External);
            GenerateToken(_owner, "ETH", "Ethereum", ethPlatform, Hash.FromString("ETH"), UnitConversion.ToBigInteger(0, 18), 18, TokenFlags.Fungible | TokenFlags.Transferable | TokenFlags.Divisible | TokenFlags.External);
            GenerateToken(_owner, "DAI", "Dai Stablecoin", ethPlatform, Hash.FromUnpaddedHex("89d24a6b4ccb1b6faa2625fe562bdd9a23260359"), UnitConversion.ToBigInteger(0, 18), 18, TokenFlags.Fungible | TokenFlags.Transferable | TokenFlags.Divisible | TokenFlags.External);
            //GenerateToken(_owner, "EOS", "EOS", "EOS", UnitConversion.ToBigInteger(1006245120, 18), 18, TokenFlags.Fungible | TokenFlags.Transferable | TokenFlags.Finite | TokenFlags.Divisible | TokenFlags.External);

            EndBlock();

            /*
             * var market = Nexus.FindChainByName("market");
             * var nftSales = new List<KeyValuePair<KeyPair, BigInteger>>();
             *
             * BeginBlock();
             * for (int i = 1; i < 7; i++)
             * {
             *  BigInteger ID = i + 100;
             *  TokenContent info;
             *  try
             *  {
             *      info = Nexus.GetNFT(nachoSymbol, ID);
             *  }
             *  catch
             *  {
             *      continue;
             *  }
             *
             *  var chain = Nexus.FindChainByAddress(info.CurrentChain);
             *  if (chain == null)
             *  {
             *      continue;
             *  }
             *
             *  var nftOwner = chain.GetTokenOwner(nachoSymbol, ID);
             *
             *  if (nftOwner == Address.Null)
             *  {
             *      continue;
             *  }
             *
             *  foreach (var key in _keys)
             *  {
             *      if (key.Address == nftOwner)
             *      {
             *          nftSales.Add(new KeyValuePair<KeyPair, BigInteger>(key, ID));
             *          // send some gas to the sellers
             *          GenerateTransfer(_owner, key.Address, Nexus.RootChain, Nexus.FuelTokenSymbol, UnitConversion.ToBigInteger(0.01m, Nexus.FuelTokenDecimals));
             *      }
             *  }
             * }
             *
             * EndBlock();
             *
             * BeginBlock();
             * foreach (var sale in nftSales)
             * {
             *  // TODO this later should be the market chain instead of root
             *  GenerateNftSale(sale.Key, Nexus.RootChain, nachoSymbol, sale.Value, UnitConversion.ToBigInteger(100 + 5 * _rnd.Next() % 50, Nexus.FuelTokenDecimals));
             * }
             * EndBlock();
             */
        }
Exemplo n.º 9
0
        public NexusSimulator(Nexus nexus, PhantasmaKeys ownerKey, int seed, Logger logger = null)
        {
            this.Logger = logger != null ? logger : new DummyLogger();

            _owner     = ownerKey;
            this.Nexus = nexus;

            CurrentTime = new DateTime(2018, 8, 26);

            if (!Nexus.HasGenesis)
            {
                if (!Nexus.CreateGenesisBlock("simnet", _owner, CurrentTime))
                {
                    throw new ChainException("Genesis block failure");
                }
            }
            else
            {
                var genesisBlock = Nexus.GetGenesisBlock();
                CurrentTime = new Timestamp(genesisBlock.Timestamp.Value + 1);
            }

            _rnd = new Random(seed);
            _keys.Add(_owner);

            var oneFuel      = UnitConversion.ToBigInteger(1, DomainSettings.FuelTokenDecimals);
            var token        = Nexus.GetTokenInfo(Nexus.RootStorage, DomainSettings.FuelTokenSymbol);
            var localBalance = Nexus.RootChain.GetTokenBalance(Nexus.RootStorage, token, _owner.Address);

            if (localBalance < oneFuel)
            {
                throw new Exception("Funds missing oops");
            }

            var neoPlatform = Pay.Chains.NeoWallet.NeoPlatform;
            var neoKeys     = InteropUtils.GenerateInteropKeys(_owner, Nexus.GetGenesisHash(Nexus.RootStorage), neoPlatform);
            var neoText     = Phantasma.Neo.Core.NeoKeys.FromWIF(neoKeys.ToWIF()).Address;
            var neoAddress  = Phantasma.Pay.Chains.NeoWallet.EncodeAddress(neoText);

            /*
             * var ethPlatform = Pay.Chains.EthereumWallet.EthereumPlatform;
             * var ethKeys = InteropUtils.GenerateInteropKeys(_owner, ethPlatform);
             * var ethText = Phantasma.Ethereum.EthereumKey.FromWIF(ethKeys.ToWIF()).address;
             * var ethAddress = Phantasma.Pay.Chains.EthereumWallet.EncodeAddress(ethText);
             */

            BeginBlock();

            GenerateCustomTransaction(_owner, 0, () => new ScriptBuilder().AllowGas(_owner.Address, Address.Null, MinimumFee, 9999).
                                      CallInterop("Nexus.CreatePlatform", _owner.Address, neoPlatform, neoText, neoAddress, "GAS").
                                      //CallInterop("Nexus.CreatePlatform", _owner.Address, ethKeys.PublicKey, ethPlatform, "ETH").
                                      SpendGas(_owner.Address).EndScript());

            GenerateToken(_owner, "NEO", "NEO", neoPlatform, Hash.FromUnpaddedHex("c56f33fc6ecfcd0c225c4ab356fee59390af8560be0e930faebe74a6daff7c9b"), UnitConversion.ToBigInteger(100000000, 0), 0, TokenFlags.Fungible | TokenFlags.Transferable | TokenFlags.Finite | TokenFlags.External);
            GenerateToken(_owner, "GAS", "GAS", neoPlatform, Hash.FromUnpaddedHex("602c79718b16e442de58778e148d0b1084e3b2dffd5de6b7b16cee7969282de7"), UnitConversion.ToBigInteger(100000000, 8), 8, TokenFlags.Fungible | TokenFlags.Transferable | TokenFlags.Divisible | TokenFlags.Finite | TokenFlags.External);
            //GenerateToken(_owner, "ETH", "Ethereum", ethPlatform, Hash.FromString("ETH"), UnitConversion.ToBigInteger(0, 18), 18, TokenFlags.Fungible | TokenFlags.Transferable | TokenFlags.Divisible | TokenFlags.External);
            //GenerateToken(_owner, "DAI", "Dai Stablecoin", ethPlatform, Hash.FromUnpaddedHex("89d24a6b4ccb1b6faa2625fe562bdd9a23260359"), UnitConversion.ToBigInteger(0, 18), 18, TokenFlags.Fungible | TokenFlags.Transferable | TokenFlags.Divisible | TokenFlags.External);
            //GenerateToken(_owner, "EOS", "EOS", "EOS", UnitConversion.ToBigInteger(1006245120, 18), 18, TokenFlags.Fungible | TokenFlags.Transferable | TokenFlags.Finite | TokenFlags.Divisible | TokenFlags.External);

            var orgFunding = UnitConversion.ToBigInteger(1863626, DomainSettings.StakingTokenDecimals);
            var orgScript  = new byte[0];
            var orgID      = DomainSettings.PhantomForceOrganizationName;
            var orgAddress = Address.FromHash(orgID);

            GenerateCustomTransaction(_owner, ProofOfWork.None, () =>
            {
                return(new ScriptBuilder().AllowGas(_owner.Address, Address.Null, 1, 99999).
                       CallInterop("Nexus.CreateOrganization", _owner.Address, orgID, "Phantom Force", orgScript).
                       CallInterop("Organization.AddMember", _owner.Address, orgID, _owner.Address).
                       TransferTokens(DomainSettings.StakingTokenSymbol, _owner.Address, orgAddress, orgFunding).
                       CallContract("swap", "SwapFee", orgAddress, DomainSettings.StakingTokenSymbol, 50000).
                       CallContract("stake", "Stake", orgAddress, orgFunding - (5000)).
                       SpendGas(_owner.Address).
                       EndScript());
            });

            var communitySupply = 100000;

            GenerateToken(_owner, "MKNI", "Mankini Token", DomainSettings.PlatformName, Hash.FromString("MKNI"), UnitConversion.ToBigInteger(communitySupply, 0), 0, TokenFlags.Fungible | TokenFlags.Transferable | TokenFlags.Finite);
            MintTokens(_owner, _owner.Address, "MKNI", communitySupply);
            EndBlock();

            /*
             * var market = Nexus.FindChainByName("market");
             * var nftSales = new List<KeyValuePair<KeyPair, BigInteger>>();
             *
             * BeginBlock();
             * for (int i = 1; i < 7; i++)
             * {
             *  BigInteger ID = i + 100;
             *  TokenContent info;
             *  try
             *  {
             *      info = Nexus.GetNFT(nachoSymbol, ID);
             *  }
             *  catch
             *  {
             *      continue;
             *  }
             *
             *  var chain = Nexus.FindChainByAddress(info.CurrentChain);
             *  if (chain == null)
             *  {
             *      continue;
             *  }
             *
             *  var nftOwner = chain.GetTokenOwner(nachoSymbol, ID);
             *
             *  if (nftOwner == Address.Null)
             *  {
             *      continue;
             *  }
             *
             *  foreach (var key in _keys)
             *  {
             *      if (key.Address == nftOwner)
             *      {
             *          nftSales.Add(new KeyValuePair<KeyPair, BigInteger>(key, ID));
             *          // send some gas to the sellers
             *          GenerateTransfer(_owner, key.Address, Nexus.RootChain, Nexus.FuelTokenSymbol, UnitConversion.ToBigInteger(0.01m, Nexus.FuelTokenDecimals));
             *      }
             *  }
             * }
             *
             * EndBlock();
             *
             * BeginBlock();
             * foreach (var sale in nftSales)
             * {
             *  // TODO this later should be the market chain instead of root
             *  GenerateNftSale(sale.Key, Nexus.RootChain, nachoSymbol, sale.Value, UnitConversion.ToBigInteger(100 + 5 * _rnd.Next() % 50, Nexus.FuelTokenDecimals));
             * }
             * EndBlock();
             */
        }
Exemplo n.º 10
0
        public CLI(string[] args)
        {
            var culture = new CultureInfo("en-US");

            Thread.CurrentThread.CurrentCulture     = culture;
            CultureInfo.DefaultThreadCurrentCulture = culture;

            var seeds = new List <string>();

            var settings = new Arguments(args);

            var useGUI = settings.GetBool("gui.enabled", true);

            if (useGUI)
            {
                gui    = new ConsoleGUI();
                logger = gui;
            }
            else
            {
                gui    = null;
                logger = new ConsoleLogger();
            }

            string mode = settings.GetString("node.mode", "default");

            restartTime = settings.GetInt("node.reboot", 0);

            showWebLogs = settings.GetBool("web.log", false);
            bool apiLog = settings.GetBool("api.log", true);

            string apiProxyURL = settings.GetString("api.proxy", "");

            if (string.IsNullOrEmpty(apiProxyURL))
            {
                apiProxyURL = null;
            }

            bool hasSync    = settings.GetBool("sync.enabled", true);
            bool hasMempool = settings.GetBool("mempool.enabled", true);
            bool hasEvents  = settings.GetBool("events.enabled", true);
            bool hasRelay   = settings.GetBool("relay.enabled", true);
            bool hasArchive = settings.GetBool("archive.enabled", true);
            bool hasRPC     = settings.GetBool("rpc.enabled", false);
            bool hasREST    = settings.GetBool("rest.enabled", false);

            var nexusName = settings.GetString("nexus.name", "simnet");

            string profilePath = settings.GetString("mempool.profile", "");

            if (string.IsNullOrEmpty(profilePath))
            {
                profilePath = null;
            }

            bool isValidator = false;

            switch (mode)
            {
            case "sender":
            {
                string host               = settings.GetString("sender.host");
                int    threadCount        = settings.GetInt("sender.threads", 8);
                int    addressesPerSender = settings.GetInt("sender.addressCount", 100);

                string wif = settings.GetString("node.wif");
                RunSender(wif, nexusName, host, threadCount, addressesPerSender);
                Console.WriteLine("Sender finished operations.");
                return;
            }

            case "validator": isValidator = true; break;

            case "default": break;

            default:
            {
                logger.Error("Unknown mode: " + mode);
                return;
            }
            }

            int port = settings.GetInt("node.port", 7073);
            var defaultStoragePath = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location) + "/Storage";
            var defaultOraclePath  = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location) + "/Oracle";
            var storagePath        = FixPath(settings.GetString("storage.path", defaultStoragePath));
            var oraclePath         = FixPath(settings.GetString("storage.oracle", defaultOraclePath));
            var storageBackend     = settings.GetString("storage.backend", "file");

            logger.Message("Storage backend: " + storageBackend);

            var storageFix = settings.GetBool("storage.fix", false);

            // TODO remove this later
            if (storageFix)
            {
                if (Directory.Exists(storagePath))
                {
                    logger.Warning("Storage fix enabled... Cleaning up all storage...");
                    var di = new DirectoryInfo(storagePath);
                    foreach (FileInfo file in di.EnumerateFiles())
                    {
                        file.Delete();
                    }
                }
            }

            logger.Message("Storage path: " + storagePath);
            logger.Message("Oracle path: " + oraclePath);

            switch (storageBackend)
            {
            case "file":
                nexus = new Nexus(logger,
                                  (name) => new BasicDiskStore(storagePath + name + ".csv"),
                                  (n) => new SpookOracle(this, n, oraclePath)
                                  );
                break;

            case "db":
                nexus = new Nexus(logger,
                                  (name) => new DBPartition(storagePath + name),
                                  (n) => new SpookOracle(this, n, oraclePath)
                                  );
                break;

            default:
                throw new Exception("Backend has to be set to either \"db\" or \"file\"");
            }


            running = true;

            // mempool setup
            int blockTime = settings.GetInt("node.blocktime", Mempool.MinimumBlockTime);

            int minimumFee;

            try
            {
                minimumFee = settings.GetInt("mempool.fee", 100000);
                if (minimumFee < 1)
                {
                    logger.Error("Invalid mempool fee value. Expected a positive value.");
                }
            }
            catch (Exception e)
            {
                logger.Error("Invalid mempool fee value. Expected something in fixed point format.");
                return;
            }

            int minimumPow;

            try
            {
                minimumPow = settings.GetInt("mempool.pow", 0);
                int maxPow = 5;
                if (minimumPow < 0 || minimumPow > maxPow)
                {
                    logger.Error($"Invalid mempool pow value. Expected a value between 0 and {maxPow}.");
                }
            }
            catch (Exception e)
            {
                logger.Error("Invalid mempool fee value. Expected something in fixed point format.");
                return;
            }

            if (apiProxyURL != null)
            {
                hasMempool  = false;
                isValidator = false;
                hasSync     = false;
                hasEvents   = false;
                hasRelay    = false;
                hasArchive  = false;

                if (!hasRPC && !hasREST)
                {
                    logger.Error("API proxy must have REST or RPC enabled.");
                    return;
                }
            }

            if (hasMempool)
            {
                this.mempool = new Mempool(nexus, blockTime, minimumFee, System.Text.Encoding.UTF8.GetBytes(Identifier), 0, logger, profilePath);

                var mempoolLogging = settings.GetBool("mempool.log", true);
                if (mempoolLogging)
                {
                    mempool.OnTransactionFailed    += Mempool_OnTransactionFailed;
                    mempool.OnTransactionAdded     += (hash) => logger.Message($"Received transaction {hash}");
                    mempool.OnTransactionCommitted += (hash) => logger.Message($"Commited transaction {hash}");
                    mempool.OnTransactionDiscarded += (hash) => logger.Message($"Discarded transaction {hash}");
                }

                mempool.Start(ThreadPriority.AboveNormal);
            }
            else
            {
                this.mempool = null;
            }

            if (!isValidator && !hasSync && apiProxyURL == null)
            {
                logger.Warning("Non-validator nodes require sync feature to be enabled, auto enabled now");
                hasSync = true;
            }

            PeerCaps caps = PeerCaps.None;

            if (hasSync)
            {
                caps |= PeerCaps.Sync;
            }
            if (hasMempool)
            {
                caps |= PeerCaps.Mempool;
            }
            if (hasEvents)
            {
                caps |= PeerCaps.Events;
            }
            if (hasRelay)
            {
                caps |= PeerCaps.Relay;
            }
            if (hasArchive)
            {
                caps |= PeerCaps.Archive;
            }
            if (hasRPC)
            {
                caps |= PeerCaps.RPC;
            }
            if (hasREST)
            {
                caps |= PeerCaps.REST;
            }

            var possibleCaps = Enum.GetValues(typeof(PeerCaps)).Cast <PeerCaps>().ToArray();

            foreach (var cap in possibleCaps)
            {
                if (cap != PeerCaps.None && caps.HasFlag(cap))
                {
                    logger.Message("Feature enabled: " + cap);
                }
            }

            PhantasmaKeys node_keys = null;
            bool          bootstrap = false;

            if (hasSync)
            {
                string wif = settings.GetString("node.wif");
                node_keys         = PhantasmaKeys.FromWIF(wif);
                WalletModule.Keys = PhantasmaKeys.FromWIF(wif);

                try
                {
                    if (this.mempool != null)
                    {
                        this.mempool.SetKeys(node_keys);
                    }
                    this.node = new Node("Spook v" + SpookVersion, nexus, mempool, node_keys, port, caps, seeds, logger);
                }
                catch (Exception e)
                {
                    logger.Error(e.Message);
                    return;
                }

                if (!nexus.HasGenesis)
                {
                    if (isValidator)
                    {
                        if (settings.GetBool("nexus.bootstrap"))
                        {
                            if (!ValidationUtils.IsValidIdentifier(nexusName))
                            {
                                logger.Error("Invalid nexus name: " + nexusName);
                                this.Terminate();
                                return;
                            }

                            logger.Debug($"Boostraping {nexusName} nexus using {node_keys.Address}...");

                            var genesisTimestamp = new Timestamp(settings.GetUInt("genesis.timestamp", Timestamp.Now.Value));

                            bootstrap = true;
                            if (!nexus.CreateGenesisBlock(nexusName, node_keys, genesisTimestamp))
                            {
                                throw new ChainException("Genesis block failure");
                            }

                            logger.Debug("Genesis block created: " + nexus.GetGenesisHash(nexus.RootStorage));
                        }
                        else
                        {
                            logger.Error("No Nexus found.");
                            this.Terminate();
                        }
                    }
                }
                else
                {
                    var genesisAddress = nexus.GetGenesisAddress(nexus.RootStorage);
                    if (isValidator && node_keys.Address != genesisAddress)
                    {
                        logger.Error("Specified node key does not match genesis address " + genesisAddress.Text);
                        return;
                    }
                    else
                    {
                        logger.Success("Loaded Nexus with genesis " + nexus.GetGenesisHash(nexus.RootStorage));
                        //seeds.Add("127.0.0.1:7073");
                    }
                }
            }
            else
            {
                this.node = null;
            }

            if (mempool != null)
            {
                if (isValidator)
                {
                    this.mempool.SetKeys(node_keys);
                }
                else
                {
                    this.mempool.SubmissionCallback = (tx, chain) =>
                    {
                        logger.Message($"Relaying tx {tx.Hash} to other node");
                        //this.node.
                    };
                }
            }

            var useAPICache = settings.GetBool("api.cache", true);

            if (apiProxyURL != null)
            {
                useAPICache = true;
            }

            logger.Message($"API cache is {(useAPICache ? "enabled" : "disabled")}.");
            nexusApi         = new NexusAPI(nexus, useAPICache, apiLog ? logger : null);
            nexusApi.Mempool = mempool;

            if (!string.IsNullOrEmpty(apiProxyURL))
            {
                nexusApi.ProxyURL = apiProxyURL;
                logger.Message($"API will be acting as proxy for {apiProxyURL}");
            }
            else
            {
                nexusApi.Node = node;
            }

            var readOnlyMode = settings.GetBool("readonly", false);

            if (apiProxyURL != null)
            {
                readOnlyMode = true;
            }

            if (readOnlyMode)
            {
                logger.Warning($"Node will be running in read-only mode.");
                nexusApi.acceptTransactions = false;
            }

            // RPC setup
            if (hasRPC)
            {
                rpcPort = settings.GetInt("rpc.port", 7077);
                logger.Message($"RPC server listening on port {rpcPort}...");
                var rpcServer = new RPCServer(nexusApi, "/rpc", rpcPort, (level, text) => WebLogMapper("rpc", level, text));
                rpcServer.Start(ThreadPriority.AboveNormal);
            }
            else
            {
                rpcPort = 0;
            }

            // REST setup
            if (hasREST)
            {
                restPort = settings.GetInt("rest.port", 7078);
                logger.Message($"REST server listening on port {restPort}...");
                var restServer = new RESTServer(nexusApi, "/api", restPort, (level, text) => WebLogMapper("rest", level, text));
                restServer.Start(ThreadPriority.AboveNormal);
            }
            else
            {
                restPort = 0;
            }

            if (node != null)
            {
                var neoScanURL = settings.GetString("neoscan.url", "https://api.neoscan.io");

                var rpcList    = settings.GetString("neo.rpc", "http://seed6.ngd.network:10332,http://seed.neoeconomy.io:10332");
                var neoRpcURLs = rpcList.Split(',');
                this.neoAPI = new Neo.Core.RemoteRPCNode(neoScanURL, neoRpcURLs);
                this.neoAPI.SetLogger((s) => logger.Message(s));

                this.neoScanAPI = new NeoScanAPI(neoScanURL, logger, nexus, node_keys);

                cryptoCompareAPIKey = settings.GetString("cryptocompare.apikey", "");
                if (!string.IsNullOrEmpty(cryptoCompareAPIKey))
                {
                    logger.Message($"CryptoCompare API enabled...");
                }

                node.Start();
            }

            if (gui != null)
            {
                int pluginPeriod = settings.GetInt("plugin.refresh", 1); // in seconds

                if (settings.GetBool("plugin.tps", false))
                {
                    RegisterPlugin(new TPSPlugin(logger, pluginPeriod));
                }

                if (settings.GetBool("plugin.ram", false))
                {
                    RegisterPlugin(new RAMPlugin(logger, pluginPeriod));
                }

                if (settings.GetBool("plugin.mempool", false))
                {
                    RegisterPlugin(new MempoolPlugin(mempool, logger, pluginPeriod));
                }
            }

            Console.CancelKeyPress += delegate
            {
                Terminate();
            };

            useSimulator = settings.GetBool("simulator.enabled", false);

            var dispatcher = new CommandDispatcher();

            SetupCommands(dispatcher);

            if (settings.GetBool("swaps.enabled"))
            {
                var tokenSwapper = new TokenSwapper(node_keys, nexusApi, neoScanAPI, neoAPI, minimumFee, logger, settings);
                nexusApi.TokenSwapper = tokenSwapper;

                new Thread(() =>
                {
                    logger.Message("Running token swapping service...");
                    while (running)
                    {
                        Thread.Sleep(5000);

                        if (nodeReady)
                        {
                            tokenSwapper.Update();
                        }
                    }
                }).Start();
            }

            if (useSimulator && bootstrap)
            {
                new Thread(() =>
                {
                    logger.Message("Initializing simulator...");
                    simulator            = new NexusSimulator(this.nexus, node_keys, 1234);
                    simulator.MinimumFee = minimumFee;

                    /*
                     * logger.Message("Bootstrapping validators");
                     * simulator.BeginBlock();
                     * for (int i = 1; i < validatorWIFs.Length; i++)
                     * {
                     *  simulator.GenerateTransfer(node_keys, Address.FromWIF(validatorWIFs[i]), this.nexus.RootChain, DomainSettings.StakingTokenSymbol, UnitConversion.ToBigInteger(50000, DomainSettings.StakingTokenDecimals));
                     * }
                     * simulator.EndBlock();*/

                    string[] dapps = settings.GetString("dapps", "").Split(',');

                    DappServer.InitDapps(nexus, simulator, node_keys, dapps, minimumFee, logger);

                    bool genBlocks = settings.GetBool("simulator.blocks", false);
                    if (genBlocks)
                    {
                        int blockNumber = 0;
                        while (running)
                        {
                            Thread.Sleep(5000);
                            blockNumber++;
                            logger.Message("Generating sim block #" + blockNumber);
                            try
                            {
                                simulator.CurrentTime = DateTime.UtcNow;
                                simulator.GenerateRandomBlock();
                            }
                            catch (Exception e)
                            {
                                logger.Error("Fatal error: " + e.ToString());
                                Environment.Exit(-1);
                            }
                        }
                    }

                    MakeReady(dispatcher);
                }).Start();
            }
            else
            {
                MakeReady(dispatcher);
            }

            this.Run();
        }
Exemplo n.º 11
0
        public CLI(string[] args)
        {
            var culture = new CultureInfo("en-US");

            CultureInfo.DefaultThreadCurrentCulture = culture;

            var seeds = new List <string>();

            var settings = new Arguments(args);

            /*
             * for (int i = 0; i < 20; i++)
             * {
             *  var k = KeyPair.Generate();
             *  Console.WriteLine(k.ToWIF() + " => " + k.Address.Text);
             * }*/

            var useGUI = settings.GetBool("gui.enabled", true);

            if (useGUI)
            {
                gui    = new ConsoleGUI();
                logger = gui;
            }
            else
            {
                gui    = null;
                logger = new ConsoleLogger();
            }

            string mode = settings.GetString("node.mode", "validator");

            bool hasRPC  = settings.GetBool("rpc.enabled", false);
            bool hasREST = settings.GetBool("rest.enabled", false);

            string wif = settings.GetString("node.wif");

            var nexusName = settings.GetString("nexus.name", "simnet");

            switch (mode)
            {
            case "sender":
                string host               = settings.GetString("sender.host");
                int    threadCount        = settings.GetInt("sender.threads", 8);
                int    addressesPerSender = settings.GetInt("sender.addressCount", 100);
                RunSender(wif, host, threadCount, addressesPerSender);
                Console.WriteLine("Sender finished operations.");
                return;

            case "validator": break;

            default:
            {
                logger.Error("Unknown mode: " + mode);
                return;
            }
            }

            int defaultPort = 0;

            for (int i = 0; i < validatorWIFs.Length; i++)
            {
                if (validatorWIFs[i] == wif)
                {
                    defaultPort = (7073 + i);
                }
            }

            if (defaultPort == 0)
            {
                defaultPort = (7073 + validatorWIFs.Length);
            }

            int port = settings.GetInt("node.port", defaultPort);
            var defaultStoragePath = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location) + "/Storage";
            var storagePath        = settings.GetString("storage.path", defaultStoragePath);

            storagePath = storagePath.Replace("\\", "/");
            if (!storagePath.EndsWith('/'))
            {
                storagePath += '/';
            }

            var storageFix = settings.GetBool("storage.fix", false);

            // TODO remove this later
            if (storageFix)
            {
                if (Directory.Exists(storagePath))
                {
                    logger.Warning("Storage fix enabled... Cleaning up all storage...");
                    var di = new DirectoryInfo(storagePath);
                    foreach (FileInfo file in di.EnumerateFiles())
                    {
                        file.Delete();
                    }
                }
            }

            logger.Message("Storage path: " + storagePath);

            var node_keys = KeyPair.FromWIF(wif);

            nexus = new Nexus(logger, (name) => new BasicDiskStore(storagePath + name + ".txt"));

            bool bootstrap = false;

            if (wif == validatorWIFs[0])
            {
                if (!nexus.Ready)
                {
                    logger.Debug("Boostraping nexus...");
                    bootstrap = true;
                    if (!nexus.CreateGenesisBlock(nexusName, node_keys, Timestamp.Now))
                    {
                        throw new ChainException("Genesis block failure");
                    }

                    logger.Debug("Genesis block created: " + nexus.GenesisHash);
                }
            }
            else
            {
                //nexus = new Nexus(nexusName, genesisAddress, logger);
                nexus = new Nexus(logger);
                seeds.Add("127.0.0.1:7073");
            }

            // TODO this should be later optional to enable
            nexus.AddPlugin(new ChainAddressesPlugin());
            nexus.AddPlugin(new TokenTransactionsPlugin());
            nexus.AddPlugin(new AddressTransactionsPlugin());
            nexus.AddPlugin(new UnclaimedTransactionsPlugin());

            running = true;

            // mempool setup
            int blockTime = settings.GetInt("node.blocktime", Mempool.MinimumBlockTime);

            this.mempool = new Mempool(node_keys, nexus, blockTime, ReadFromOracle);
            mempool.Start(ThreadPriority.AboveNormal);

            mempool.OnTransactionFailed += Mempool_OnTransactionFailed;

            api = new NexusAPI(nexus, mempool);

            // RPC setup
            if (hasRPC)
            {
                int rpcPort = settings.GetInt("rpc.port", 7077);

                logger.Message($"RPC server listening on port {rpcPort}...");
                var rpcServer = new RPCServer(api, "/rpc", rpcPort, (level, text) => WebLogMapper("rpc", level, text));
                rpcServer.Start(ThreadPriority.AboveNormal);
            }

            // REST setup
            if (hasREST)
            {
                int restPort = settings.GetInt("rest.port", 7078);

                logger.Message($"REST server listening on port {restPort}...");
                var restServer = new RESTServer(api, "/api", restPort, (level, text) => WebLogMapper("rest", level, text));
                restServer.Start(ThreadPriority.AboveNormal);
            }


            cryptoCompareAPIKey = settings.GetString("cryptocompare.apikey", "");
            if (!string.IsNullOrEmpty(cryptoCompareAPIKey))
            {
                logger.Message($"CryptoCompare API enabled...");
            }

            // node setup
            this.node = new Node(nexus, mempool, node_keys, port, seeds, logger);
            node.Start();

            if (gui != null)
            {
                int pluginPeriod = settings.GetInt("plugin.refresh", 1); // in seconds
                RegisterPlugin(new TPSPlugin(logger, pluginPeriod));
                RegisterPlugin(new RAMPlugin(logger, pluginPeriod));
                RegisterPlugin(new MempoolPlugin(mempool, logger, pluginPeriod));
            }

            Console.CancelKeyPress += delegate {
                Terminate();
            };

            var dispatcher = new CommandDispatcher();

            SetupCommands(dispatcher);

            bool useSimulator = settings.GetBool("simulator.enabled", false);

            if (useSimulator && bootstrap)
            {
                new Thread(() =>
                {
                    logger.Message("Initializing simulator...");
                    var simulator = new ChainSimulator(this.nexus, node_keys, 1234);

                    logger.Message("Bootstrapping validators");
                    simulator.BeginBlock();
                    for (int i = 1; i < validatorWIFs.Length; i++)
                    {
                        simulator.GenerateTransfer(node_keys, Address.FromWIF(validatorWIFs[i]), this.nexus.RootChain, Nexus.StakingTokenSymbol, UnitConversion.ToBigInteger(50000, Nexus.StakingTokenDecimals));
                    }
                    simulator.EndBlock();

                    for (int i = 0; i < 3; i++)
                    {
                        logger.Message("Generating sim block #" + i);
                        simulator.GenerateRandomBlock();
                    }

                    NachoServer.InitNachoServer(nexus, simulator, node_keys, logger);
                    MakeReady(dispatcher);
                }).Start();
            }
            else
            {
                MakeReady(dispatcher);
            }

            this.Run();
        }
Exemplo n.º 12
0
        private Node SetupNode()
        {
            if (Settings.Node.Mode == NodeMode.Proxy)
            {
                Logger.Warning("No nexus will be setup locally due to proxy mode being enabled");
                return(null);
            }

            Node node = null;

            if (this._mempool != null)
            {
                this._mempool.SetKeys(_nodeKeys);
            }

            if (!Settings.Node.IsValidator && Settings.Node.Seeds.Count == 0 && _peerCaps.HasFlag(PeerCaps.Sync))
            {
                throw new Exception("A non-validator node with sync enabled must specificy a non-empty list of seed endpoints");
            }

            node = new Node("Spook v" + Version
                            , _nexus
                            , _mempool
                            , _nodeKeys
                            , Settings.Node.NodeHost
                            , _availablePorts
                            , _peerCaps
                            , Settings.Node.Seeds
                            , Logger);

            var missingNexus = !_nexus.HasGenesis;

            if (missingNexus)
            {
                if (Settings.Node.IsValidator)
                {
                    var nexusName = Settings.Node.NexusName;
                    if (Settings.Node.NexusBootstrap)
                    {
                        if (!ValidationUtils.IsValidIdentifier(nexusName))
                        {
                            Logger.Error("Invalid nexus name: " + nexusName);
                            this.Terminate();
                        }

                        Logger.Message($"Boostraping {nexusName} nexus using {_nodeKeys.Address}...");

                        var genesisTimestamp = Settings.Node.GenesisTimestamp;

                        if (!_nexus.CreateGenesisBlock(_nodeKeys, genesisTimestamp, DomainSettings.LatestKnownProtocol))
                        {
                            throw new ChainException("Genesis block failure");
                        }

                        Logger.Success("Genesis block created: " + _nexus.GetGenesisHash(_nexus.RootStorage));

                        missingNexus = false;
                    }
                }
                else
                {
                    if (_mempool != null)
                    {
                        _mempool.SubmissionCallback = (tx, chain) =>
                        {
                            Logger.Message($"Relaying tx {tx.Hash} to other node");
                        };
                    }
                }

                if (missingNexus && !_peerCaps.HasFlag(PeerCaps.Sync))
                {
                    Logger.Error("No Nexus found.");
                    this.Terminate();
                }
            }
            else
            {
                var genesisAddress = _nexus.GetGenesisAddress(_nexus.RootStorage);
                if (Settings.Node.IsValidator && !Settings.Node.Readonly)
                {
                    if (!_nexus.IsKnownValidator(_nodeKeys.Address))
                    {
                        throw new Exception("Specified node key does not match a known validator address");
                    }
                    else
                    if (_nodeKeys.Address != genesisAddress)
                    {
                        Logger.Warning("Specified node key does not match genesis address " + genesisAddress.Text);
                    }
                }

                var chainHeight = _nexus.RootChain.Height;
                var genesisHash = _nexus.GetGenesisHash(_nexus.RootStorage);
                Logger.Success($"Loaded {Nexus.Name} Nexus with genesis {genesisHash } with {chainHeight} blocks");
            }

            return(node);
        }
Exemplo n.º 13
0
        public ChainSimulator(KeyPair ownerKey, int seed, int cacheSize, Logger logger = null)
        {
            this.Logger = logger != null ? logger : new DummyLogger();

            _owner     = ownerKey;
            this.Nexus = new Nexus("simnet", ownerKey.Address, cacheSize);

            CurrentTime = new DateTime(2018, 8, 26);

            if (!Nexus.CreateGenesisBlock(_owner, CurrentTime))
            {
                throw new ChainException("Genesis block failure");
            }

            this.bankChain = Nexus.FindChainByName("bank");

            _rnd = new System.Random(seed);
            _keys.Add(_owner);

            var oneFuel      = UnitConversion.ToBigInteger(1, Nexus.FuelTokenDecimals);
            var localBalance = Nexus.RootChain.GetTokenBalance(Nexus.FuelToken, _owner.Address);

            if (localBalance < oneFuel)
            {
                throw new Exception("Funds missing oops");
            }

            var appsChain = Nexus.FindChainByName("apps");

            BeginBlock();
            GenerateSideChainSend(_owner, Nexus.FuelToken, Nexus.RootChain, _owner.Address, appsChain, oneFuel, 0);
            var blockTx = EndBlock().First();

            BeginBlock();
            GenerateSideChainSettlement(_owner, Nexus.RootChain, appsChain, blockTx.Hash);
            GenerateChain(_owner, Nexus.RootChain, "dex");
            GenerateChain(_owner, Nexus.RootChain, "market");
            EndBlock();

            BeginBlock();
            GenerateAppRegistration(_owner, "nachomen", "https://nacho.men", "Collect, train and battle against other players in Nacho Men!");
            GenerateAppRegistration(_owner, "mystore", "https://my.store", "The future of digital content distribution!");
            GenerateAppRegistration(_owner, "nftbazar", "https://nft.bazar", "A decentralized NFT market");
            GenerateToken(_owner, "NACHO", "Nachomen", 0, 0, TokenFlags.Transferable);
            EndBlock();

            var market = Nexus.FindChainByName("market");

            BeginBlock();

            var nacho = Nexus.FindTokenBySymbol("NACHO");

            RandomSpreadNFT(nacho, 150);

            GenerateSetTokenMetadata(_owner, nacho, "details", "https://nacho.men/luchador/*");
            GenerateSetTokenMetadata(_owner, nacho, "viewer", "https://nacho.men/luchador/body/*");
            EndBlock();

            var nftSales = new List <KeyValuePair <KeyPair, BigInteger> >();

            BeginBlock();
            for (int i = 1; i < 7; i++)
            {
                BigInteger ID   = i + 100;
                var        info = Nexus.GetNFT(nacho, ID);
                if (info == null)
                {
                    continue;
                }

                var chain = Nexus.FindChainByAddress(info.CurrentChain);
                if (chain == null)
                {
                    continue;
                }

                var nftOwner = chain.GetTokenOwner(nacho, ID);

                if (nftOwner == Address.Null)
                {
                    continue;
                }

                foreach (var key in _keys)
                {
                    if (key.Address == nftOwner)
                    {
                        nftSales.Add(new KeyValuePair <KeyPair, BigInteger>(key, ID));
                        // send some gas to the sellers
                        GenerateTransfer(_owner, key.Address, Nexus.RootChain, Nexus.FuelToken, UnitConversion.ToBigInteger(0.01m, Nexus.FuelTokenDecimals));
                    }
                }
            }

            EndBlock();

            BeginBlock();
            foreach (var sale in nftSales)
            {
                // TODO this later should be the market chain instead of root
                GenerateNftSale(sale.Key, Nexus.RootChain, nacho, sale.Value, UnitConversion.ToBigInteger(100 + 5 * _rnd.Next() % 50, Nexus.FuelTokenDecimals));
            }
            EndBlock();
        }