Exemplo n.º 1
0
        public static void ExecuteScript(string[] args, SpookSettings settings, NexusAPI api, BigInteger minFee)
        {
            if (args.Length != 1)
            {
                throw new CommandException("Invalid number of arguments, expected file name");
            }

            DoChecks(api);

            var fileName = args[0];

            if (!File.Exists(fileName))
            {
                throw new CommandException("Provided file does not exist");
            }

            if (!fileName.EndsWith(".tx"))
            {
                throw new CommandException($"Provided file is not a compiled transaction script");
            }

            var txScript = File.ReadAllBytes(fileName);

            var sb = new ScriptBuilder();

            sb.AllowGas(Keys.Address, Address.Null, minFee, 9999);
            sb.EmitRaw(txScript);
            sb.SpendGas(Keys.Address);

            var script = sb.EndScript();

            var hash = ExecuteTransaction(settings, api, script, ProofOfWork.Minimal, Keys);
        }
Exemplo n.º 2
0
        public static void Finish(string[] args, SpookSettings settings, NexusAPI api, BigInteger minFee)
        {
            string hashStr = null;

            try
            {
                hashStr = args[0];
            }
            catch
            {
                throw new CommandException("Could not obtain sale hash");
            }

            Hash saleHash;

            if (!Hash.TryParse(hashStr, out saleHash))
            {
                throw new CommandException("Invalid sale hash");
            }

            WalletModule.DoChecks(api);


            var script = ScriptUtils.BeginScript().
                         AllowGas(WalletModule.Keys.Address, Address.Null, minFee, 9999).
                         CallContract(Domain.NativeContractKind.Sale, nameof(SaleContract.CloseSale), WalletModule.Keys.Address, saleHash).
                         SpendGas(WalletModule.Keys.Address).
                         EndScript();

            WalletModule.ExecuteTransaction(settings, api, script, ProofOfWork.None, WalletModule.Keys);
        }
Exemplo n.º 3
0
        private TestData CreateAPI(bool useMempool = false)
        {
            var owner = PhantasmaKeys.FromWIF(testWIF);
            var nexus = new Nexus("simnet", null, null);

            nexus.SetOracleReader(new OracleSimulator(nexus));
            var sim     = new NexusSimulator(nexus, owner, 1234);
            var mempool = useMempool? new Mempool(sim.Nexus, 2, 1, System.Text.Encoding.UTF8.GetBytes("TEST"), 0, new DummyLogger()) : null;

            mempool?.SetKeys(owner);

            var api = new NexusAPI(sim.Nexus);

            api.Mempool = mempool;

            var data = new TestData()
            {
                owner     = owner,
                simulator = sim,
                nexus     = sim.Nexus,
                api       = api
            };

            mempool?.StartInThread();

            return(data);
        }
Exemplo n.º 4
0
        public static void Migrate(string[] args, SpookSettings settings, NexusAPI api, BigInteger minFee)
        {
            if (args.Length != 1)
            {
                throw new CommandException("Invalid number of arguments, expected new wif");
            }

            DoChecks(api);

            var newWIF  = args[0];
            var newKeys = PhantasmaKeys.FromWIF(newWIF);

            var expectedLimit = 800;

            var sb = new ScriptBuilder();

            sb.AllowGas(Keys.Address, Address.Null, minFee, expectedLimit);
            sb.CallContract("validator", "Migrate", Keys.Address, newKeys.Address);
            sb.SpendGas(Keys.Address);
            var script = sb.EndScript();

            var hash = ExecuteTransaction(settings, api, script, ProofOfWork.None, Keys /*, newKeys*/);

            if (hash != Hash.Null)
            {
                logger.Message($"Migrated to " + newKeys.Address);
                Keys = newKeys;
            }
        }
Exemplo n.º 5
0
        public override void Init(MyObjectBuilder_SessionComponent sessionComponent)
        {
            Tools.Log(MyLogSeverity.Info, "Initializing");

            MyAPIGateway.Multiplayer.RegisterSecureMessageHandler(8008, PluginHandleIncomingPacket);
            if (!NetworkAPI.IsInitialized)
            {
                NetworkAPI.Init(ComId, DisplayName, Keyword);
            }

            Network.RegisterChatCommand(string.Empty, Chat_Help);
            Network.RegisterChatCommand("help", Chat_Help);

            if (!MyAPIGateway.Session.IsServer)
            {
                Network.RegisterChatCommand("score", (args) => Network.SendCommand("score"));
                Network.RegisterChatCommand("save", (args) => Network.SendCommand("save"));
                Network.RegisterChatCommand("force-load", (args) => Network.SendCommand("force-load"));

                Network.RegisterNetworkCommand("score", ClientCallback_Score);

                //NEXUS: client message handler, recieves and shows messages forwarded from the sector
                if (!nexusCliInit)
                {
                    MyAPIGateway.Multiplayer.RegisterMessageHandler(CliComId, HandleClientCrossServerComm);
                    nexusCliInit = true;
                }
            }
            else
            {
                ZoneBlock.OnAwardPoints += AwardPoints;
                ZoneBlock.OnPlayerDied  += PlayerDied;

                Network.RegisterChatCommand("score", (args) => { MyAPIGateway.Utilities.ShowMissionScreen(Network.ModName, "King of the Hill", "", FormatScores()); });
                Network.RegisterChatCommand("save", (args) => { ServerCallback_Save(MyAPIGateway.Session.Player.SteamUserId, "save", null, DateTime.Now); });
                Network.RegisterChatCommand("force-load", (args) => { ServerCallback_ForceLoad(MyAPIGateway.Session.Player.SteamUserId, "force_load", null, DateTime.Now); });

                Network.RegisterNetworkCommand("score", ServerCallback_Score);
                Network.RegisterNetworkCommand("save", ServerCallback_Save);
                Network.RegisterNetworkCommand("force_load", ServerCallback_ForceLoad);

                if (MyAPIGateway.Multiplayer.IsServer && !nexusInit)
                {
                    //NEXUS: registration of sector handlers and nexus instances for each
                    Nexus2 = new NexusAPI(5431);                    // score message
                    Nexus  = new NexusAPI(5432);                    // text message
                    MyAPIGateway.Multiplayer.RegisterMessageHandler(5431, HandleCrossServerScore);
                    MyAPIGateway.Multiplayer.RegisterMessageHandler(5432, HandleCrossServerComm);

                    nexusInit = true;
                }
            }

            MyAPIGateway.Entities.OnEntityAdd    += EntityAdded;
            MyAPIGateway.Entities.OnEntityRemove += EntityRemoved;
        }
