Esempio n. 1
0
        /*private void ExecuteQuery(MySqlConnection connection, string query)
         * {
         *
         * }*/

        private void Execute()
        {
            var logger = new ConsoleLogger(LogLevel.Maximum);

            var path = @"Storage/";

            this.nexus = new Nexus("mainnet", logger,
                                   (name) => new DBPartition(logger, path + name));

            if (!nexus.HasGenesis)
            {
                throw new Exception("Genesis block not found, check storage path");
            }

            this.nexus.SetOracleReader(new DummyOracle(this.nexus));

            var chains = nexus.GetChains(nexus.RootStorage).Select(x => nexus.GetChainByName(x)).ToArray();
            var tokens = nexus.GetTokens(nexus.RootStorage).Select(x => nexus.GetTokenInfo(nexus.RootStorage, x)).ToArray();

            foreach (var chain in chains)
            {
                foreach (var token in tokens)
                {
                    DumpBalances(chain, token);
                }

                DumpBlocks(chain);
            }
        }
Esempio n. 2
0
        protected override bool Run()
        {
            Thread.Sleep(1000);

            if (this.Capabilities.HasFlag(PeerCaps.Sync))
            {
                if (!listening)
                {
                    listening = true;
                    var accept = listener.BeginAcceptSocket(new AsyncCallback(DoAcceptSocketCallback), listener);
                }

                var now  = DateTime.UtcNow;
                var diff = now - _lastPeerConnect;
                if (diff.TotalSeconds >= 1)
                {
                    ConnectToPeers();
                    _lastPeerConnect = now;
                }
            }

            // check if we have any cached blocks TODO: needs to be revisited when we have multiple chains
            lock (_pendingBlocks)
            {
                if (_pendingBlocks.Count > 0)
                {
                    var chains = Nexus.GetChains(Nexus.RootStorage).Select(x => Nexus.GetChainByName(x));

                    foreach (var chain in chains)
                    {
                        HandlePendingBlocks(chain);
                    }
                }
                else
                {
                    UpdateRequests();
                }
            }

            return(true);
        }
Esempio n. 3
0
        /*private void ExecuteQuery(MySqlConnection connection, string query)
         * {
         *
         * }*/

        private void Execute()
        {
            var logger = new ConsoleLogger(LogLevel.Maximum);

            var path = @"C:\Code\Spook\Spook\bin\Debug\netcoreapp3.1\Storage\";

            this.nexus = new Nexus("mainnet", logger,
                                   (name) => new DBPartition(logger, path + name));

            var chains = nexus.GetChains(nexus.RootStorage).Select(x => nexus.GetChainByName(x)).ToArray();
            var tokens = nexus.GetTokens(nexus.RootStorage).Select(x => nexus.GetTokenInfo(nexus.RootStorage, x)).ToArray();

            foreach (var chain in chains)
            {
                foreach (var token in tokens)
                {
                    DumpBalances(chain, token);
                }

                DumpBlocks(chain);
            }
        }
Esempio n. 4
0
 public IChain GetChainByName(string name)
 {
     return(Nexus.GetChainByName(name));
 }
