Skip to content

Commit

Permalink
Fix worknet help text + add worknet command reference
Browse files Browse the repository at this point in the history
  • Loading branch information
Harry committed Sep 29, 2022
1 parent 0a355e0 commit 728e103
Show file tree
Hide file tree
Showing 7 changed files with 160 additions and 21 deletions.
135 changes: 135 additions & 0 deletions docs/worknet-command-reference.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,135 @@
<!-- markdownlint-enable -->
# Neo-WorkNet Command Reference

The `neo-worknet` tool enables a developer to create and run a Neo N3 consensus node that branches
from a public Neo N3 blockchain - including the official Neo N3 MainNet and T5 TestNet. This provides
the developer a local scratchpad environment that mirrors the state of a known public network at a
specified index. Changes to the local branch of the network are independent of the public network.


> Note, you can pass -?|-h|--help to show a list of supported commands or to show
> help information about a specific command.
## neo-worknet create

```
Create a Neo Worknet branch
Usage: neo-worknet create [options] <RpcUri> <Output>
Arguments:
RpcUri URL of Neo JSON-RPC Node
Specify MainNet, TestNet or JSON-RPC URL
Output Name of .neo-worknet file to create (Default: ./default.neo-worknet)
Options:
-i|--index <INDEX> Block height to branch at
Default value is: 0.
-f|--force Overwrite existing data
--disable-log Disable verbose data logging
-?|-h|--help Show help information.
```

The `create` command creates a new local WorkNet blockchain as a branch from a public Neo N3 blockchain.
This command will create both a `.neo-worknet` file to hold details about the blockchain branch and a
`data` folder that will contain data loaded from the remote blockchain and cached locally as well as
locally generated blocks and contract storage updates.

The user must specify a remote Neo N3 blockchain network to branch from. Neo-WorkNet has built in knowledge
of MainNet and the T5 TestNet. However, the user can specify any Neo N3 RPC API node they wish. The
user can specify a specific block index to branch at. If unspecified, `neo-worknet` will branch at the
current height of the specified blockchain.