Exemplo n.º 6
0
        protected override void OnStart()
        {
            Console.CancelKeyPress += delegate
            {
                this.Terminate();
            };

            ValidateConfig();

            Version = Assembly.GetAssembly(typeof(Spook)).GetVersion();

            _nodeKeys = SetupNodeKeys();

            if (!SetupNexus())
            {
                this.OnStop();
                return;
            }

            SetupOracleApis();

            if (Settings.Node.HasMempool && !Settings.Node.Readonly)
            {
                _mempool = SetupMempool();
            }

            _peerCaps = SetupPeerCaps();

            _node = SetupNode();

            _nexusApi = SetupNexusApi();


            if (_node != null && Settings.App.NodeStart)
            {
                _node.StartInThread();
            }

            _commandDispatcher = SetupCommandDispatcher();

            if (Settings.Simulator.Enabled)
            {
                StartSimulator(_commandDispatcher);
            }
            else
            {
                MakeReady(_commandDispatcher);
            }

            if (!string.IsNullOrEmpty(Settings.Oracle.Swaps))
            {
                _tokenSwapper = StartTokenSwapper();
            }
        }
Exemplo n.º 7
0
        public static void GridOfferBought(MarketListing NewOffer, ulong Buyer)
        {
            if (!NexusSupport.RunningNexus)
            {
                return;
            }

            string Title = "Hangar Market - Offer Purchased";



            if (!MySession.Static.Players.TryGetIdentityFromSteamID(NewOffer.SteamID, out MyIdentity Seller))
            {
                return;
            }


            if (!MySession.Static.Players.TryGetIdentityFromSteamID(NewOffer.SteamID, out MyIdentity BuyerIdentity))
            {
                return;
            }



            var    Fac      = MySession.Static.Factions.GetPlayerFaction(Seller.IdentityId);
            var    BuyerFac = MySession.Static.Factions.GetPlayerFaction(BuyerIdentity.IdentityId);
            string Footer;

            if (Fac != null)
            {
                Footer = $"Seller: [{Fac.Tag}] {Seller.DisplayName}";
            }
            else
            {
                Footer = $"Seller: {Seller.DisplayName}";
            }



            StringBuilder Msg = new StringBuilder();

            if (BuyerFac != null)
            {
                Msg.AppendLine($"Grid {NewOffer.Name} was purchased by [{BuyerFac.Tag}] {BuyerIdentity.DisplayName} for {NewOffer.Price}sc!");
            }
            else
            {
                Msg.AppendLine($"Grid {NewOffer.Name} was purchased by {BuyerIdentity.DisplayName} for {NewOffer.Price}sc!");
            }


            NexusAPI.SendEmbedMessageToDiscord(Hangar.Config.MarketUpdateChannel, Title, Msg.ToString(), Footer, "#FFFF00");
        }
Exemplo n.º 8
0
        internal static void DoChecks(NexusAPI api)
        {
            if (Keys == null)
            {
                throw new CommandException("Please open a wallet first");
            }

            if (api.Mempool == null && api.ProxyURL == null)
            {
                throw new CommandException("Need either mempool or proxy enabled!");
            }
        }
Exemplo n.º 9
0
        public static void Airdrop(string[] args, NexusAPI api, BigInteger minFee)
        {
            if (args.Length != 1)
            {
                throw new CommandException("Invalid number of arguments, expected airdrop filename");
            }

            DoChecks(api);

            var fileName = args[0];

            if (!File.Exists(fileName))
            {
                throw new CommandException("Airdrop file does not exist");
            }

            var lines = File.ReadAllLines(fileName);
            var sb    = new ScriptBuilder();

            var expectedLimit = 100 + 600 * lines.Length;

            var expectedGas = UnitConversion.ToDecimal(expectedLimit * minFee, DomainSettings.FuelTokenDecimals);

            logger.Message($"This airdrop will require at least {expectedGas} {DomainSettings.FuelTokenSymbol}");

            sb.AllowGas(Keys.Address, Address.Null, minFee, expectedLimit);

            int addressCount = 0;

            foreach (var line in lines)
            {
                var temp = line.Split(',');

                if (!Address.IsValidAddress(temp[0]))
                {
                    continue;
                }

                addressCount++;

                var target = Address.FromText(temp[0]);
                var symbol = temp[1];
                var amount = BigInteger.Parse(temp[2]);

                sb.TransferTokens(symbol, Keys.Address, target, amount);
            }

            sb.SpendGas(Keys.Address);
            var script = sb.EndScript();

            logger.Message($"Sending airdrop to {addressCount} addresses...");
            ExecuteTransaction(api, script, ProofOfWork.None, Keys);
        }