Esempio n. 5
0
        private Message HandleMessage(Peer peer, Message msg)
        {
            if (msg.IsSigned && !msg.Address.IsNull)
            {
                if (msg.Address.IsUser)
                {
                    peer.SetAddress(msg.Address);
                }
                else
                {
                    return(new ErrorMessage(Address, this.PublicEndpoint, P2PError.InvalidAddress));
                }
            }
            else
            {
                return(new ErrorMessage(Address, this.PublicEndpoint, P2PError.MessageShouldBeSigned));
            }

            Endpoint endpoint;

            try
            {
                endpoint = Endpoint.FromString(msg.Host);
            }
            catch (ChainException e)
            {
                return(new ErrorMessage(Address, this.PublicEndpoint, P2PError.InvalidEndpoint));
            }

            var peerKey = endpoint.ToString();

            lock (_peers)
            {
                if (!_peers.ContainsKey(peerKey))
                {
                    Logger.Message("Added peer: " + peerKey);
                    peer.UpdateEndpoint(endpoint);
                    _peers[peerKey] = peer;
                }
            }

            Logger.Debug($"Got {msg.Opcode} message from {peerKey}");

            switch (msg.Opcode)
            {
            case Opcode.EVENT:
            {
                var evtMessage = (EventMessage)msg;
                var evt        = evtMessage.Event;
                Logger.Message("New event: " + evt.ToString());
                return(null);
            }

            case Opcode.REQUEST:
            {
                var request = (RequestMessage)msg;

                if (request.NexusName != Nexus.Name)
                {
                    return(new ErrorMessage(Address, this.PublicEndpoint, P2PError.InvalidNexus));
                }

                if (request.Kind == RequestKind.None)
                {
                    return(null);
                }

                var answer = new ListMessage(this.Address, this.PublicEndpoint, request.Kind);

                if (request.Kind.HasFlag(RequestKind.Peers))
                {
                    answer.SetPeers(this.Peers.Where(x => x != peer).Select(x => x.Endpoint.ToString()));
                }

                if (request.Kind.HasFlag(RequestKind.Chains))
                {
                    var chainList = Nexus.GetChains(Nexus.RootStorage);
                    var chains    = chainList.Select(x => Nexus.GetChainByName(x)).Select(x => new ChainInfo(x.Name, Nexus.GetParentChainByName(x.Name), x.Height)).ToArray();
                    answer.SetChains(chains);
                }

                if (request.Kind.HasFlag(RequestKind.Mempool) && Capabilities.HasFlag(PeerCaps.Mempool))
                {
                    var txs = _mempool.GetTransactions().Select(x => Base16.Encode(x.ToByteArray(true)));
                    answer.SetMempool(txs);
                }

                if (request.Kind.HasFlag(RequestKind.Blocks))
                {
                    foreach (var entry in request.Blocks)
                    {
                        var chain = this.Nexus.GetChainByName(entry.Key);
                        if (chain == null)
                        {
                            continue;
                        }

                        answer.AddBlockRange(chain, entry.Value);
                    }
                }

                return(answer);
            }

            case Opcode.LIST:
            {
                var listMsg = (ListMessage)msg;

                var outKind = RequestKind.None;

                if (listMsg.Kind.HasFlag(RequestKind.Peers))
                {
                    IEnumerable <string> newPeers;

                    lock (_peers)
                    {
                        newPeers = listMsg.Peers.Where(x => !_peers.ContainsKey(x));
                    }

                    foreach (var entry in newPeers)
                    {
                        Logger.Message("New peer: " + entry);
                    }
                    QueueEndpoints(newPeers);
                }

                var blockFetches = new Dictionary <string, RequestRange>();
                if (listMsg.Kind.HasFlag(RequestKind.Chains))
                {
                    foreach (var entry in listMsg.Chains)
                    {
                        var chain = Nexus.GetChainByName(entry.name);
                        // NOTE if we dont find this chain then it is too soon for ask for blocks from that chain
                        if (chain != null)
                        {
                            if (chain.Height < entry.height)
                            {
                                var start = chain.Height + 1;
                                var end   = entry.height;
                                var limit = start + ListMessage.MaxBlocks - 1;

                                if (end > limit)
                                {
                                    end = limit;
                                }

                                blockFetches[entry.name] = new RequestRange(start, end);

                                lock (_knownHeights)
                                {
                                    BigInteger lastKnowHeight = _knownHeights.ContainsKey(chain.Name) ? _knownHeights[chain.Name] : 0;
                                    if (entry.height > lastKnowHeight)
                                    {
                                        _knownHeights[chain.Name] = entry.height;
                                        IsFullySynced             = false;
                                    }
                                }
                            }

                            if (chain.Height == entry.height)
                            {
                                IsFullySynced = true;
                            }
                        }
                    }
                }

                if (listMsg.Kind.HasFlag(RequestKind.Mempool) && Capabilities.HasFlag(PeerCaps.Mempool))
                {
                    int submittedCount = 0;
                    foreach (var txStr in listMsg.Mempool)
                    {
                        var bytes = Base16.Decode(txStr);
                        var tx    = Transaction.Unserialize(bytes);
                        try
                        {
                            _mempool.Submit(tx);
                            submittedCount++;
                        }
                        catch
                        {
                        }

                        Logger.Message(submittedCount + " new transactions");
                    }
                }

                if (listMsg.Kind.HasFlag(RequestKind.Blocks))
                {
                    Chain chain = null;
                    foreach (var entry in listMsg.Blocks)
                    {
                        chain = Nexus.GetChainByName(entry.Key);
                        if (chain == null)
                        {
                            continue;
                        }

                        var blockRange = entry.Value;
                        foreach (var block in blockRange.blocks)
                        {
                            var transactions = new List <Transaction>();
                            foreach (var txHash in block.TransactionHashes)
                            {
                                var tx = entry.Value.transactions[txHash];
                                transactions.Add(tx);
                            }

                            var maxPendingHeightExpected = chain.Height + ListMessage.MaxBlocks;

                            if (block.Height > chain.Height && block.Height <= maxPendingHeightExpected)
                            {
                                var key = $"{chain.Name}.{block.Height}";
                                lock (_pendingBlocks)
                                {
                                    _pendingBlocks[key] = new PendingBlock(chain.Name, block, transactions);
                                }
                            }
                        }

                        _lastRequestTime = DateTime.UtcNow;
                        //Thread.Sleep(10000);
                    }
                }

                if (blockFetches.Count > 0)
                {
                    outKind |= RequestKind.Blocks;
                }

                if (outKind != RequestKind.None)
                {
                    var answer = new RequestMessage(this.Address, this.PublicEndpoint, outKind, Nexus.Name);

                    if (blockFetches.Count > 0)
                    {
                        answer.SetBlocks(blockFetches);
                    }

                    return(answer);
                }

                return(null);
            }

            case Opcode.MEMPOOL_Add:
            {
                if (Capabilities.HasFlag(PeerCaps.Mempool))
                {
                    var memtx           = (MempoolAddMessage)msg;
                    int submissionCount = 0;
                    foreach (var tx in memtx.Transactions)
                    {
                        try
                        {
                            if (_mempool.Submit(tx))
                            {
                                submissionCount++;
                            }
                        }
                        catch
                        {
                            // ignore
                        }
                    }

                    Logger.Message($"Added {submissionCount} txs to the mempool");
                }

                return(null);
            }

            case Opcode.BLOCKS_List:
            {
                break;
            }

            case Opcode.ERROR:
            {
                var errorMsg = (ErrorMessage)msg;
                if (string.IsNullOrEmpty(errorMsg.Text))
                {
                    Logger.Error($"ERROR: {errorMsg.Code}");
                }
                else
                {
                    Logger.Error($"ERROR: {errorMsg.Code} ({errorMsg.Text})");
                }

                return(null);
            }
            }

            throw new NodeException("No answer sent to request " + msg.Opcode);
        }
Esempio n. 6
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.GetChainByName("bank");

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

            var oneFuel      = UnitConversion.ToBigInteger(1, DomainSettings.FuelTokenDecimals);
            var localBalance = Nexus.RootChain.GetTokenBalance(Nexus.RootStorage, DomainSettings.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();

            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();
             */
        }