> Note, Neo-WorkNet depends on the StateService and RpcServer [plugins](https://github.com/neo-project/neo-modules)
> to be installed on the `RpcUri` argument. Furthermore, the StateService *MUST* be configured with
> `FullState` as `true`.
The branched blockchain *CANNOT* be validated across the branch point. When a Neo Worknet branch network
is created, a new wallet account is created to act as the consensus block signer. The public network's
council members' accounts are obviously not available for signing new blocks on a local branch of the
chain. Changing the consensus account that signs blocks requires an update to the `NextConsensus` field.
Updating this field requires adding an *unsigned* block to the local blockchain branch. Since this branch
transition block is unsigned, the blockchain history can not be validated across this transition block.

Unlike Neo-Express, Neo-Worknet doesn't provide an option for creating a multiple consensus nodes for
the branched chain. Based on understanding of Neo-Express usage patterns, multiple conesnsus nodes are
not typically used. If four or seven conesnsus node support in Neo-WorkNet is important to you, please
file an issue in our [GitHub repo](https://github.com/neo-project/neo-express/issues)

## neo-worknet prefetch

```
Fetch data for specified contract
Usage: neo-worknet prefetch [options] <Contract>
Arguments:
Contract Name or Hash of contract to prefetch contract storage
Options:
--disable-log Disable verbose data logging
-?|-h|--help Show help information.
--input Path to .neo-worknet data file
```

Neo-WorkNet caches deployed contract storage on first access. For deployed contracts with thousands
of storage records, this can be very time consuming. The `prefetch` command provides a mechanism to
download contract storage before running the chain. This will ensure all data associated with the specified
contract is downloaded and available so the WorkNet node can run that contract without needing to pause
and download data the first time it's run locally.

## neo-worknet reset

```
Reset WorkNet back to initial branch point
Usage: neo-worknet reset [options]
Options:
-f|--force Overwrite existing data
-?|-h|--help Show help information.
--input Path to .neo-worknet data file
```

This command resets all the locally generated blocks in the chain. The unsigned branch transition block
(described in the `create` command section) is deleted and regenerated as part of this process.

Any contract data from the public chain that has been cached locally - either via `prefetch` or thru
the normal process of executing transactions on the branched chain - are not affected. Even after a
`reset`, contract storage does not need to be `prefetch`ed again.

## neo-worknet run

```
Run Neo-WorkNet instance node
Usage: neo-worknet run [options]
Options:
-s|--seconds-per-block <SECONDS_PER_BLOCK> Time between blocks
-?|-h|--help Show help information.
--input Path to .neo-worknet data file
```

Runs the branched blockchain locally. New blocks will be added to the chain every 15 seconds unless
overridded with the `--seconds-per-block` option.

These new blocks added to the chain have *no* correlation to the blocks added to the public chain that
was branched from. From the point of the branch, the original source chain and the local branched chain
are independent.

Neo-WorkNet comes bundled with the standard `RpcServer` module, similar to Neo-Express. This enables
dApps to interact with the branched chain like they would with the public chain. Neo-WorkNet supports
both read operations like
[`getblock`](https://docs.neo.org/docs/en-us/reference/rpc/latest-version/api/getblock.html)
as well as write operations like
[`sendrawtransaction`](https://docs.neo.org/docs/en-us/reference/rpc/latest-version/api/sendrawtransaction.html).

In addition to the standard `RpcServer` methods, Neo-WorkNet provides custom implementations of
[`getapplicationlog`](https://docs.neo.org/docs/en-us/reference/rpc/latest-version/api/getapplicationlog.html),
[`getnep11balances`](https://docs.neo.org/docs/en-us/reference/rpc/latest-version/api/getnep11balances.html),
[`getnep11properties`](https://docs.neo.org/docs/en-us/reference/rpc/latest-version/api/getnep11properties.html)
and [`getnep17balances`](https://docs.neo.org/docs/en-us/reference/rpc/latest-version/api/getnep17balances.html)
from the ApplicationLogs and TokenTracker plugins (Note, the `getnep11transfers` and `getnep17transfers`)
RPC methods are *not* supported. Additionally, Neo-WorkNet implements `ExpressShutdown` and `ExpressListContracts`
RPC methods that are exposed by Neo-Express.
26 changes: 14 additions & 12 deletions src/worknet/Commands/CreateCommand.cs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@

namespace NeoWorkNet.Commands;

[Command("create", Description = "")]
[Command("create", Description = "Create a Neo-Worknet branch")]
class CreateCommand
{
readonly IFileSystem fs;
Expand All @@ -32,20 +32,20 @@ public CreateCommand(IFileSystem fileSystem)
this.fs = fileSystem;
}

[Argument(0, Description = "URL of Neo JSON-RPC Node\nSpecify MainNet, TestNet or JSON-RPC URL")]
[Argument(0, Description = "URL of Neo JSON-RPC Node. Specify MainNet, TestNet or JSON-RPC URL")]
[Required]
internal string RpcUri { get; } = string.Empty;

[Argument(1, Description = "")]
internal uint Height { get; } = 0;

[Option(Description = "name of " + WORKNET_EXTENSION + " file to create (Default: ./" + DEFAULT_WORKNET_FILENAME + ")")]
[Argument(1, Description = "Name of " + WORKNET_EXTENSION + " file to create (Default: ./" + DEFAULT_WORKNET_FILENAME + ")")]
internal string Output { get; set; } = string.Empty;

[Option]
[Option(Description = "Block height to branch at")]
internal uint Index { get; } = 0;

[Option(Description = "Overwrite existing data")]
internal bool Force { get; set; }

[Option("--disable-log")]
[Option("--disable-log", Description = "Disable verbose data logging")]
internal bool DisableLog { get; set; }

internal async Task<int> OnExecuteAsync(CommandLineApplication app, IConsole console)
Expand All @@ -72,14 +72,14 @@ internal async Task<int> OnExecuteAsync(CommandLineApplication app, IConsole con

console.WriteLine($"Retrieving branch information from {RpcUri}");
using var rpcClient = new RpcClient(uri);
var height = Height;
if (height == 0)
var index = Index;
if (index == 0)
{
var stateApi = new StateAPI(rpcClient);
var (localRootIndex, validatedRootIndex) = await stateApi.GetStateHeightAsync().ConfigureAwait(false);
height = validatedRootIndex ?? localRootIndex ?? throw new Exception("No valid root index available");
index = validatedRootIndex ?? localRootIndex ?? throw new Exception("No valid root index available");
}
var branchInfo = await StateServiceStore.GetBranchInfoAsync(rpcClient, height).ConfigureAwait(false);
var branchInfo = await StateServiceStore.GetBranchInfoAsync(rpcClient, index).ConfigureAwait(false);

console.WriteLine($"Initializing local worknet");

Expand All @@ -102,6 +102,8 @@ internal async Task<int> OnExecuteAsync(CommandLineApplication app, IConsole con
InitializeStore(trackStore, consensusAccount);

console.WriteLine($"Created {filename}");
console.WriteLine(" Note: The private keys for the accounts in this file are are *not* encrypted.");
console.WriteLine(" Do not use these accounts on MainNet or in any other system where security is a concern.");
return 0;
}
catch (Exception ex)
Expand Down
7 changes: 3 additions & 4 deletions src/worknet/Commands/PrefetchCommand.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,12 @@
using System.IO.Abstractions;
using McMaster.Extensions.CommandLineUtils;
using Neo;
using Neo.BlockchainToolkit.Models;
using Neo.BlockchainToolkit.Persistence;
using OneOf.Types;

namespace NeoWorkNet.Commands;

[Command("prefetch", Description = "")]
[Command("prefetch", Description = "Fetch data for specified contract")]
class PrefetchCommand
{
readonly IFileSystem fs;
Expand All @@ -18,10 +17,10 @@ public PrefetchCommand(IFileSystem fileSystem)
fs = fileSystem;
}

[Argument(0)]
[Argument(0, Description = "Name or Hash of contract to prefetch contract storage")]
string Contract { get; set; } = string.Empty;

[Option("--disable-log")]
[Option("--disable-log", Description = "Disable verbose data logging")]
bool DisableLog { get; set; }

internal async Task<int> OnExecuteAsync(CommandLineApplication app, IConsole console, CancellationToken token)
Expand Down
2 changes: 1 addition & 1 deletion src/worknet/Commands/ResetCommand.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

namespace NeoWorkNet.Commands;

[Command("reset", Description = "")]
[Command("reset", Description = "Reset WorkNet back to initial branch point")]
class ResetCommand
{
readonly IFileSystem fs;
Expand Down
2 changes: 1 addition & 1 deletion src/worknet/Commands/RunCommand.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@

namespace NeoWorkNet.Commands;

[Command("run", Description = "")]
[Command("run", Description = "Run Neo-WorkNet instance node")]
partial class RunCommand
{
readonly IFileSystem fs;
Expand Down
6 changes: 5 additions & 1 deletion src/worknet/Program.InputFileConvention.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
using System.Reflection;
using McMaster.Extensions.CommandLineUtils;
using McMaster.Extensions.CommandLineUtils.Conventions;
using static Neo.BlockchainToolkit.Constants;

namespace NeoWorkNet;

Expand All @@ -19,7 +20,10 @@ public void Apply(ConventionContext context)
var parser = context.Application.ValueParsers.GetParser<string>()
?? throw new InvalidOperationException("Can't get string value parser");

var option = new CommandOption<string>(parser, "--input", CommandOptionType.SingleValue);
var option = new CommandOption<string>(parser, "--input", CommandOptionType.SingleValue)
{
Description = $"Path to {WORKNET_EXTENSION} data file"
};
context.Application.AddOption(option);
}
}
Expand Down
3 changes: 1 addition & 2 deletions src/worknet/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,11 @@
using McMaster.Extensions.CommandLineUtils;
using Microsoft.Extensions.DependencyInjection;
using NeoWorkNet.Commands;
using static Neo.BlockchainToolkit.Utility;
using static Crayon.Output;

namespace NeoWorkNet;

[Command("neoxp", Description = "Neo N3 blockchain private net for developers", UsePagerForHelpText = false)]
[Command("neo-worknet", Description = "Branch a public Neo N3 blockchain for private development use", UsePagerForHelpText = false)]
[VersionOption(ThisAssembly.AssemblyInformationalVersion)]
[Subcommand(typeof(CreateCommand), typeof(PrefetchCommand), typeof(ResetCommand), typeof(RunCommand))]
partial class Program
Expand Down

0 comments on commit 728e103

Please sign in to comment.