Exemplo n.º 10
0
        private NexusAPI SetupNexusApi()
        {
            var apiCache     = Settings.Node.ApiCache;
            var apiLog       = Settings.Node.ApiLog;
            var apiProxyURL  = Settings.Node.ApiProxyUrl;
            var readOnlyMode = Settings.Node.Readonly;
            var hasRPC       = Settings.Node.HasRpc;
            var hasREST      = Settings.Node.HasRest;

            NexusAPI nexusApi = new NexusAPI(_nexus, apiCache, apiLog ? Logger : null);

            if (apiProxyURL != null)
            {
                nexusApi.ProxyURL = apiProxyURL;
                // TEMP Normal node needs a proxy url set to relay transactions to the BPs
                nexusApi.Node = _node;
                Logger.Message($"API will be acting as proxy for {apiProxyURL}");
            }
            else
            {
                nexusApi.Node = _node;
            }

            if (readOnlyMode)
            {
                Logger.Warning($"Node will be running in read-only mode.");
            }
            else
            {
                nexusApi.Mempool = _mempool;
            }

            // RPC setup
            if (hasRPC)
            {
                var rpcPort = Settings.Node.RpcPort;
                Logger.Message($"RPC server listening on port {rpcPort}...");
                var rpcServer = new RPCServer(nexusApi, "/rpc", rpcPort, (level, text) => WebLogMapper("rpc", level, text));
                rpcServer.StartInThread(ThreadPriority.AboveNormal);
            }

            // REST setup
            if (hasREST)
            {
                var restPort = Settings.Node.RestPort;
                Logger.Message($"REST server listening on port {restPort}...");
                var restServer = new RESTServer(nexusApi, "/api", restPort, (level, text) => WebLogMapper("rest", level, text));
                restServer.StartInThread(ThreadPriority.AboveNormal);
            }

            return(nexusApi);
        }
Exemplo n.º 11
0
 private static TokenResult FetchTokenInfo(NexusAPI api, string symbol)
 {
     try
     {
         var resultStr = api.Execute("getToken", new object[] { symbol, false });
         var tokenInfo = JsonConvert.DeserializeObject <TokenResult>(resultStr);
         return(tokenInfo);
     }
     catch (Exception e)
     {
         throw new CommandException(e.Message);
     }
 }
Exemplo n.º 12
0
        /* Following are for discord status messages */
        public static void NewGridOfferListed(MarketListing NewOffer)
        {
            if (!NexusSupport.RunningNexus)
            {
                return;
            }


            string Title = "Hangar Market - New Offer";


            StringBuilder Msg = new StringBuilder();

            Msg.AppendLine($"GridName: {NewOffer.Name}");
            Msg.AppendLine($"Price: {NewOffer.Price}sc");
            Msg.AppendLine($"PCU: {NewOffer.PCU}");
            Msg.AppendLine($"Mass: {NewOffer.GridMass}kg");
            Msg.AppendLine($"Jump Distance: {NewOffer.JumpDistance}m");
            Msg.AppendLine($"Number Of Blocks: {NewOffer.NumberofBlocks}");
            Msg.AppendLine($"PowerOutput: {NewOffer.MaxPowerOutput / 1000}kW");
            Msg.AppendLine($"Built-Percent: {NewOffer.GridBuiltPercent * 100}%");
            Msg.AppendLine($"Total Grids: {NewOffer.NumberOfGrids}");
            Msg.AppendLine($"Static Grids: {NewOffer.StaticGrids}");
            Msg.AppendLine($"Large Grids: {NewOffer.LargeGrids}");
            Msg.AppendLine($"Small Grids: {NewOffer.SmallGrids}");


            Msg.AppendLine();
            Msg.AppendLine($"Description: {NewOffer.Description}");

            if (!MySession.Static.Players.TryGetIdentityFromSteamID(NewOffer.SteamID, out MyIdentity Player))
            {
                return;
            }

            var Fac = MySession.Static.Factions.GetPlayerFaction(Player.IdentityId);

            string Footer;

            if (Fac != null)
            {
                Footer = $"Seller: [{Fac.Tag}] {Player.DisplayName}";
            }
            else
            {
                Footer = $"Seller: {Player.DisplayName}";
            }


            NexusAPI.SendEmbedMessageToDiscord(Hangar.Config.MarketUpdateChannel, Title, Msg.ToString(), Footer, "#FFFF00");
        }
Exemplo n.º 13
0
        public void TestGetBotWrestler()
        {
            var owner     = PhantasmaKeys.Generate();
            var simulator = new NexusSimulator(owner, 1234);
            var nexus     = simulator.Nexus;
            var api       = new NexusAPI(nexus);


            var callScript    = ScriptUtils.BeginScript().CallContract("nacho", "GetWrestler", new object[] { -1 }).EndScript();
            var apiResult     = (ScriptResult)api.InvokeRawScript("main", Base16.Encode(callScript));
            var bytes         = Base16.Decode(apiResult.results[0]);
            var objResult     = Serialization.Unserialize <VMObject>(bytes);
            var nachoWrestler = objResult.ToStruct <NachoWrestler>();
        }
Exemplo n.º 14
0
        public static void Balance(NexusAPI api, int phantasmaRestPort, NeoScanAPI neoScanAPI, string[] args)
        {
            if (phantasmaRestPort <= 0)
            {
                throw new CommandException("Please enable REST API on this node to use this feature");
            }

            Address address;

            if (args.Length == 1)
            {
                address = Address.FromText(args[0]);
            }
            else
            {
                address = Keys.Address;
            }

            logger.Message("Fetching balances...");
            var wallets = new List <CryptoWallet>();

            wallets.Add(new PhantasmaWallet(Keys, $"http://*****:*****@ {entry.Chain}");
                        }
                        if (empty)
                        {
                            logger.Message("Empty wallet.");
                        }
                    }
                    else
                    {
                        logger.Message("Failed to fetch balances!");
                    }
                });
            }
        }
Exemplo n.º 15
0
        private static void SettleSwap(SpookSettings settings, NexusAPI api, BigInteger minimumFee, string platform, string swapSymbol, Hash extHash, IKeyPair externalKeys, Address targetAddress)
        {
            var outputAddress = Address.FromKey(externalKeys);

            var script = new ScriptBuilder()
                         .CallContract("interop", "SettleTransaction", outputAddress, platform, extHash)
                         .CallContract("swap", "SwapFee", outputAddress, swapSymbol, UnitConversion.ToBigInteger(0.1m, DomainSettings.FuelTokenDecimals))
                         .TransferBalance(swapSymbol, outputAddress, targetAddress)
                         .AllowGas(outputAddress, Address.Null, minimumFee, 500)
                         .SpendGas(outputAddress).EndScript();

            logger.Message("Settling swap on Phantasma");
            ExecuteTransaction(settings, api, script, ProofOfWork.None, externalKeys);
            logger.Success($"Swap of {swapSymbol} is complete!");
        }
