public static void Preload(uint preloadGasAmount, Store store, ExpressConsensusNode node, TextWriter writer, CancellationToken cancellationToken) { Debug.Assert(preloadGasAmount > 0); var wallet = DevWallet.FromExpressWallet(node.Wallet); using var system = new NeoSystem(store); var generationAmount = Blockchain.GenerationAmount[0]; var gas = preloadGasAmount / generationAmount; var preloadCount = preloadGasAmount % generationAmount == 0 ? gas : gas + 1; writer.WriteLine($"Creating {preloadCount} empty blocks to preload {preloadGasAmount} GAS"); Random random = new Random(); for (int i = 1; i <= preloadCount; i++) { if (i % 100 == 0) { writer.WriteLine($" Creating Block {i}"); } var block = CreatePreloadBlock(wallet, random); var relayResult = system.Blockchain.Ask <RelayResultReason>(block).Result; if (relayResult != RelayResultReason.Succeed) { throw new Exception($"Preload block {i} failed {relayResult}"); } } ClaimPreloadGas(system, wallet, random); writer.WriteLine($"Preload complete. {preloadCount * generationAmount} GAS loaded into genesis account."); }
public async Task RunAsync(IStorageProvider store, ExpressConsensusNode node, bool enableTrace, TextWriter writer, CancellationToken token) { if (IsNodeRunning(node)) { throw new Exception("Node already running"); } var tcs = new TaskCompletionSource <bool>(); _ = Task.Run(() => { try { var linkedToken = CancellationTokenSource.CreateLinkedTokenSource(token); var defaultAccount = node.Wallet.Accounts.Single(a => a.IsDefault); using var mutex = new Mutex(true, GLOBAL_PREFIX + defaultAccount.ScriptHash); var wallet = DevWallet.FromExpressWallet(ProtocolSettings, node.Wallet); var multiSigAccount = wallet.GetMultiSigAccounts().Single(); var logPlugin = new Node.LogPlugin(writer); var storageProviderPlugin = new Node.StorageProviderPlugin(store); var appEngineProvider = enableTrace ? new Node.ApplicationEngineProvider() : null; var dbftPlugin = new Neo.Consensus.DBFTPlugin(GetConsensusSettings(chain)); var persistencePlugin = new Node.PersistencePlugin(store); using var neoSystem = new Neo.NeoSystem(ProtocolSettings, storageProviderPlugin.Name); _ = neoSystem.ActorSystem.ActorOf(EventWrapper <Blockchain.ApplicationExecuted> .Props(OnApplicationExecuted)); var rpcSettings = GetRpcServerSettings(chain, node); var rpcServer = new Neo.Plugins.RpcServer(neoSystem, rpcSettings); var expressRpcMethods = new ExpressRpcMethods(neoSystem, store, multiSigAccount.ScriptHash, linkedToken); rpcServer.RegisterMethods(expressRpcMethods); rpcServer.RegisterMethods(persistencePlugin); rpcServer.StartRpcServer(); neoSystem.StartNode(new Neo.Network.P2P.ChannelsConfig { Tcp = new IPEndPoint(IPAddress.Loopback, node.TcpPort), WebSocket = new IPEndPoint(IPAddress.Loopback, node.WebSocketPort), }); dbftPlugin.Start(wallet); // DevTracker looks for a string that starts with "Neo express is running" to confirm that the instance has started // Do not remove or re-word this console output: writer.WriteLine($"Neo express is running ({store.GetType().Name})"); linkedToken.Token.WaitHandle.WaitOne(); } catch (Exception ex) { tcs.SetException(ex); } finally { tcs.TrySetResult(true); } }); await tcs.Task.ConfigureAwait(false);
public async Task RunAsync(IExpressStore store, ExpressConsensusNode node, uint secondsPerBlock, bool enableTrace, TextWriter writer, CancellationToken token) { if (IsRunning(node)) { throw new Exception("Node already running"); } chain.InitalizeProtocolSettings(secondsPerBlock); await writer.WriteLineAsync(store.GetType().Name).ConfigureAwait(false); var tcs = new TaskCompletionSource <bool>(); _ = Task.Run(() => { try { var defaultAccount = node.Wallet.Accounts.Single(a => a.IsDefault); using var mutex = new Mutex(true, GLOBAL_PREFIX + defaultAccount.ScriptHash); var wallet = DevWallet.FromExpressWallet(node.Wallet); var multiSigAccount = node.Wallet.Accounts.Single(a => a.IsMultiSigContract()); var dbftPlugin = new Neo.Consensus.DBFTPlugin(); var logPlugin = new Node.LogPlugin(writer); var storageProvider = new Node.ExpressStorageProvider((IStore)store); var appEngineProvider = enableTrace ? new Node.ExpressApplicationEngineProvider() : null; var appLogsPlugin = new Node.ExpressAppLogsPlugin(store); using var system = new Neo.NeoSystem(storageProvider.Name); var rpcSettings = new Neo.Plugins.RpcServerSettings(port: node.RpcPort); var rpcServer = new Neo.Plugins.RpcServer(system, rpcSettings); var expressRpcServer = new ExpressRpcServer(store, multiSigAccount); rpcServer.RegisterMethods(expressRpcServer); rpcServer.RegisterMethods(appLogsPlugin); rpcServer.StartRpcServer(); system.StartNode(new Neo.Network.P2P.ChannelsConfig { Tcp = new IPEndPoint(IPAddress.Loopback, node.TcpPort), WebSocket = new IPEndPoint(IPAddress.Loopback, node.WebSocketPort), }); dbftPlugin.Start(wallet); token.WaitHandle.WaitOne(); } catch (Exception ex) { tcs.SetException(ex); } finally { tcs.TrySetResult(true); } }); await tcs.Task.ConfigureAwait(false); }
public static (Wallet wallet, UInt160 accountHash) GetGenesisAccount(this ExpressChain chain, ProtocolSettings settings) { Debug.Assert(chain.ConsensusNodes != null && chain.ConsensusNodes.Count > 0); var wallet = DevWallet.FromExpressWallet(settings, chain.ConsensusNodes[0].Wallet); var account = wallet.GetMultiSigAccounts().Single(); return(wallet, account.ScriptHash); }
public static bool TryGetSigningAccount(this ExpressChainManager chainManager, string name, string password, [MaybeNullWhen(false)] out Wallet wallet, [MaybeNullWhen(false)] out UInt160 accountHash) { if (!string.IsNullOrEmpty(name)) { var settings = chainManager.Chain.GetProtocolSettings(); if (name.Equals(ExpressChainExtensions.GENESIS, StringComparison.OrdinalIgnoreCase)) { (wallet, accountHash) = chainManager.Chain.GetGenesisAccount(settings); return(true); } if (chainManager.Chain.Wallets != null && chainManager.Chain.Wallets.Count > 0) { for (int i = 0; i < chainManager.Chain.Wallets.Count; i++) { var expWallet = chainManager.Chain.Wallets[i]; if (name.Equals(expWallet.Name, StringComparison.OrdinalIgnoreCase)) { wallet = DevWallet.FromExpressWallet(settings, expWallet); accountHash = wallet.GetAccounts().Single(a => a.IsDefault).ScriptHash; return(true); } } } for (int i = 0; i < chainManager.Chain.ConsensusNodes.Count; i++) { var expWallet = chainManager.Chain.ConsensusNodes[i].Wallet; if (name.Equals(expWallet.Name, StringComparison.OrdinalIgnoreCase)) { wallet = DevWallet.FromExpressWallet(settings, expWallet); accountHash = wallet.GetAccounts().Single(a => !a.Contract.Script.IsMultiSigContract()).ScriptHash; return(true); } } if (!string.IsNullOrEmpty(password)) { if (TryGetNEP2Wallet(name, password, settings, out wallet, out accountHash)) { return(true); } if (TryGetNEP6Wallet(name, password, settings, out wallet, out accountHash)) { return(true); } } } wallet = null; accountHash = null; return(false);
public void RestoreCheckpoint(string checkPointArchive, bool force) { if (chain.ConsensusNodes.Count != 1) { throw new ArgumentException("Checkpoint restore is only supported on single node express instances", nameof(chain)); } checkPointArchive = ResolveCheckpointFileName(checkPointArchive); if (!fileSystem.File.Exists(checkPointArchive)) { throw new Exception($"Checkpoint {checkPointArchive} couldn't be found"); } var node = chain.ConsensusNodes[0]; if (IsNodeRunning(node)) { var scriptHash = node.Wallet.DefaultAccount?.ScriptHash ?? "<unknown>"; throw new InvalidOperationException($"node {scriptHash} currently running"); } var checkpointTempPath = fileSystem.GetTempFolder(); using var folderCleanup = AnonymousDisposable.Create(() => { if (fileSystem.Directory.Exists(checkpointTempPath)) { fileSystem.Directory.Delete(checkpointTempPath, true); } }); var nodePath = fileSystem.GetNodePath(node); if (fileSystem.Directory.Exists(nodePath)) { if (!force) { throw new Exception("You must specify force to restore a checkpoint to an existing blockchain."); } fileSystem.Directory.Delete(nodePath, true); } var wallet = DevWallet.FromExpressWallet(ProtocolSettings, node.Wallet); var multiSigAccount = wallet.GetMultiSigAccounts().Single(); RocksDbUtility.RestoreCheckpoint(checkPointArchive, checkpointTempPath, ProtocolSettings.Network, ProtocolSettings.AddressVersion, multiSigAccount.ScriptHash); fileSystem.Directory.Move(checkpointTempPath, nodePath); }
public static Task RunAsync(Store store, ExpressConsensusNode node, TextWriter writer, CancellationToken cancellationToken) { var tcs = new TaskCompletionSource <bool>(); Task.Run(() => { try { var wallet = DevWallet.FromExpressWallet(node.Wallet); using (var system = new NeoSystem(store)) { var logPlugin = new LogPlugin(writer); var rpcPlugin = new ExpressNodeRpcPlugin(store); system.StartNode(node.TcpPort, node.WebSocketPort); system.StartConsensus(wallet); system.StartRpc(IPAddress.Loopback, node.RpcPort, wallet); { using var snapshot = Blockchain.Singleton.GetSnapshot(); var validators = snapshot.GetValidators(); ; } cancellationToken.WaitHandle.WaitOne(); } } catch (Exception ex) { tcs.SetException(ex); } finally { if (store is IDisposable disposable) { disposable.Dispose(); } tcs.TrySetResult(true); } }); return(tcs.Task); }
public static bool TryGetAccountHash(this ExpressChain chain, string name, [MaybeNullWhen(false)] out UInt160 accountHash, ProtocolSettings?settings = null) { settings ??= chain.GetProtocolSettings(); if (chain.Wallets != null && chain.Wallets.Count > 0) { for (int i = 0; i < chain.Wallets.Count; i++) { if (string.Equals(name, chain.Wallets[i].Name, StringComparison.OrdinalIgnoreCase)) { var wallet = DevWallet.FromExpressWallet(settings, chain.Wallets[i]); var account = wallet.GetAccounts().Single(a => a.IsDefault); accountHash = account.ScriptHash; return(true); } } } Debug.Assert(chain.ConsensusNodes != null && chain.ConsensusNodes.Count > 0); for (int i = 0; i < chain.ConsensusNodes.Count; i++) { var nodeWallet = chain.ConsensusNodes[i].Wallet; if (string.Equals(name, nodeWallet.Name, StringComparison.OrdinalIgnoreCase)) { var wallet = DevWallet.FromExpressWallet(settings, nodeWallet); var account = wallet.GetAccounts().Single(a => a.IsDefault); accountHash = account.ScriptHash; return(true); } } if (GENESIS.Equals(name, StringComparison.OrdinalIgnoreCase)) { (_, accountHash) = chain.GetGenesisAccount(settings); return(true); } if (TryToScriptHash(name, settings.AddressVersion, out accountHash)) { return(true); } accountHash = default; return(false);
Block RunConsensus() { if (chain.ConsensusNodes.Count == 1) { var ctx = new ConsensusContext(nodeWallet, Blockchain.Singleton.Store); ctx.Reset(0); ctx.MakePrepareRequest(); ctx.MakeCommit(); return(ctx.CreateBlock()); } // create ConsensusContext for each ConsensusNode var contexts = new ConsensusContext[chain.ConsensusNodes.Count]; for (int x = 0; x < contexts.Length; x++) { contexts[x] = new ConsensusContext(DevWallet.FromExpressWallet(chain.ConsensusNodes[x].Wallet), Blockchain.Singleton.Store); contexts[x].Reset(0); } // find the primary node for this consensus round var primary = contexts.Single(c => c.IsPrimary); var prepareRequestPayload = primary.MakePrepareRequest(); for (int x = 0; x < contexts.Length; x++) { var context = contexts[x]; if (context.MyIndex == primary.MyIndex) { continue; } var prepareRequestMessage = context.GetMessage <PrepareRequest>(prepareRequestPayload); OnPrepareRequestReceived(context, prepareRequestPayload, prepareRequestMessage); var commitPayload = context.MakeCommit(); var commitMessage = primary.GetMessage <Commit>(commitPayload); OnCommitReceived(primary, commitPayload, commitMessage); } return(primary.CreateBlock()); }
// this method only used in Online/OfflineNode ExecuteAsync public static IReadOnlyList <Wallet> GetMultiSigWallets(this ExpressChain chain, ProtocolSettings settings, UInt160 accountHash) { var builder = ImmutableList.CreateBuilder <Wallet>(); for (int i = 0; i < chain.ConsensusNodes.Count; i++) { var wallet = DevWallet.FromExpressWallet(settings, chain.ConsensusNodes[i].Wallet); if (wallet.GetAccount(accountHash) != null) { builder.Add(wallet); } } for (int i = 0; i < chain.Wallets.Count; i++) { var wallet = DevWallet.FromExpressWallet(settings, chain.Wallets[i]); if (wallet.GetAccount(accountHash) != null) { builder.Add(wallet); } } return(builder.ToImmutable()); }
public OfflineNode(IExpressStore store, ExpressWallet nodeWallet, ExpressChain chain, bool enableTrace) : this(store, DevWallet.FromExpressWallet(nodeWallet), chain, enableTrace) { }
public OfflineNode(ProtocolSettings settings, RocksDbStorageProvider rocksDbStorageProvider, ExpressWallet nodeWallet, ExpressChain chain, bool enableTrace) : this(settings, rocksDbStorageProvider, DevWallet.FromExpressWallet(settings, nodeWallet), chain, enableTrace) { }
public static void ExportWallet(ExpressWallet wallet, string filename, string password) { var devWallet = DevWallet.FromExpressWallet(wallet); devWallet.Export(filename, password); }