GithubHelp home page GithubHelp logo

spacesvm's Introduction

Spaces Virtual Machine (SpacesVM)

Authenticated, Hierarchical Key-Value Store w/EIP-712 Compatibility, State Expiry, and Fee-Based Metering

Avalanche Subnets and Custom VMs

Avalanche is a network composed of multiple sub-networks (called subnets) that each contain any number of blockchains. Each blockchain is an instance of a Virtual Machine (VM), much like an object in an object-oriented language is an instance of a class. That is, the VM defines the behavior of the blockchain where it is instantiated. For example, Coreth (EVM) is a VM that is instantiated by the C-Chain. Likewise, one could deploy another instance of the EVM as their own blockchain (to take this to its logical conclusion).

AvalancheGo Compatibility

Introduction

Just as Coreth powers the C-Chain, SpacesVM can be used to power its own blockchain in an Avalanche Subnet. Instead of providing a place to execute Solidity smart contracts, however, SpacesVM enables authenticated, hierarchical storage of arbitrary keys/values using any EIP-712 compatible wallet.

Authenticated

All modifications of storage require the signature of the owner of a "space".

Hierarchical

Owners can modify any key in their "space" (ex: owner/*), however, no one else can.

Arbitrary Key/Value Storage

As long as a key is ^[a-z0-9]{1,256}$, it can be used as an identifier in SpacesVM. The max length of values is defined in genesis but typically ranges between 64-200KB. Any number of values can be linked together to store files in the > 100s of MBs range (as long as you have the SPC to pay for it).

EIP-712 Compatible

wallet_signing

The canonical digest of a SpacesVM transaction is EIP-712 compliant, so any Web3 wallet that can sign typed data can interact with SpacesVM.

EIP-712 compliance in this case, however, does not mean that SpacesVM is an EVM or even an EVM derivative. SpacesVM is a new Avalanche-native VM written from scratch to optimize for storage-related operations.

What better way to understand how the the SpacesVM works than to see it in action? Well anon, you are in luck!

You can try out the SpacesVM at tryspaces.xyz. All you need is a EIP-712 Compatible Web3 Wallet (like MetaMask) and some SPC (all 973k of you that interacted with the C-Chain more than 2 times got 10k SPC to get you started).

This demo is running as an Avalanche Subnet on Fuji. It is ALPHA LEVEL CODE and may be restarted/have a few bugs in it. It exists for demonstration purposes ONLY but could be extended to run as a production-level Subnet on Avalanche Mainnet.

How it Works

Claim

Interacting with the SpacesVM starts with a ClaimTx. This reserves your own "space" and associates your address with it (so that only you can make changes to it and/or the keys in it).

Reserved Spaces

Spaces of length 66 (0x + hex-encoded EVM-style address) are reserved for address holders. Only the person who can produce a valid signature for a given address can claim these types of spaces.

Set/Delete

Once you have a space, you can then use SetTx and DeleteTx actions to add/modify/delete keys in it. The more storage your space uses, the faster it will expire.

Content-Addressable Keys

To support common blockchain use cases (like NFT storage), the SpacesVM supports the storage of arbitrary size files using content-addressable keys. You can try this out using spaces-cli set-file <space> <filename>.

Lifeline

When your space uses a lot of storage and/or you've had it for a while, you may need to extend its life using a LifelineTx. If you don't, your space will eventually become inaccessible and all data stored within it will be deleted by the SpacesVM.

Community Space Support

It is not required that you own a space to submit a LifelineTx that extends its life. This enables the community to support useful spaces with their SPC.

Resolve

When you want to view data stored in SpacesVM, you call Resolve on the value path: <space>/<key>. If you stored a file at a particular path, use this command to retrieve it: spaces-cli resolve-file <path> <destination filepath>.

Transfer

If you want to share some of your SPC with your friends, you can use a TransferTx to send to any EVM-style address.

Move

If you want to share a space with a friend, you can use a MoveTx to transfer it to any EVM-style address.

Space Rewards

50% of the fees spent on each transaction are sent to a random space owner (as long as the randomly selected recipient is not the creator of the transaction).

One could modify the SpacesVM to instead send rewards to a beneficiary chosen by whoever produces a block.

Fees

All interactions with the SpacesVM require the payment of fees (denominated in SPC). The VM Genesis includes support for allocating one-off SPC to different EVM-style addresses and to allocating SPC to an airdrop list.

Nearly all fee-related params can be tuned by the SpacesVM deployer.

Usage

If you are interested in running the VM, not using it. Jump to Running the VM.

The easiest way to try out SpacesVM is to visit the demo website tryspaces.xyz.

spaces-cli

Install

git clone https://github.com/ava-labs/spacesvm.git;
cd spacesvm;
go install -v ./cmd/spaces-cli;

Usage

SpacesVM CLI

Usage:
  spaces-cli [command]

Available Commands:
  activity     View recent activity on the network
  claim        Claims the given space
  completion   generate the autocompletion script for the specified shell
  create       Creates a new key in the default location
  delete       Deletes a key-value pair for the given space
  delete-file  Deletes all hashes reachable from root file identifier
  genesis      Creates a new genesis in the default location
  help         Help about any command
  info         Reads space info and all values at space
  lifeline     Extends the life of a given space
  move         Transfers a space to another address
  network      View information about this instance of the SpacesVM
  owned        Fetches all owned spaces for the address associated with the private key
  resolve      Reads a value at space/key
  resolve-file Reads a file at space/key and saves it to disk
  set          Writes a key-value pair for the given space
  set-file     Writes a file to the given space
  transfer     Transfers units to another address

Flags:
      --endpoint string           RPC endpoint for VM (default "https://api.tryspaces.xyz")
  -h, --help                      help for spaces-cli
      --private-key-file string   private key file path (default ".spaces-cli-pk")
      --verbose                   Print verbose information about operations

Use "spaces-cli [command] --help" for more information about a command.
Uploading Files
spaces-cli set-file spaceslover ~/Downloads/computer.gif -> patrick/6fe5a52f52b34fb1e07ba90bad47811c645176d0d49ef0c7a7b4b22013f676c8
spaces-cli resolve-file spaceslover/6fe5a52f52b34fb1e07ba90bad47811c645176d0d49ef0c7a7b4b22013f676c8 computer_copy.gif
spaces-cli delete-file spaceslover/6fe5a52f52b34fb1e07ba90bad47811c645176d0d49ef0c7a7b4b22013f676c8
// Client defines spacesvm client operations.
type Client interface {
	// Pings the VM.
	Ping() (bool, error)
	// Network information about this instance of the VM
	Network() (uint32, ids.ID, ids.ID, error)

	// Returns the VM genesis.
	Genesis() (*chain.Genesis, error)
	// Accepted fetches the ID of the last accepted block.
	Accepted() (ids.ID, error)

	// Returns if a space is already claimed
	Claimed(space string) (bool, error)
	// Returns the corresponding space information.
	Info(space string) (*chain.SpaceInfo, []*chain.KeyValueMeta, error)
	// Balance returns the balance of an account
	Balance(addr common.Address) (bal uint64, err error)
	// Resolve returns the value associated with a path
	Resolve(path string) (exists bool, value []byte, valueMeta *chain.ValueMeta, err error)

	// Requests the suggested price and cost from VM.
	SuggestedRawFee() (uint64, uint64, error)
	// Issues the transaction and returns the transaction ID.
	IssueRawTx(d []byte) (ids.ID, error)

	// Requests the suggested price and cost from VM, returns the input as
	// TypedData.
	SuggestedFee(i *chain.Input) (*tdata.TypedData, uint64, error)
	// Issues a human-readable transaction and returns the transaction ID.
	IssueTx(td *tdata.TypedData, sig []byte) (ids.ID, error)

	// Checks the status of the transaction, and returns "true" if confirmed.
	HasTx(id ids.ID) (bool, error)
	// Polls the transactions until its status is confirmed.
	PollTx(ctx context.Context, txID ids.ID) (confirmed bool, err error)

	// Recent actions on the network (sorted from recent to oldest)
	RecentActivity() ([]*chain.Activity, error)
	// All spaces owned by a given address
	Owned(owner common.Address) ([]string, error)
}

Public Endpoints (/public)

spacesvm.ping

<<< POST
{
  "jsonrpc": "2.0",
  "method": "spacesvm.ping",
  "params":{},
  "id": 1
}
>>> {"success":<bool>}

spacesvm.network

<<< POST
{
  "jsonrpc": "2.0",
  "method": "spacesvm.network",
  "params":{},
  "id": 1
}
>>> {"networkId":<uint32>, "subnetId":<ID>, "chainId":<ID>}

spacesvm.genesis

<<< POST
{
  "jsonrpc": "2.0",
  "method": "spacesvm.genesis",
  "params":{},
  "id": 1
}
>>> {"genesis":<genesis file>}

spacesvm.suggestedFee

Provide your intent and get back a transaction to sign.

<<< POST
{
  "jsonrpc": "2.0",
  "method": "spacesvm.suggestedFee",
  "params":{
    "input":<chain.Input (tx abstractor)>
  },
  "id": 1
}
>>> {"typedData":<EIP-712 compliant typed data for signing>,
>>> "totalCost":<uint64>}
chain.Input
{
  "type":<string>,
  "space":<string>,
  "key":<string>,
  "value":<base64 encoded>,
  "to":<hex encoded>,
  "units":<uint64>
}
Transaction Types
claim    {type,space}
lifeline {type,space,units}
set      {type,space,key,value}
delete   {type,space,key}
move     {type,space,to}
transfer {type,to,units}

spacesvm.issueTx

<<< POST
{
  "jsonrpc": "2.0",
  "method": "spacesvm.issueTx",
  "params":{
    "typedData":<EIP-712 compliant typed data>,
    "signature":<hex-encoded sig>
  },
  "id": 1
}
>>> {"txId":<ID>}
Transaction Creation Worflow
1) spacesvm.claimed {"space":"patrick"} => Yes/No
2) spacesvm.suggestedFee {"input":{"type":"claim", "space":"patrick"}} => {"typedData":<EIP-712 Typed Data>, "cost":<total fee>}
3) sign EIP-712 Typed Data
4) spacesvm.issueTx {"typedData":<from spacesvm.suggestedFee>, "signature":<sig from step 3>} => {"txId":<ID>}
5) [loop] spacesvm.hasTx {"txId":<ID>} => {"accepted":true"}

spacesvm.hasTx

<<< POST
{
  "jsonrpc": "2.0",
  "method": "spacesvm.hasTx",
  "params":{
    "txId":<transaction ID>
  },
  "id": 1
}
>>> {"accepted":<bool>}

spacesvm.lastAccepted

<<< POST
{
  "jsonrpc": "2.0",
  "method": "spacesvm.lastAccepted",
  "params":{},
  "id": 1
}
>>> {"height":<uint64>, "blockId":<ID>}

spacesvm.claimed

<<< POST
{
  "jsonrpc": "2.0",
  "method": "spacesvm.claimed",
  "params":{
    "space":<string>
  },
  "id": 1
}
>>> {"claimed":<bool>}

spacesvm.info

<<< POST
{
  "jsonrpc": "2.0",
  "method": "spacesvm.info",
  "params":{
    "space":<string>
  },
  "id": 1
}
>>> {"info":<chain.SpaceInfo>, "values":[<chain.KeyValueMeta>]}
chain.SpaceInfo
{
  "owner":<hex encoded>,
  "created":<unix>,
  "updated":<unix>,
  "expiry":<unix>,
  "units":<uint64>,
  "rawSpace":<ShortID>
}
chain.KeyValueMeta
{
  "key":<string>,
  "valueMeta":{
    "created":<unix>,
    "updated":<unix>,
    "txId":<ID>, // where value was last set
    "size":<uint64>
  }
}

spacesvm.resolve

<<< POST
{
  "jsonrpc": "2.0",
  "method": "spacesvm.resolve",
  "params":{
    "path":<string | ex:jim/twitter>
  },
  "id": 1
}
>>> {"exists":<bool>, "value":<base64 encoded>, "valueMeta":<chain.ValueMeta>}

spacesvm.balance

<<< POST
{
  "jsonrpc": "2.0",
  "method": "spacesvm.balance",
  "params":{
    "address":<hex encoded>
  },
  "id": 1
}
>>> {"balance":<uint64>}

spacesvm.recentActivity

<<< POST
{
  "jsonrpc": "2.0",
  "method": "spacesvm.recentActivity",
  "params":{},
  "id": 1
}
>>> {"activity":[<chain.Activity>,...]}
chain.Activity
{
  "timestamp":<unix>,
  "sender":<address>,
  "txId":<ID>,
  "type":<string>,
  "space":<string>,
  "key":<string>,
  "to":<hex encoded>,
  "units":<uint64>
}
Activity Types
claim    {timestamp,sender,txId,type,space}
lifeline {timestamp,sender,txId,type,space,units}
set      {timestamp,sender,txId,type,space,key,value}
delete   {timestamp,sender,txId,type,space,key}
move     {timestamp,sender,txId,type,space,to}
transfer {timestamp,sender,txId,type,to,units}
reward   {timestamp,txId,type,to,units}

spacesvm.owned

<<< POST
{
  "jsonrpc": "2.0",
  "method": "spacesvm.owned",
  "params":{
    "address":<hex encoded>
  },
  "id": 1
}
>>> {"spaces":[<string>]}

Advanced Public Endpoints (/public)

spacesvm.suggestedRawFee

Can use this to get the current fee rate.

<<< POST
{
  "jsonrpc": "2.0",
  "method": "spacesvm.suggestedRawFee",
  "params":{},
  "id": 1
}
>>> {"price":<uint64>,"cost":<uint64>}

spacesvm.issueRawTx

<<< POST
{
  "jsonrpc": "2.0",
  "method": "spacesvm.issueRawTx",
  "params":{
    "tx":<raw tx bytes>
  },
  "id": 1
}
>>> {"txId":<ID>}

Running the VM

To build the VM (and spaces-cli), run ./scripts/build.sh.

Joining the Spaces Demo

If you'd like to validate the Spaces Subnet Demo on Fuji, please follow the following steps:

You can find the genesis used for the Spaces Demo in networks/42/*.

Download and Build SpacesVM

git clone https://github.com/ava-labs/spacesvm.git;
cd spacesvm;
./scripts/build.sh

Running the above commands will generate a binary and save it at ~/spacesvm/build/sqja3uK17MJxfC7AN8nGadBw9JK5BcrsNwNynsqP5Gih8M5Bm.

Move Binary

Once the SpacesVM binary is built, you'll need to move it to AvalancheGo's plugin directory (within the --build-dir) so it can be run by your node. When building from source, this defaults to ~/avalanchego/build/plugins. This build directory is structured as:

build-dir
|_avalanchego
    |_plugins
      |_evm

To put the SpacesVM binary in the right place, run the following command (assuming the avalanchego and spacesvm repos are in the same folder):

mv ./spacesvm/build/sqja3uK17MJxfC7AN8nGadBw9JK5BcrsNwNynsqP5Gih8M5Bm ./avalanchego/build/plugins;

Add Subnet to Whitelist

Next, you'll need to provide the whitelisted-subnets argument by modifying your config file or providing an argument on startup (which tells your node to connect to the Spaces Subnet Demo). Ai42MkKqk8yjXFCpoHXw7rdTWSHiKEMqh5h8gbxwjgkCUfkrk is the subnet id for Spaces Subnet.

Example Config File:

{
  "network-id":"fuji",
  "health-check-frequency":"2s",
  "log-display-level":"INFO",
  "log-level":"INFO",
  "whitelisted-subnets":"Ai42MkKqk8yjXFCpoHXw7rdTWSHiKEMqh5h8gbxwjgkCUfkrk"
}

Example Node Args:

--whitelisted-subnets=Ai42MkKqk8yjXFCpoHXw7rdTWSHiKEMqh5h8gbxwjgkCUfkrk --network-id=fuji

Restart Node

Once you've performed the following steps, you'll need to restart your AvalancheGo node for the changes to take effect.

If you completed the steps successfully, you'll see the node print out:

INFO [01-25|16:47:04] chains/manager.go#246: creating chain:
    ID: 2AM3vsuLoJdGBGqX2ibE8RGEq4Lg7g4bot6BT1Z7B9dH5corUD
    VMID:sqja3uK17MJxfC7AN8nGadBw9JK5BcrsNwNynsqP5Gih8M5Bm
INFO [01-25|16:47:04] api/server/server.go#203: adding route /ext/bc/2JVSBoinj9C2J33VntvzYtVJNZdN2NKiwwKjcumHUWEb5DbBrm/events
INFO [01-25|16:47:04] api/server/server.go#203: adding route /ext/bc/2JVSBoinj9C2J33VntvzYtVJNZdN2NKiwwKjcumHUWEb5DbBrm
INFO [01-25|16:47:04] api/server/server.go#203: adding route /ext/bc/2JVSBoinj9C2J33VntvzYtVJNZdN2NKiwwKjcumHUWEb5DbBrm/wallet
INFO [01-25|16:47:04] <2AM3vsuLoJdGBGqX2ibE8RGEq4Lg7g4bot6BT1Z7B9dH5corUD Chain> snow/engine/snowman/transitive.go#67: initializing consensus engine
INFO [01-25|16:47:04] <2AM3vsuLoJdGBGqX2ibE8RGEq4Lg7g4bot6BT1Z7B9dH5corUD Chain> snow/engine/snowman/bootstrap/bootstrapper.go#225: Starting bootstrap...
INFO [01-25|16:47:04] <P Chain> snow/engine/snowman/bootstrap/bootstrapper.go#458: waiting for the remaining chains in this subnet to finish syncing
INFO [01-25|16:47:04] api/server/server.go#203: adding route /ext/bc/2AM3vsuLoJdGBGqX2ibE8RGEq4Lg7g4bot6BT1Z7B9dH5corUD/public
INFO [01-25|16:47:04] <2AM3vsuLoJdGBGqX2ibE8RGEq4Lg7g4bot6BT1Z7B9dH5corUD Chain> snow/engine/common/bootstrapper.go#235: Bootstrapping started syncing with 2 vertices in the accepted frontier
INFO [01-25|16:47:05] <2AM3vsuLoJdGBGqX2ibE8RGEq4Lg7g4bot6BT1Z7B9dH5corUD Chain> snow/engine/snowman/bootstrap/bootstrapper.go#419: bootstrapping fetched 69 blocks. Executing state transitions...
INFO [01-25|16:47:06] <2AM3vsuLoJdGBGqX2ibE8RGEq4Lg7g4bot6BT1Z7B9dH5corUD Chain> snow/engine/common/queue/jobs.go#181: executed 69 operations
INFO [01-25|16:47:06] <2AM3vsuLoJdGBGqX2ibE8RGEq4Lg7g4bot6BT1Z7B9dH5corUD Chain> snow/engine/snowman/transitive.go#354: bootstrapping finished with 2DUxceCx71L5TLTeLpKUQxSBVm8vTKPmFs2usAyRnusUzs4Q4M as the last accepted block

If you didn't put the SpacesVM binary in the right place, you'll see something like:

INFO [01-26|05:54:19] chains/manager.go#246: creating chain:
    ID: 2AM3vsuLoJdGBGqX2ibE8RGEq4Lg7g4bot6BT1Z7B9dH5corUD
    VMID:sqja3uK17MJxfC7AN8nGadBw9JK5BcrsNwNynsqP5Gih8M5Bm
ERROR[01-26|05:54:19] chains/manager.go#270: error creating chain 2AM3vsuLoJdGBGqX2ibE8RGEq4Lg7g4bot6BT1Z7B9dH5corUD: error while looking up VM: there is no ID with alias sqja3uK17MJxfC7AN8nGadBw9JK5BcrsNwNynsqP5Gih8M5Bm

Become a Fuji Validator

Once your node is up and running with the SpacesVM, you'll need to become a Fuji Validator. This is the exact same flow as Mainnet except you only need to stake 1 AVAX instead of 2000 AVAX.

Recall, only validators on the Primary Network (in this case Fuji) can become validators of subnets.

Submit a Validator Request

Once you've completed the above steps and your node is fully bootstrapped, submit a Spaces Demo Validator Request to be considered as a validator (everyone will be approved).

The Spaces Subnet Demo is a Permissioned Subnet and requires explicit approval from the creator to validate. In the near future, it will be possible to create permissionless subnets that anyone can join.

If you have any questions, reach out to @_patrickogrady on Twitter!

Running a local network

scripts/run.sh automatically installs avalanchego, sets up a local network, and creates a spacesvm genesis file. To build and run E2E tests, you need to set the variable E2E before it: E2E=true ./scripts/run.sh 1.7.11

See tests/e2e to see how it's set up and how its client requests are made.

# to startup a local cluster (good for development)
cd ${HOME}/go/src/github.com/ava-labs/spacesvm
./scripts/run.sh 1.7.11

# to run full e2e tests and shut down cluster afterwards
cd ${HOME}/go/src/github.com/ava-labs/spacesvm
E2E=true ./scripts/run.sh 1.7.11
# inspect cluster endpoints when ready
cat /tmp/avalanchego-v1.7.11/output.yaml
<<COMMENT
endpoint: /ext/bc/2VCAhX6vE3UnXC6s1CBPE6jJ4c4cHWMfPgCptuWS59pQ9vbeLM
logsDir: ...
pid: 12811
uris:
- http://localhost:56239
- http://localhost:56251
- http://localhost:56253
- http://localhost:56255
- http://localhost:56257
COMMENT

# ping the local cluster
curl --location --request POST 'http://localhost:61858/ext/bc/BJfusM2TpHCEfmt5i7qeE1MwVCbw5jU1TcZNz8MYUwG1PGYRL/public' \
--header 'Content-Type: application/json' \
--data-raw '{
    "jsonrpc": "2.0",
    "method": "spacesvm.ping",
    "params":{},
    "id": 1
}'
<<COMMENT
{"jsonrpc":"2.0","result":{"success":true},"id":1}
COMMENT

# resolve a path
curl --location --request POST 'http://localhost:61858/ext/bc/BJfusM2TpHCEfmt5i7qeE1MwVCbw5jU1TcZNz8MYUwG1PGYRL/public' \
--header 'Content-Type: application/json' \
--data-raw '{
    "jsonrpc": "2.0",
    "method": "spacesvm.resolve",
    "params":{
      "path": "coolperson/twitter"
    },
    "id": 1
}'
<<COMMENT
{"jsonrpc":"2.0","result":{"exists":true, "value":"....", "valueMeta":{....}},"id":1}
COMMENT

# to terminate the cluster
kill 12811

Deploying Your Own Network

Anyone can deploy their own instance of the SpacesVM as a subnet on Avalanche. All you need to do is compile it, create a genesis, and send a few txs to the P-Chain.

You can do this by following the subnet tutorial or by using the subnet-cli.

spacesvm's People

Contributors

aaronbuchwald avatar ceyonur avatar darioush avatar dhrubabasu avatar felipemadero avatar gyuho avatar hexfusion avatar patrick-ogrady avatar stephenbuttolph avatar yulin-dong avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

spacesvm's Issues

Tree Resolver

Have a "preferred" format for uploading dense trees to get around the file limit. This should be done unaware to the core protocol (don't need special values or anything).

resolve-file space/key
upload-file space (key is produced from hash)

Should verify that keys retrieved of hash length == hash

Make 1 root node and all children on the same level.

airdrop: High memory usage

We found in Ci that the use of airdrop[1] functionality would oom nodes due to high memory usage. This issue is to track the perf issue and possibly correct so that we can re-enable in Ci.

[1]

func (g *Genesis) Load(db database.Database, airdropData []byte) error {

ref. #131

run.sh script not working

I am trying to test the VM and the run script does not work in both testing or dev mode, it is stuck at waiting for all nodes to report healthy..., other times I get

{"level":"warn","ts":"2022-05-31T09:20:37.850Z","caller":"server/server.go:387","msg":"start custom VMs failed to complete","error":"context deadline exceeded"}
panic: context deadline exceeded

goroutine 49 [running]:
github.com/ava-labs/avalanche-network-runner/server.(*server).Start.func1()
        /home/runner/work/avalanche-network-runner/avalanche-network-runner/server/server.go:388 +0x756
created by github.com/ava-labs/avalanche-network-runner/server.(*server).Start
        /home/runner/work/avalanche-network-runner/avalanche-network-runner/server/server.go:358 +0x19e5

can you please fix the script or is it something else that I need to do?

Another Issue I have is that the e2e tests are triggered no matter if I start the script with E2E=true or not and they always fail because of the connection to the nodes is refused

Hashed Value Support

If the key length is ids.ID, verify that the key == hash(value).

This is VERY VERY useful for NFT-related efforts.

Reuse Block Data for Values

SetTx.Value are copied from the block into an additional DB when a block is verified. We should instead find a way to pull value data from the saved block to avoid unnecessary copying.

Alternatively, we could "thin" blocks when they are synced and then re-populate them if they are requested with what is stored in the value (although this could get complicated because values could be overwritten). => we could store as hash(block, tx_hash) pretty easily.

Importantly, this allow allow us to easily externalize the "value" storage at some point to an external service/DB.

TL;DR find a way to store values once.

Error When I tried to visit my space

I'm claimed an space but when I tried to visit it the console shows me and error
Steps to replicate the error:
Connect Metamask Account (Avalanche Mainnet-C)
Search an namespace availability
Claim the space
Firm the transaction
Visit my Spaces

Grabacion.de.pantalla.2022-01-20.a.la.s.13.34.41.mov

Spaces Stats Endpoint

It would be nice to be able to fetch:

  • number of claimed spaces
  • number of expired spaces
  • number of moved spaces
  • number of set keys
  • number of deleted keys
  • total value set
  • total value expired

This would involve a database migration for existing spacesvm's and a couple new singleton db values.

Airdrop Hash

Add the ability to embed a large aidrop file.

Light Syncing Mode

Instead of storing the value to the DB, allow node operators to just store the length of the value (minimum needed for block execution) for keys/prefixes they don't care about.

This allows for very lightweight running of nodes and/or just consensus nodes.

This mode should also delete historical blocks (if the rpcchainvm supports this).

We could also change the canonical form of the block to not actually include values. Instead, they could be attached and fetched separately for anyone that wants to validate their correctness/serve data.

Remove Coarse Locking from API

We should implement granular locking to prevent API calls from blocking consensus operations:

spacesvm/vm/vm.go

Lines 245 to 249 in 22a78d6

var lock common.LockOption = common.WriteLock
if len(lockOption) != 0 {
lock = lockOption[0]
}
return &common.HTTPHandler{LockOptions: lock, Handler: server}, nil

Add Lottery Rewards

Pick a random prefix inside of ExecuteTx to give a reward to. Put it in tx so that it isn't a function of how many blocks are produced.

Delete Prefixes During Bootstrapping

Once the rpcchainvm exposes bootstrapping status, we should use it to determine whether we should mark expired prefixes for sync/async cleanup.

We would likely prefer to explicitly delete prefixes during bootstrapping instead of building up a large async queue.

Verifiably Prevent Pruning for Consensus Nodes

Options:

  • When a prefix expires, include the value of a randomly selected key in state.
  • Depending on time + hash, include a random value from state in the block hash.
  • When a key's value is deleted, include the hash of the previous data. => will just result in people not accepting txs with deletions.

Block Builder Bonus

Allow the creator of a block to optionally name a prefix that will receive additional life for validating a prefix.

If the prefix doesn't exist, we should explicitly consider it an invalid block.

Should be possible to set over RPC.

Avoid Gossiping Large Values

If we enlarge the max value size to support media files, we need to find a way to avoid gossiping them aggressively to the rest of the network.

We could consider automatically replacing them with a hash within the value in the node and then querying the rest of the network for their actual value for RPC responses (this would ensure blocks never get too heavy).

Variable Claim Cost

The shorter the prefix you are trying to claim, the more work it should cost. Likewise, the more it should cost to extend its lifespan.

This change may require us to separate Units into WorkUnits (how much mining needs to be done) and LoadUnits (how much it affects target units for fees...we want to charge the user more but it should't affect algo determining load we are processing).

Update Miner ETA dynamically

We should be able to dynamically update the ETA based on the number of expected hashes and the rate at which we compute hashes.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.