Exemplo n.º 16
0
        public static void Stake(SpookSettings settings, NexusAPI api, BigInteger minFee, string[] args)
        {
            if (args.Length != 1)
            {
                throw new CommandException("Expected args: amount");
            }

            DoChecks(api);

            var tempAmount  = decimal.Parse(args[0]);
            var tokenSymbol = DomainSettings.StakingTokenSymbol;

            TokenResult tokenInfo;

            try
            {
                var result = api.GetToken(tokenSymbol);
                tokenInfo = (TokenResult)result;
            }
            catch (Exception e)
            {
                throw new CommandException(e.Message);
            }

            var amount = UnitConversion.ToBigInteger(tempAmount, tokenInfo.decimals);

            var script = ScriptUtils.BeginScript().
                         AllowGas(Keys.Address, Address.Null, minFee, 9999).
                         CallContract("stake", "Stake", Keys.Address, amount).
                         SpendGas(Keys.Address).
                         EndScript();

            var hash = ExecuteTransaction(settings, api, script, ProofOfWork.None, Keys);

            if (hash != Hash.Null)
            {
                var events = GetTransactionEvents(hash);

                if (events.Any(x => x.kind == EventKind.TokenStake.ToString()))
                {
                    logger.Message($"Staked succesfully {tempAmount} {tokenSymbol} at {Keys.Address.Text}");
                }
                else
                {
                    throw new CommandException("Transaction was confirmed but missing stake event?");
                }
            }
        }
Exemplo n.º 17
0
        private TestData CreateAPI()
        {
            var owner = KeyPair.FromWIF(testWIF);
            var sim   = new ChainSimulator(owner, 1234, -1);
            var api   = new NexusAPI(sim.Nexus);

            var data = new TestData()
            {
                owner     = owner,
                simulator = sim,
                nexus     = sim.Nexus,
                api       = api
            };

            return(data);
        }
Exemplo n.º 18
0
        private TestData CreateAPI(bool useMempool = false)
        {
            var owner   = KeyPair.FromWIF(testWIF);
            var sim     = new ChainSimulator(owner, 1234);
            var mempool = useMempool? new Mempool(owner, sim.Nexus, 2, 1) : null;
            var api     = new NexusAPI(sim.Nexus, mempool);

            var data = new TestData()
            {
                owner     = owner,
                simulator = sim,
                nexus     = sim.Nexus,
                api       = api
            };

            mempool?.Start();

            return(data);
        }
Exemplo n.º 19
0
        private TestData CreateAPI(bool useMempool = false)
        {
            var owner   = PhantasmaKeys.FromWIF(testWIF);
            var sim     = new NexusSimulator(owner, 1234);
            var mempool = useMempool? new Mempool(owner, sim.Nexus, 2, 1, System.Text.Encoding.UTF8.GetBytes("TEST")) : null;
            var api     = new NexusAPI(sim.Nexus);

            api.Mempool = mempool;

            var data = new TestData()
            {
                owner     = owner,
                simulator = sim,
                nexus     = sim.Nexus,
                api       = api
            };

            mempool?.Start();

            return(data);
        }
Exemplo n.º 20
0
        public static void Balance(Address address, NexusAPI api, Logger logger, string[] args)
        {
            if (args.Length == 1)
            {
                address = Address.FromText(args[0]);
            }

            var account = (AccountResult)api.GetAccount(address.Text);

            logger.Message($"Balance for {account.name} ({address.Text})");
            if (account.balances.Any())
            {
                foreach (var entry in account.balances)
                {
                    var amount = BigInteger.Parse(entry.amount);
                    logger.Success($"{entry.chain} => {UnitConversion.ToDecimal(amount, (int)entry.decimals)} {entry.symbol}");
                }
            }
            else
            {
                logger.Warning("Empty wallet.");
            }
        }
Exemplo n.º 21
0
        public static void GirdOfferRemoved(MarketListing NewOffer)
        {
            if (!NexusSupport.RunningNexus)
            {
                return;
            }

            string Title = "Hangar Market - Offer Removed";


            if (!MySession.Static.Players.TryGetIdentityFromSteamID(NewOffer.SteamID, out MyIdentity Player))
            {
                return;
            }

            StringBuilder Msg = new StringBuilder();

            Msg.AppendLine($"Grid {NewOffer.Name} is no longer for sale!");


            var Fac = MySession.Static.Factions.GetPlayerFaction(Player.IdentityId);

            string Footer;

            if (Fac != null)
            {
                Footer = $"Seller: [{Fac.Tag}] {Player.DisplayName}";
            }
            else
            {
                Footer = $"Seller: {Player.DisplayName}";
            }


            NexusAPI.SendEmbedMessageToDiscord(Hangar.Config.MarketUpdateChannel, Title, Msg.ToString(), Footer, "#FFFF00");
        }
Exemplo n.º 22
0
        private static void DeployOrUpgrade(string[] args, SpookSettings settings, NexusAPI api, BigInteger minFee, bool isUpgrade)
        {
            if (args.Length != 1)
            {
                throw new CommandException("Invalid number of arguments, expected file name");
            }

            DoChecks(api);

            var fileName = args[0];

            if (!File.Exists(fileName))
            {
                throw new CommandException("Provided file does not exist");
            }

            if (!FileExistsCaseSensitive(fileName))
            {
                throw new CommandException("Provided file case does not match real file name case");
            }

            var extension = ScriptModule.ScriptExtension;

            if (!fileName.EndsWith(extension))
            {
                throw new CommandException($"Provided file is not a compiled {extension} script");
            }

            var abiFile = fileName.Replace(extension, ".abi");

            if (!File.Exists(abiFile))
            {
                throw new CommandException($"No ABI file {abiFile} that matches provided script file");
            }

            var contractName = Path.GetFileNameWithoutExtension(fileName);

            var contractScript = File.ReadAllBytes(fileName);
            var abiBytes       = File.ReadAllBytes(abiFile);

            var abi = ContractInterface.FromBytes(abiBytes);

            var sb = new ScriptBuilder();

            int nexusVersion = 0;

            try
            {
                var nexusDetails = api.Execute("getNexus", new object[] { false });
                var root         = LunarLabs.Parser.JSON.JSONReader.ReadFromString(nexusDetails);

                var governance = root["governance"];

                var entry = governance.Children.Where(x => x.GetNode("name").Value == "nexus.protocol.version").FirstOrDefault();
                entry = entry.GetNodeByIndex(1);

                nexusVersion = Int32.Parse(entry.Value);
            }
            catch (Exception e)
            {
                Console.WriteLine(e);
                nexusVersion = -1;
            }

            if (nexusVersion <= 1)
            {
                throw new CommandException("Failed to obtain nexus version via API");
            }


            bool isToken        = ValidationUtils.IsValidTicker(contractName);
            var  availableFlags = Enum.GetValues(typeof(TokenFlags)).Cast <TokenFlags>().ToArray();

            sb.AllowGas(Keys.Address, Address.Null, minFee, 9999);

            if (isUpgrade)
            {
                // check for modification in flags
                if (isToken)
                {
                    var symbol    = contractName;
                    var resultStr = api.Execute("getToken", new[] { symbol, "false" });

                    logger.Debug($"{resultStr}");

                    //2021.08.27 sfichera: Fixed api obj deserialization.
                    //dynamic apiResult = System.Text.Json.JsonSerializer.Deserialize<TokenResult>(resultStr);
                    dynamic apiResult = JsonConvert.DeserializeObject <TokenResult>(resultStr);

                    if (apiResult is TokenResult)
                    {
                        var oldToken   = (TokenResult)apiResult;
                        var oldFlags   = TokenFlags.None;
                        var splitFlags = oldToken.flags.Split(',');
                        foreach (var entry in splitFlags)
                        {
                            TokenFlags flag;

                            if (Enum.TryParse <TokenFlags>(entry, true, out flag))
                            {
                                oldFlags |= flag;
                            }
                        }

                        foreach (var flag in availableFlags)
                        {
                            var propName = "is" + flag;
                            if (abi.HasMethod(propName))
                            {
                                var isSet  = ExecuteScript(contractScript, abi, propName).AsBool();
                                var wasSet = oldFlags.HasFlag(flag);
                                if (isSet != wasSet)
                                {
                                    throw new CommandException($"Detected '{flag}' flag change: {wasSet} => {isSet}");
                                }
                            }
                        }
                    }
                    else
                    {
                        throw new CommandException("could not find any deployed token contract for " + symbol);
                    }
                }

                sb.CallInterop("Runtime.UpgradeContract", Keys.Address, contractName, contractScript, abiBytes);
            }
            else
            if (isToken)
            {
                if (!abi.HasMethod("getName"))
                {
                    throw new CommandException("token contract is missing required 'name' property");
                }

                string symbol = null;


                if (nexusVersion < 6)
                {
                    symbol = contractName;
                }
                else
                {
                    if (abi.HasMethod("getSymbol"))
                    {
                        symbol = ExecuteScript(contractScript, abi, "getSymbol").AsString();
                    }

                    if (string.IsNullOrEmpty(symbol))
                    {
                        throw new CommandException("token contract 'symbol' property is either missing or returning an empty value");
                    }
                }

                var name = ExecuteScript(contractScript, abi, "getName").AsString();

                if (string.IsNullOrEmpty(name))
                {
                    throw new CommandException("token contract 'name' property is either missing or returning an empty value");
                }

                BigInteger maxSupply = abi.HasMethod("getMaxSupply") ? ExecuteScript(contractScript, abi, "getMaxSupply").AsNumber() : 0;
                BigInteger decimals  = abi.HasMethod("getDecimals") ? ExecuteScript(contractScript, abi, "getDecimals").AsNumber() : 0;

                TokenFlags flags = TokenFlags.None;

                foreach (var flag in availableFlags)
                {
                    var propName = "is" + flag;
                    if (abi.HasMethod(propName) && ExecuteScript(contractScript, abi, propName).AsBool())
                    {
                        flags |= flag;
                    }
                }

                if (nexusVersion < 6)
                {
                    sb.CallInterop("Nexus.CreateToken", Keys.Address, symbol, name, maxSupply, decimals, flags, contractScript, abiBytes);
                }
                else
                {
                    sb.CallInterop("Nexus.CreateToken", Keys.Address, contractScript, abiBytes);
                }

                contractName = symbol;
            }
            else
            {
                sb.CallInterop("Runtime.DeployContract", Keys.Address, contractName, contractScript, abiBytes);
            }

            sb.SpendGas(Keys.Address);
            var script = sb.EndScript();

            if (!isUpgrade)
            {
                var upgradeTrigger = AccountContract.GetTriggerForABI(AccountTrigger.OnUpgrade);
                if (abi.Implements(upgradeTrigger))
                {
                    logger.Message($"{contractName} implements proper triggers, and can be upgraded later.");
                }
                else
                {
                    logger.Warning($"{contractName} does not implements proper triggers, can't be upgraded later.");
                }
            }

            var hash = ExecuteTransaction(settings, api, script, ProofOfWork.Minimal, Keys);

            if (hash != Hash.Null)
            {
                var expectedEvent    = isUpgrade ? EventKind.ContractUpgrade : (isToken ? EventKind.TokenCreate : EventKind.ContractDeploy);
                var expectedEventStr = expectedEvent.ToString();

                var events = GetTransactionEvents(hash);
                if (events.Any(x => x.kind == expectedEventStr))
                {
                    var contractAddress = SmartContract.GetAddressForName(contractName);

                    string action = isUpgrade ? "Upgraded" : "Deployed";

                    logger.Message($"{action} {contractName} at {contractAddress}");
                }
                else
                {
                    throw new CommandException("Transaction was confirmed but deployment event is missing!");
                }
            }
        }
Exemplo n.º 23
0
    static void Main(string[] args)
    {
        try
        {
            RestSharpAPI restSharpAPI = new RestSharpAPI(baseUrl);
            //RestClient client = restSharpAPI.getClient();  //works
            RestClient client = restSharpAPI.getClient(user, password); // works

            if (restSharpAPI == null || client == null)
            {
                Console.WriteLine("restSharpAPI or client is null");
                Environment.Exit(1);
            }

            NexusAPI nexusAPI = new NexusAPI(restSharpAPI, client);

            //nexusAPI.testDelete();
            //Console.ReadKey(true);

            List<NexusContent> contents = new List<NexusContent>();
            string repository = "otpp-snapshots";
            //string repository = "releases";
            string pattern = ".zip";
            int days = 0;
            contents = nexusAPI.getContent(repository, "/");

            nexusAPI.findArtifacts(repository, contents, days, pattern);
            Console.WriteLine("Size of artifacts: {0}", nexusAPI.urls.Count);

            nexusAPI.removeLastFromList(repository);

            for (int i = nexusAPI.urls.Count - 1; i >= 0; i--)
            {
                nexusAPI.urls[i].TrimEnd('/');
                int local = nexusAPI.urls[i].IndexOf("/local/");
                nexusAPI.urls[i] = nexusAPI.urls[i].Substring(local + 6);
                Console.WriteLine("URL to be deleted: {0}", nexusAPI.urls[i]);
            }

            //nexusAPI.deleteArtifact(nexusAPI.urls, repository);

            Console.ReadKey(true);

            List<NexusRepo> repos = new List<NexusRepo>();
            repos = nexusAPI.GetAllRepos();
            if (repos == null)
            {
                Console.WriteLine("repos is null");
                Console.ReadKey(true);
                Environment.Exit(1);
            }
            else {
                Console.WriteLine("Size of repos: {0}", repos.Count);
            }

            foreach (NexusRepo repo in repos)
            {
               // Console.WriteLine("Repo info: {0}", repo.ToString());
            }

            //nexusAPI.uploadArtifact();
            //nexusAPI.uploadArtifact1();
            //nexusAPI.uploadArtifact2();
            //nexusAPI.uploadArtifact3();

            //List<NexusArtifact> artifacts = new List<NexusArtifact>();
            //artifacts = nexusAPI.searchMetadata();
            //if (artifacts == null)
            //{
            //    Console.WriteLine("artifacts is null");
            //    Console.ReadKey(true);
            //    Environment.Exit(1);
            //}
            //else {
            //    Console.WriteLine("Size of repos: {0}", artifacts.Count);
            //}

            Console.ReadKey(true);
        }
        catch (Exception ex)
        {
            Console.WriteLine("Exception caught: {0}", ex);
            Console.ReadKey(true);
        }
    }
Exemplo n.º 24
0
 public static void Upgrade(string[] args, SpookSettings settings, NexusAPI api, BigInteger minFee)
 {
     DeployOrUpgrade(args, settings, api, minFee, true);
 }
Exemplo n.º 25
0
        static void GenerateBindings(string inputPath, string outputPath)
        {
            inputPath = FixPath(inputPath);
            if (!Directory.Exists(inputPath))
            {
                return;
            }

            var files = Directory.GetFiles(inputPath);

            outputPath = FixPath(outputPath);
            if (!Directory.Exists(outputPath))
            {
                Directory.CreateDirectory(outputPath);
            }

            string replacementFile = inputPath + "language.ini";
            var    replacements    = new Dictionary <string, string>();
            var    replacementsRef = new Dictionary <string, string>();

            if (File.Exists(replacementFile))
            {
                var lines = File.ReadAllLines(replacementFile);
                foreach (var line in lines)
                {
                    if (line.Contains(","))
                    {
                        var temp = line.Split(new[] { ',' }, 2);
                        if (temp[0].StartsWith("@"))
                        {
                            temp[0] = temp[0].Substring(1);
                            replacementsRef[temp[0]] = temp[1];
                        }
                        else
                        {
                            replacements[temp[0]] = temp[1];
                        }
                    }
                }
            }

            var nexus = new Nexus("dummy");
            var api   = new NexusAPI(nexus);

            foreach (var v in replacements)
            {
                if (!replacementsRef.ContainsKey(v.Key))
                {
                    replacementsRef.Add(v.Key, v.Value);
                }
            }
            var typeDic  = new Dictionary <string, IEnumerable <MetaField> >();
            var apiTypes = api.GetType().Assembly.GetTypes().Where(x => !x.IsInterface && x != typeof(SingleResult) && x != typeof(ArrayResult) && x != typeof(ErrorResult) && typeof(IAPIResult).IsAssignableFrom(x)).ToList();

            foreach (var entry in apiTypes)
            {
                typeDic[entry.Name /*.Replace("Result", "")*/] = GetMetaFields(entry);
            }

            var compiler = new Compiler();

            compiler.ParseNewLines = true;
            compiler.RegisterCaseTags();
            compiler.RegisterTag("fix-ref", (doc, x) => new FixTypeNode(doc, x, replacementsRef));
            compiler.RegisterTag("fix-type", (doc, x) => new FixTypeNode(doc, x, replacements));
            compiler.RegisterTag("fix-array", (doc, x) => new FixArrayNode(doc, x));

            var data = new Dictionary <string, object>();

            data["methods"] = api.Methods.Select(x => new MethodEntry()
            {
                Info = x, ResultFields = x.ReturnType.GetFields()
            });
            data["types"]   = typeDic;
            data["opcodes"] = Enum.GetValues(typeof(Opcode)).Cast <Opcode>().Select(x => new KeyValuePair <string, byte>(x.ToString(), (byte)x));

            foreach (var file in files)
            {
                if (file == replacementFile)
                {
                    continue;
                }

                var filePath = file;

                var content = File.ReadAllText(filePath);

                var template = compiler.CompileTemplate(content);
                var queue    = new Queue <Document>();

                var context = new RenderingContext();
                context.DataRoot  = data;
                context.DataStack = new List <object>();
                context.DataStack.Add(data);
                context.queue  = queue;
                context.output = new StringBuilder();
                template.Execute(context);

                filePath = file.Replace(inputPath, outputPath);
                File.WriteAllText(filePath, context.output.ToString());
            }
        }
Exemplo n.º 26
0
        public static void Airdrop(string[] args, SpookSettings settings, NexusAPI api, BigInteger minFee)
        {
            if (args.Length != 1)
            {
                throw new CommandException("Invalid number of arguments, expected airdrop filename");
            }

            DoChecks(api);

            var fileName = args[0];

            if (!File.Exists(fileName))
            {
                throw new CommandException("Airdrop file does not exist");
            }

            var lines = File.ReadAllLines(fileName);
            var sb    = new ScriptBuilder();

            var expectedLimit = 100 + 600 * lines.Length;

            var expectedGas = UnitConversion.ToDecimal(expectedLimit * minFee, DomainSettings.FuelTokenDecimals);

            logger.Message($"This airdrop will require at least {expectedGas} {DomainSettings.FuelTokenSymbol}");

            sb.AllowGas(Keys.Address, Address.Null, minFee, expectedLimit);


            Dictionary <string, TokenResult> tokens = new Dictionary <string, TokenResult>();

            int addressCount = 0;

            foreach (var line in lines)
            {
                var temp = line.Split(',');

                if (!Address.IsValidAddress(temp[0]))
                {
                    continue;
                }

                addressCount++;

                var     target = Address.FromText(temp[0]);
                var     symbol = temp[1];
                decimal val;

                if (!Decimal.TryParse(temp[2], NumberStyles.Any, new CultureInfo("en-US"), out val) || val <= 0)
                {
                    throw new CommandException($"Invalid amount {val} for {target}");
                }

                var token = tokens.ContainsKey(symbol) ? tokens[symbol] : FetchTokenInfo(api, symbol);
                tokens[symbol] = token;

                var amount = UnitConversion.ToBigInteger(val, token.decimals);

                sb.TransferTokens(symbol, Keys.Address, target, amount);
            }

            sb.SpendGas(Keys.Address);
            var script = sb.EndScript();

            logger.Message($"Sending airdrop to {addressCount} addresses...");
            ExecuteTransaction(settings, api, script, ProofOfWork.None, Keys);
        }
Exemplo n.º 27
0
        public TokenSwapper(PhantasmaKeys swapKey, NexusAPI nexusAPI, NeoScanAPI neoscanAPI, NeoAPI neoAPI, BigInteger minFee, Logger logger, Arguments arguments)
        {
            this.SwapKeys   = swapKey;
            this.NexusAPI   = nexusAPI;
            this.MinimumFee = minFee;

            this.neoAPI     = neoAPI;
            this.neoscanAPI = neoscanAPI;
            this.logger     = logger;

            this.Storage = new KeyStoreStorage(Nexus.CreateKeyStoreAdapter("swaps"));

            this.interopBlocks = new Dictionary <string, BigInteger>();

            interopBlocks["phantasma"] = BigInteger.Parse(arguments.GetString("interop.phantasma.height", "0"));
            interopBlocks["neo"]       = BigInteger.Parse(arguments.GetString("interop.neo.height", "4261049"));
            //interopBlocks["ethereum"] = BigInteger.Parse(arguments.GetString("interop.ethereum.height", "4261049"));

            InitWIF("neo", arguments);

            /*
             * foreach (var entry in interopBlocks)
             * {
             *  BigInteger blockHeight = entry.Value;
             *
             *  ChainInterop interop;
             *
             *  switch (entry.Key)
             *  {
             *      case "phantasma":
             *          interop = new PhantasmaInterop(this, swapKey, blockHeight, nexusAPI);
             *          break;
             *
             *      case "neo":
             *          interop = new NeoInterop(this, swapKey, blockHeight, neoAPI, neoscanAPI);
             *          break;
             *
             *      case "ethereum":
             *          interop = new EthereumInterop(this, swapKey, blockHeight);
             *          break;
             *
             *      default:
             *          interop = null;
             *          break;
             *  }
             *
             *  if (interop != null)
             *  {
             *      bool shouldAdd = true;
             *
             *      if (!(interop is PhantasmaInterop))
             *      {
             *          logger.Message($"{interop.Name}.Swap.Private: {interop.PrivateKey}");
             *          logger.Message($"{interop.Name}.Swap.{interop.Name}: {interop.LocalAddress}");
             *          logger.Message($"{interop.Name}.Swap.Phantasma: {interop.ExternalAddress}");
             *
             *          for (int i = 0; i < platforms.Length; i++)
             *          {
             *              var temp = platforms[i];
             *              if (temp.platform == interop.Name)
             *              {
             *                  if (temp.address != interop.LocalAddress)
             *                  {
             *                      logger.Error($"{interop.Name} address mismatch, should be {temp.address}. Make sure you are using the proper swap seed.");
             *                      shouldAdd = false;
             *                  }
             *              }
             *          }
             *      }
             *
             *      if (shouldAdd)
             *      {
             *          AddInterop(interop);
             *      }
             *  }
             * }*/
        }
Exemplo n.º 28
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.º 29
0
        public static void Transfer(SpookSettings settings, NexusAPI api, BigInteger minimumFee, NeoAPI neoAPI, string[] args)
        {
            if (args.Length != 4)
            {
                throw new CommandException("Expected args: source_address target_address amount symbol");
            }

            DoChecks(api);

            var tempAmount  = decimal.Parse(args[2]);
            var tokenSymbol = args[3];


            var tokenInfo = FetchTokenInfo(api, tokenSymbol);

            if (!tokenInfo.flags.Contains("Fungible"))
            {
                throw new CommandException("Token must be fungible!");
            }

            var amount = UnitConversion.ToBigInteger(tempAmount, tokenInfo.decimals);

            var    sourceName = args[0];
            string sourcePlatform;

            if (Address.IsValidAddress(sourceName))
            {
                sourcePlatform = PhantasmaWallet.PhantasmaPlatform;
            }
            else
            if (NeoWallet.IsValidAddress(sourceName))
            {
                sourcePlatform = NeoWallet.NeoPlatform;
            }
            else
            {
                throw new CommandException("Invalid source address " + sourceName);
            }

            var    destName = args[1];
            string destPlatform;

            if (Address.IsValidAddress(destName))
            {
                destPlatform = PhantasmaWallet.PhantasmaPlatform;
            }
            else
            if (NeoWallet.IsValidAddress(destName))
            {
                destPlatform = NeoWallet.NeoPlatform;
            }
            else
            {
                throw new CommandException("Invalid destination address " + destName);
            }

            if (destName == sourceName)
            {
                throw new CommandException("Cannot transfer to same address");
            }

            if (sourcePlatform != PhantasmaWallet.PhantasmaPlatform)
            {
                if (destPlatform != PhantasmaWallet.PhantasmaPlatform)
                {
                    if (sourcePlatform != destPlatform)
                    {
                        throw new CommandException($"Cannot transfer directly from {sourcePlatform} to {destPlatform}");
                    }
                    else
                    {
                        switch (destPlatform)
                        {
                        case NeoWallet.NeoPlatform:
                        {
                            var neoKeys = new NeoKeys(Keys.PrivateKey);

                            if (sourceName != neoKeys.Address)
                            {
                                throw new CommandException("The current open wallet does not have keys that match address " + sourceName);
                            }

                            var neoHash = NeoTransfer(neoKeys, destName, tokenSymbol, tempAmount, neoAPI);
                            return;
                        }

                        default:
                            throw new CommandException($"Not implemented yet :(");
                        }
                    }
                }
                else
                {
                    logger.Message($"Source is {sourcePlatform} address, a swap will be performed using an interop address.");

                    IPlatform platformInfo = api.Nexus.GetPlatformInfo(api.Nexus.RootStorage, sourcePlatform);

                    Hash     extHash;
                    IKeyPair extKeys;

                    switch (sourcePlatform)
                    {
                    case NeoWallet.NeoPlatform:
                    {
                        try
                        {
                            var neoKeys = new NeoKeys(Keys.PrivateKey);

                            if (sourceName != neoKeys.Address)
                            {
                                throw new CommandException("The current open wallet does not have keys that match address " + sourceName);
                            }

                            extHash = NeoTransfer(neoKeys, platformInfo.InteropAddresses[0].ExternalAddress, tokenSymbol, tempAmount, neoAPI);

                            if (extHash == Hash.Null)
                            {
                                return;
                            }

                            extKeys = neoKeys;
                        }
                        catch (Exception e)
                        {
                            logger.Message($"{sourcePlatform} error: " + e.Message);
                            return;
                        }

                        break;
                    }

                    default:
                        logger.Message($"Transactions using platform {sourcePlatform} are not supported yet");
                        return;
                    }

                    var destAddress = Address.FromText(destName);
                    SettleSwap(settings, api, minimumFee, sourcePlatform, tokenSymbol, extHash, extKeys, destAddress);
                }
                return;
            }
            else
            {
                Address destAddress;

                if (destPlatform != PhantasmaWallet.PhantasmaPlatform)
                {
                    switch (destPlatform)
                    {
                    case NeoWallet.NeoPlatform:
                        destAddress = NeoWallet.EncodeAddress(destName);
                        break;

                    default:
                        logger.Message($"Transactions to platform {destPlatform} are not supported yet");
                        return;
                    }

                    logger.Message($"Target is {destPlatform} address, a swap will be performed through interop address {destAddress}.");
                }
                else
                {
                    destAddress = Address.FromText(destName);
                }

                var script = ScriptUtils.BeginScript().
                             CallContract("swap", "SwapFee", Keys.Address, tokenSymbol, UnitConversion.ToBigInteger(0.01m, DomainSettings.FuelTokenDecimals)).
                             AllowGas(Keys.Address, Address.Null, minimumFee, 9999).
                             TransferTokens(tokenSymbol, Keys.Address, destAddress, amount).
                             SpendGas(Keys.Address).
                             EndScript();

                logger.Message($"Sending {tempAmount} {tokenSymbol} to {destAddress.Text}...");
                ExecuteTransaction(settings, api, script, ProofOfWork.None, Keys);
            }
        }
Exemplo n.º 30
0
        protected override void OnStart()
        {
            Console.CancelKeyPress += delegate
            {
                this.Terminate();
            };

            ValidateConfig();

            Version = Assembly.GetAssembly(typeof(Spook)).GetVersion();

            _nodeKeys = SetupNodeKeys();

            if (Settings.Node.Mode != NodeMode.Proxy && !SetupNexus())
            {
                this.OnStop();
                return;
            }

            SetupOracleApis();

            if (Settings.Node.HasMempool && !Settings.Node.Readonly)
            {
                _mempool = SetupMempool();
            }

            if (Settings.Node.Mode != NodeMode.Proxy)
            {
                _availablePorts.Add(new PeerPort("sync", Settings.Node.NodePort));
            }

            if (Settings.Node.HasRpc)
            {
                _availablePorts.Add(new PeerPort("rpc", Settings.Node.RpcPort));
            }

            if (Settings.Node.HasRest)
            {
                _availablePorts.Add(new PeerPort("rest", Settings.Node.RestPort));
            }

            _peerCaps = SetupPeerCaps();

            _node = SetupNode();

            _nexusApi = SetupNexusApi();


            if (_node != null && Settings.App.NodeStart)
            {
                if (_peerCaps.HasFlag(PeerCaps.Sync) && Settings.Node.NodeHost.Contains("localhost"))
                {
                    Logger.Warning($"This node host external endpoint is not properly configured and it won't appear on other nodes GetPeers API call.");
                }

                _node.StartInThread();
            }

            _commandDispatcher = SetupCommandDispatcher();

            if (Settings.Simulator.Enabled)
            {
                StartSimulator(_commandDispatcher);
            }
            else
            {
                MakeReady(_commandDispatcher);
            }

            var enabledSwapPlatforms = Settings.Oracle.SwapPlatforms.Select(x => x.Chain != SwapPlatformChain.Phantasma && x.Enabled);

            if (enabledSwapPlatforms.Any())
            {
                _tokenSwapper = StartTokenSwapper();
            }
            else
            {
                Logger.Warning("No swap platforms found in config, token swapper won't be available");
            }
        }
Exemplo n.º 31
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();
        }