mirror of https://github.com/poanetwork/gecko.git
merged
This commit is contained in:
commit
11f66e1394
|
@ -0,0 +1,6 @@
|
|||
#!/bin/bash
|
||||
|
||||
set -ev
|
||||
|
||||
docker run --rm -v "$PWD:$GECKO_HOME" $DOCKERHUB_REPO:$COMMIT bash "$GECKO_HOME/scripts/build_test.sh"
|
||||
docker run --rm -v "$PWD:$GECKO_HOME" $DOCKERHUB_REPO:$COMMIT bash "$GECKO_HOME/scripts/build.sh"
|
|
@ -0,0 +1,9 @@
|
|||
#!/bin/bash
|
||||
|
||||
set -ev
|
||||
|
||||
go get -d -t -v github.com/ava-labs/gecko/...
|
||||
|
||||
cd $GOPATH/src/github.com/ava-labs/gecko
|
||||
./scripts/build_test.sh
|
||||
./scripts/build.sh
|
|
@ -0,0 +1,6 @@
|
|||
# https://editorconfig.org/
|
||||
|
||||
[*]
|
||||
end_of_line = lf
|
||||
insert_final_newline = true
|
||||
trim_trailing_newspace = true
|
|
@ -24,3 +24,5 @@ Which OS you used to reveal the bug.
|
|||
|
||||
**Additional context**
|
||||
Add any other context about the problem here.
|
||||
|
||||
By submitting this issue I agree to the [Terms and Conditions](https://files.avalabs.org/legal/bug_hunt_q2_2020_terms.pdf) of the [Developer Accelerator Program](https://avalabs.org/dap).
|
||||
|
|
|
@ -0,0 +1,24 @@
|
|||
name: Ansible Lint
|
||||
on:
|
||||
- pull_request
|
||||
- push
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v2
|
||||
|
||||
- name: Lint Ansible playbooks
|
||||
# Lastest commit, as of 30 Apr 2020
|
||||
uses: ansible/ansible-lint-action@6c8c141
|
||||
with:
|
||||
targets: |
|
||||
scripts/ansible/kill_playbook.yml
|
||||
scripts/ansible/ping_playbook.yml
|
||||
scripts/ansible/restart_playbook.yml
|
||||
scripts/ansible/update_playbook.yml
|
||||
|
||||
args:
|
||||
-c scripts/ansible/.ansible-lint
|
|
@ -18,6 +18,9 @@ awscpu
|
|||
# Output of the go coverage tool, specifically when used with LiteIDE
|
||||
*.out
|
||||
|
||||
# ignore GoLand metafiles directory
|
||||
.idea/
|
||||
|
||||
*logs/
|
||||
|
||||
.vscode*
|
||||
|
@ -26,6 +29,7 @@ awscpu
|
|||
*.ava
|
||||
|
||||
db*
|
||||
|
||||
*cpu[0-9]*
|
||||
*mem[0-9]*
|
||||
*lock[0-9]*
|
||||
|
@ -42,4 +46,9 @@ db*
|
|||
bin/
|
||||
build/
|
||||
|
||||
*/mykey/staker.*
|
||||
keys/staker.*
|
||||
|
||||
!*.go
|
||||
!*.proto
|
||||
|
||||
plugins/
|
27
.travis.yml
27
.travis.yml
|
@ -1,5 +1,13 @@
|
|||
dist: bionic
|
||||
language: go
|
||||
go:
|
||||
- 1.13.x
|
||||
|
||||
jobs:
|
||||
include:
|
||||
- os: linux
|
||||
dist: bionic
|
||||
- os: osx
|
||||
osx_image: xcode11.4
|
||||
services:
|
||||
- docker
|
||||
env:
|
||||
|
@ -10,7 +18,16 @@ env:
|
|||
- DOCKERHUB_REPO=avaplatform/gecko
|
||||
- secure: "L/A9+re0NEKP6EV6H9RcTGiDhX3WMvsiWrkRKDYKqnviqbjY30RK6EM4vvjrM4Lrw2QwsO3YKgnku3+zioE/TxEZFkpkbjNUXru0nYBrWAg1TKVsDXnYaIZkHUejfryST3E8N7F4Hx6zCtGEO0sEdUeKuT+MNUIuHezHooTgGzDjMogm70EWMFjQHc7VucTJu7dWU1RBPjovWQ0q9qflrtCpbrvXFIiihQQ1PQha1Q2C4wLakKuLbhhSafue90Mnyss0blaPHy/tyewcASJu4vsGTKRBn0DzttlkNTwuD6+nKrbmJY0ohunnkVFzYjrZAw1gyN+DCDb/lPbz4ZDItKPwrIUPEtL5xuUOrxUZPUh+0io3Q2d6rjaqkdGjd1KQXzbnW1mn0BxX3d3b2UpIqhBn9umYYjHBKnMuoRiTK33b7U9+LF3K84+tEvVDCPeHs/mw6Inp5jGRSravnM6yPQ6feGzogs4+3EMzZXxnkngKFKCsnd67Oe9xfV9amOU2aQAx4jaAwlPjEpBEkUa8YKx3lPznvmUk1QsNCUbLjdSl5JBaXojLJoiuPbj29hp4S5AXXgn+3Hvwk3ndcFCxi6/l1W9mjYSOtFqg3EAUdF4EgnA/ykQg9ZokkoKY0+qgOzG2bKOAYuCDWeGr7P1apToh00ccsQXL81nVPiq7uDw="
|
||||
- secure: "zfTm7tJBYiPYrli76d4Ep6Lc2TJQ8Xv//+7OoqTA/aIf6YJDHe05f2GFTWAHG2iOIix/yjwHYwnhyIW66eWPb+Ujejnmh4eXlYZFufX9J5jUpDpbFu/+ybOLgE1Tmr0je0ycneSMe/NAaS74nWU1wnP34/cEE4sYL7TJyhwbeEtgz3cbSWwkpdvHFbXCjSOA196jdIYYUwsnqU9yycAG+2WUSk3DHHzzdtMrh/UOH2r1VFyp5US0zmbW90WkWX+o3TIlzZJgTUGQRNnWKq95Mrh1EQotxgL6CJ8NkfY4bVAGAhusPjdjscJsHxfY93WRMH64TzPYYp0zdibatH0ztyhnZPXVKqv+AIIVTEW+xWv5V18kTQAd1uBW103NFacbgXhIGWtbFcN9g1+ws29HROMclYs7ci6+72Qnq0eL55huqSyFx6+InhYwn+LfJmaBcGW4wx1umdp505M0obZ4ghlyn6b0pDYmqsu1XyBC3mjUTFbwlQmWE2Fize4L5o+DdH4ZDc9japF9ntxIMvO+b3nOicr7tplY2AGp61bB89o3dUAFlN5mDaEJotiAuFk5mo244rY1FjSzyGiKkA3M9TkTIbgcbN098hOJoMCYybH7yqiPwNnZiFvUuYjHuC5D1kIYBWuqqO0iVcbIZn0rV2jyzbVFlhFVk2clTZGhkrY="
|
||||
before_install: .ci/before_install.sh
|
||||
install: DOCKER_BUILDKIT=1 docker build --progress plain --ssh default -t $DOCKERHUB_REPO:$COMMIT .
|
||||
script: docker run --rm -v "$PWD:$GECKO_HOME" $DOCKERHUB_REPO:$COMMIT bash "$GECKO_HOME/scripts/build_test.sh"
|
||||
after_success: .ci/after_success.sh
|
||||
before_install:
|
||||
- if [ "$TRAVIS_OS_NAME" = "linux" ]; then .ci/before_install_linux.sh; fi
|
||||
|
||||
install:
|
||||
- if [ "$TRAVIS_OS_NAME" = "linux" ]; then DOCKER_BUILDKIT=1 docker build --progress plain -t $DOCKERHUB_REPO:$COMMIT . ; fi
|
||||
|
||||
script:
|
||||
- if [ "$TRAVIS_OS_NAME" = "osx" ]; then .ci/runscript_osx.sh; fi
|
||||
- if [ "$TRAVIS_OS_NAME" = "linux" ]; then .ci/runscript_linux.sh; fi
|
||||
|
||||
#Need to push to docker hub only from one build
|
||||
after_success:
|
||||
- if [ "$TRAVIS_OS_NAME" = "linux" ]; then .ci/after_success.sh; fi
|
||||
|
|
|
@ -2,14 +2,8 @@
|
|||
|
||||
FROM golang:1.13.4-buster
|
||||
|
||||
RUN apt-get update && apt-get install -y libssl-dev libuv1-dev curl cmake
|
||||
|
||||
RUN mkdir -p /go/src/github.com/ava-labs
|
||||
|
||||
# Because downloading ethereum takes long it is done separately, so that the docker
|
||||
# layer, when cached can be re-used
|
||||
RUN go get -t -v github.com/ava-labs/go-ethereum
|
||||
|
||||
WORKDIR $GOPATH/src/github.com/ava-labs/
|
||||
COPY . gecko
|
||||
|
||||
|
|
45
README.md
45
README.md
|
@ -1,4 +1,4 @@
|
|||
# gecko
|
||||
# Gecko
|
||||
|
||||
## Installation
|
||||
|
||||
|
@ -11,31 +11,11 @@ AVA is an incredibly lightweight protocol, so the minimum computer requirements
|
|||
|
||||
### Native Install
|
||||
|
||||
Ubuntu users need the following libraries:
|
||||
|
||||
* libssl-dev
|
||||
* libuv1-dev
|
||||
* cmake
|
||||
* make
|
||||
* curl
|
||||
* g++
|
||||
|
||||
Install the libraries:
|
||||
|
||||
```sh
|
||||
sudo apt-get install libssl-dev libuv1-dev cmake make curl g++
|
||||
```
|
||||
|
||||
#### Downloading Gecko Source Code
|
||||
|
||||
Clone the Gecko repository:
|
||||
|
||||
```sh
|
||||
cd $GOPATH
|
||||
mkdir -p src/github.com/ava-labs
|
||||
cd src/github.com/ava-labs
|
||||
git clone https://github.com/ava-labs/gecko.git
|
||||
cd gecko
|
||||
go get -v -d github.com/ava-labs/gecko/...
|
||||
cd $GOPATH/src/github.com/ava-labs/gecko
|
||||
```
|
||||
|
||||
#### Building the Gecko Executable
|
||||
|
@ -46,7 +26,7 @@ Build Gecko using the build script:
|
|||
./scripts/build.sh
|
||||
```
|
||||
|
||||
The Gecko binary, named `ava`, is in the `build` directory.
|
||||
The Gecko binary, named `ava`, is in the `build` directory.
|
||||
|
||||
### Docker Install
|
||||
|
||||
|
@ -54,7 +34,7 @@ The Gecko binary, named `ava`, is in the `build` directory.
|
|||
- Build the docker image of latest gecko branch by `scripts/build_image.sh`.
|
||||
- Check the built image by `docker image ls`, you should see some image tagged
|
||||
`gecko-xxxxxxxx`, where `xxxxxxxx` is the commit id of the Gecko source it was built from.
|
||||
- Test Gecko by `docker run -ti -p 9651:9651 gecko-xxxxxxxx /gecko/build/ava
|
||||
- Test Gecko by `docker run -ti -p 9650:9650 -p 9651:9651 gecko-xxxxxxxx /gecko/build/ava
|
||||
--public-ip=127.0.0.1 --snow-sample-size=1 --snow-quorum-size=1 --staking-tls-enabled=false`. (For a production deployment,
|
||||
you may want to extend the docker image with required credentials for
|
||||
staking and TLS.)
|
||||
|
@ -75,10 +55,11 @@ You may see a few warnings. These are OK.
|
|||
You can use `Ctrl + C` to kill the node.
|
||||
|
||||
If you want to specify your log level. You should set `--log-level` to one of the following values, in decreasing order of logging.
|
||||
* `--log-level=verbo`
|
||||
* `--log-level=debug`
|
||||
* `--log-level=info`
|
||||
* `--log-level=warn`
|
||||
* `--log-level=error`
|
||||
* `--log-level=fatal`
|
||||
* `--log-level=off`
|
||||
|
||||
- `--log-level=verbo`
|
||||
- `--log-level=debug`
|
||||
- `--log-level=info`
|
||||
- `--log-level=warn`
|
||||
- `--log-level=error`
|
||||
- `--log-level=fatal`
|
||||
- `--log-level=off`
|
||||
|
|
|
@ -1,27 +0,0 @@
|
|||
// (c) 2019-2020, Ava Labs, Inc. All rights reserved.
|
||||
// See the file LICENSE for licensing terms.
|
||||
|
||||
package admin
|
||||
|
||||
import (
|
||||
"sort"
|
||||
|
||||
"github.com/ava-labs/gecko/utils"
|
||||
)
|
||||
|
||||
// Peerable can return a group of peers
|
||||
type Peerable interface{ Peers() []utils.IPDesc }
|
||||
|
||||
// Networking provides helper methods for tracking the current network state
|
||||
type Networking struct{ peers Peerable }
|
||||
|
||||
// Peers returns the current peers
|
||||
func (n *Networking) Peers() ([]string, error) {
|
||||
ipDescs := n.peers.Peers()
|
||||
ips := make([]string, len(ipDescs))
|
||||
for i, ipDesc := range ipDescs {
|
||||
ips[i] = ipDesc.String()
|
||||
}
|
||||
sort.Strings(ips)
|
||||
return ips, nil
|
||||
}
|
|
@ -10,42 +10,71 @@ import (
|
|||
|
||||
"github.com/ava-labs/gecko/api"
|
||||
"github.com/ava-labs/gecko/chains"
|
||||
"github.com/ava-labs/gecko/genesis"
|
||||
"github.com/ava-labs/gecko/ids"
|
||||
"github.com/ava-labs/gecko/network"
|
||||
"github.com/ava-labs/gecko/snow/engine/common"
|
||||
"github.com/ava-labs/gecko/utils/logging"
|
||||
"github.com/ava-labs/gecko/version"
|
||||
|
||||
cjson "github.com/ava-labs/gecko/utils/json"
|
||||
)
|
||||
|
||||
// Admin is the API service for node admin management
|
||||
type Admin struct {
|
||||
version version.Version
|
||||
nodeID ids.ShortID
|
||||
networkID uint32
|
||||
log logging.Logger
|
||||
networking Networking
|
||||
networking network.Network
|
||||
performance Performance
|
||||
chainManager chains.Manager
|
||||
httpServer *api.Server
|
||||
}
|
||||
|
||||
// NewService returns a new admin API service
|
||||
func NewService(networkID uint32, log logging.Logger, chainManager chains.Manager, peers Peerable, httpServer *api.Server) *common.HTTPHandler {
|
||||
func NewService(version version.Version, nodeID ids.ShortID, networkID uint32, log logging.Logger, chainManager chains.Manager, peers network.Network, httpServer *api.Server) *common.HTTPHandler {
|
||||
newServer := rpc.NewServer()
|
||||
codec := cjson.NewCodec()
|
||||
newServer.RegisterCodec(codec, "application/json")
|
||||
newServer.RegisterCodec(codec, "application/json;charset=UTF-8")
|
||||
newServer.RegisterService(&Admin{
|
||||
version: version,
|
||||
nodeID: nodeID,
|
||||
networkID: networkID,
|
||||
log: log,
|
||||
chainManager: chainManager,
|
||||
networking: Networking{
|
||||
peers: peers,
|
||||
},
|
||||
httpServer: httpServer,
|
||||
networking: peers,
|
||||
httpServer: httpServer,
|
||||
}, "admin")
|
||||
return &common.HTTPHandler{Handler: newServer}
|
||||
}
|
||||
|
||||
// GetNetworkIDArgs are the arguments for calling GetNetworkID
|
||||
type GetNetworkIDArgs struct{}
|
||||
// GetNodeVersionReply are the results from calling GetNodeVersion
|
||||
type GetNodeVersionReply struct {
|
||||
Version string `json:"version"`
|
||||
}
|
||||
|
||||
// GetNodeVersion returns the version this node is running
|
||||
func (service *Admin) GetNodeVersion(_ *http.Request, _ *struct{}, reply *GetNodeVersionReply) error {
|
||||
service.log.Debug("Admin: GetNodeVersion called")
|
||||
|
||||
reply.Version = service.version.String()
|
||||
return nil
|
||||
}
|
||||
|
||||
// GetNodeIDReply are the results from calling GetNodeID
|
||||
type GetNodeIDReply struct {
|
||||
NodeID ids.ShortID `json:"nodeID"`
|
||||
}
|
||||
|
||||
// GetNodeID returns the node ID of this node
|
||||
func (service *Admin) GetNodeID(_ *http.Request, _ *struct{}, reply *GetNodeIDReply) error {
|
||||
service.log.Debug("Admin: GetNodeID called")
|
||||
|
||||
reply.NodeID = service.nodeID
|
||||
return nil
|
||||
}
|
||||
|
||||
// GetNetworkIDReply are the results from calling GetNetworkID
|
||||
type GetNetworkIDReply struct {
|
||||
|
@ -53,13 +82,26 @@ type GetNetworkIDReply struct {
|
|||
}
|
||||
|
||||
// GetNetworkID returns the network ID this node is running on
|
||||
func (service *Admin) GetNetworkID(r *http.Request, args *GetNetworkIDArgs, reply *GetNetworkIDReply) error {
|
||||
func (service *Admin) GetNetworkID(_ *http.Request, _ *struct{}, reply *GetNetworkIDReply) error {
|
||||
service.log.Debug("Admin: GetNetworkID called")
|
||||
|
||||
reply.NetworkID = cjson.Uint32(service.networkID)
|
||||
return nil
|
||||
}
|
||||
|
||||
// GetNetworkNameReply is the result from calling GetNetworkName
|
||||
type GetNetworkNameReply struct {
|
||||
NetworkName string `json:"networkName"`
|
||||
}
|
||||
|
||||
// GetNetworkName returns the network name this node is running on
|
||||
func (service *Admin) GetNetworkName(_ *http.Request, _ *struct{}, reply *GetNetworkNameReply) error {
|
||||
service.log.Debug("Admin: GetNetworkName called")
|
||||
|
||||
reply.NetworkName = genesis.NetworkName(service.networkID)
|
||||
return nil
|
||||
}
|
||||
|
||||
// GetBlockchainIDArgs are the arguments for calling GetBlockchainID
|
||||
type GetBlockchainIDArgs struct {
|
||||
Alias string `json:"alias"`
|
||||
|
@ -71,7 +113,7 @@ type GetBlockchainIDReply struct {
|
|||
}
|
||||
|
||||
// GetBlockchainID returns the blockchain ID that resolves the alias that was supplied
|
||||
func (service *Admin) GetBlockchainID(r *http.Request, args *GetBlockchainIDArgs, reply *GetBlockchainIDReply) error {
|
||||
func (service *Admin) GetBlockchainID(_ *http.Request, args *GetBlockchainIDArgs, reply *GetBlockchainIDReply) error {
|
||||
service.log.Debug("Admin: GetBlockchainID called")
|
||||
|
||||
bID, err := service.chainManager.Lookup(args.Alias)
|
||||
|
@ -79,21 +121,16 @@ func (service *Admin) GetBlockchainID(r *http.Request, args *GetBlockchainIDArgs
|
|||
return err
|
||||
}
|
||||
|
||||
// PeersArgs are the arguments for calling Peers
|
||||
type PeersArgs struct{}
|
||||
|
||||
// PeersReply are the results from calling Peers
|
||||
type PeersReply struct {
|
||||
Peers []string `json:"peers"`
|
||||
Peers []network.PeerID `json:"peers"`
|
||||
}
|
||||
|
||||
// Peers returns the list of current validators
|
||||
func (service *Admin) Peers(r *http.Request, args *PeersArgs, reply *PeersReply) error {
|
||||
func (service *Admin) Peers(_ *http.Request, _ *struct{}, reply *PeersReply) error {
|
||||
service.log.Debug("Admin: Peers called")
|
||||
|
||||
peers, err := service.networking.Peers()
|
||||
reply.Peers = peers
|
||||
return err
|
||||
reply.Peers = service.networking.Peers()
|
||||
return nil
|
||||
}
|
||||
|
||||
// StartCPUProfilerArgs are the arguments for calling StartCPUProfiler
|
||||
|
@ -107,22 +144,19 @@ type StartCPUProfilerReply struct {
|
|||
}
|
||||
|
||||
// StartCPUProfiler starts a cpu profile writing to the specified file
|
||||
func (service *Admin) StartCPUProfiler(r *http.Request, args *StartCPUProfilerArgs, reply *StartCPUProfilerReply) error {
|
||||
func (service *Admin) StartCPUProfiler(_ *http.Request, args *StartCPUProfilerArgs, reply *StartCPUProfilerReply) error {
|
||||
service.log.Debug("Admin: StartCPUProfiler called with %s", args.Filename)
|
||||
reply.Success = true
|
||||
return service.performance.StartCPUProfiler(args.Filename)
|
||||
}
|
||||
|
||||
// StopCPUProfilerArgs are the arguments for calling StopCPUProfiler
|
||||
type StopCPUProfilerArgs struct{}
|
||||
|
||||
// StopCPUProfilerReply are the results from calling StopCPUProfiler
|
||||
type StopCPUProfilerReply struct {
|
||||
Success bool `json:"success"`
|
||||
}
|
||||
|
||||
// StopCPUProfiler stops the cpu profile
|
||||
func (service *Admin) StopCPUProfiler(r *http.Request, args *StopCPUProfilerArgs, reply *StopCPUProfilerReply) error {
|
||||
func (service *Admin) StopCPUProfiler(_ *http.Request, _ *struct{}, reply *StopCPUProfilerReply) error {
|
||||
service.log.Debug("Admin: StopCPUProfiler called")
|
||||
reply.Success = true
|
||||
return service.performance.StopCPUProfiler()
|
||||
|
@ -139,7 +173,7 @@ type MemoryProfileReply struct {
|
|||
}
|
||||
|
||||
// MemoryProfile runs a memory profile writing to the specified file
|
||||
func (service *Admin) MemoryProfile(r *http.Request, args *MemoryProfileArgs, reply *MemoryProfileReply) error {
|
||||
func (service *Admin) MemoryProfile(_ *http.Request, args *MemoryProfileArgs, reply *MemoryProfileReply) error {
|
||||
service.log.Debug("Admin: MemoryProfile called with %s", args.Filename)
|
||||
reply.Success = true
|
||||
return service.performance.MemoryProfile(args.Filename)
|
||||
|
@ -156,7 +190,7 @@ type LockProfileReply struct {
|
|||
}
|
||||
|
||||
// LockProfile runs a mutex profile writing to the specified file
|
||||
func (service *Admin) LockProfile(r *http.Request, args *LockProfileArgs, reply *LockProfileReply) error {
|
||||
func (service *Admin) LockProfile(_ *http.Request, args *LockProfileArgs, reply *LockProfileReply) error {
|
||||
service.log.Debug("Admin: LockProfile called with %s", args.Filename)
|
||||
reply.Success = true
|
||||
return service.performance.LockProfile(args.Filename)
|
||||
|
@ -174,7 +208,7 @@ type AliasReply struct {
|
|||
}
|
||||
|
||||
// Alias attempts to alias an HTTP endpoint to a new name
|
||||
func (service *Admin) Alias(r *http.Request, args *AliasArgs, reply *AliasReply) error {
|
||||
func (service *Admin) Alias(_ *http.Request, args *AliasArgs, reply *AliasReply) error {
|
||||
service.log.Debug("Admin: Alias called with URL: %s, Alias: %s", args.Endpoint, args.Alias)
|
||||
reply.Success = true
|
||||
return service.httpServer.AddAliasesWithReadLock(args.Endpoint, args.Alias)
|
||||
|
@ -207,3 +241,17 @@ func (service *Admin) AliasChain(_ *http.Request, args *AliasChainArgs, reply *A
|
|||
reply.Success = true
|
||||
return service.httpServer.AddAliasesWithReadLock("bc/"+chainID.String(), "bc/"+args.Alias)
|
||||
}
|
||||
|
||||
// StacktraceArgs are the arguments for calling Stacktrace
|
||||
type StacktraceArgs struct{}
|
||||
|
||||
// StacktraceReply are the results from calling Stacktrace
|
||||
type StacktraceReply struct {
|
||||
Stacktrace string `json:"stacktrace"`
|
||||
}
|
||||
|
||||
// Stacktrace returns the current global stacktrace
|
||||
func (service *Admin) Stacktrace(_ *http.Request, _ *struct{}, reply *StacktraceReply) error {
|
||||
reply.Stacktrace = logging.Stacktrace{Global: true}.String()
|
||||
return nil
|
||||
}
|
||||
|
|
|
@ -0,0 +1,74 @@
|
|||
// (c) 2020, Ava Labs, Inc. All rights reserved.
|
||||
// See the file LICENSE for licensing terms.
|
||||
|
||||
package health
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"time"
|
||||
)
|
||||
|
||||
var (
|
||||
// ErrHeartbeatNotDetected is returned from a HeartbeatCheckFn when the
|
||||
// heartbeat has not been detected recently enough
|
||||
ErrHeartbeatNotDetected = errors.New("heartbeat not detected")
|
||||
)
|
||||
|
||||
// CheckFn returns optional status information and an error indicating health or
|
||||
// non-health
|
||||
type CheckFn func() (interface{}, error)
|
||||
|
||||
// Check defines a single health check that we want to monitor and consider as
|
||||
// part of our wider healthiness
|
||||
type Check struct {
|
||||
// Name is the identifier for this check and must be unique among all Checks
|
||||
Name string
|
||||
|
||||
// CheckFn is the function to call to perform the the health check
|
||||
CheckFn CheckFn
|
||||
|
||||
// ExecutionPeriod is the duration to wait between executions of this Check
|
||||
ExecutionPeriod time.Duration
|
||||
|
||||
// InitialDelay is the duration to wait before executing the first time
|
||||
InitialDelay time.Duration
|
||||
|
||||
// InitiallyPassing is whether or not to consider the Check healthy before the
|
||||
// initial execution
|
||||
InitiallyPassing bool
|
||||
}
|
||||
|
||||
// gosundheitCheck implements the health.Check interface backed by a CheckFn
|
||||
type gosundheitCheck struct {
|
||||
name string
|
||||
checkFn CheckFn
|
||||
}
|
||||
|
||||
// Name implements the health.Check interface by returning a unique name
|
||||
func (c gosundheitCheck) Name() string { return c.name }
|
||||
|
||||
// Execute implements the health.Check interface by executing the checkFn and
|
||||
// returning the results
|
||||
func (c gosundheitCheck) Execute() (interface{}, error) { return c.checkFn() }
|
||||
|
||||
// Heartbeater provides a getter to the most recently observed heartbeat
|
||||
type Heartbeater interface {
|
||||
GetHeartbeat() int64
|
||||
}
|
||||
|
||||
// HeartbeatCheckFn returns a CheckFn that checks the given heartbeater has
|
||||
// pulsed within the given duration
|
||||
func HeartbeatCheckFn(hb Heartbeater, max time.Duration) CheckFn {
|
||||
return func() (data interface{}, err error) {
|
||||
// Get the heartbeat and create a data set to return to the caller
|
||||
hb := hb.GetHeartbeat()
|
||||
data = map[string]int64{"heartbeat": hb}
|
||||
|
||||
// If the current time is after the last known heartbeat + the limit then
|
||||
// mark our check as failed
|
||||
if time.Unix(hb, 0).Add(max).Before(time.Now()) {
|
||||
err = ErrHeartbeatNotDetected
|
||||
}
|
||||
return data, err
|
||||
}
|
||||
}
|
|
@ -0,0 +1,80 @@
|
|||
// (c) 2020, Ava Labs, Inc. All rights reserved.
|
||||
// See the file LICENSE for licensing terms.
|
||||
|
||||
package health
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"time"
|
||||
|
||||
"github.com/AppsFlyer/go-sundheit"
|
||||
"github.com/ava-labs/gecko/snow/engine/common"
|
||||
"github.com/ava-labs/gecko/utils/json"
|
||||
"github.com/ava-labs/gecko/utils/logging"
|
||||
"github.com/gorilla/rpc/v2"
|
||||
)
|
||||
|
||||
// defaultCheckOpts is a Check whose properties represent a default Check
|
||||
var defaultCheckOpts = Check{ExecutionPeriod: time.Minute}
|
||||
|
||||
// Health observes a set of vital signs and makes them available through an HTTP
|
||||
// API.
|
||||
type Health struct {
|
||||
log logging.Logger
|
||||
health health.Health
|
||||
}
|
||||
|
||||
// NewService creates a new Health service
|
||||
func NewService(log logging.Logger) *Health {
|
||||
return &Health{log, health.New()}
|
||||
}
|
||||
|
||||
// Handler returns an HTTPHandler providing RPC access to the Health service
|
||||
func (h *Health) Handler() *common.HTTPHandler {
|
||||
newServer := rpc.NewServer()
|
||||
codec := json.NewCodec()
|
||||
newServer.RegisterCodec(codec, "application/json")
|
||||
newServer.RegisterCodec(codec, "application/json;charset=UTF-8")
|
||||
newServer.RegisterService(h, "health")
|
||||
return &common.HTTPHandler{LockOptions: common.NoLock, Handler: newServer}
|
||||
}
|
||||
|
||||
// RegisterHeartbeat adds a check with default options and a CheckFn that checks
|
||||
// the given heartbeater for a recent heartbeat
|
||||
func (h *Health) RegisterHeartbeat(name string, hb Heartbeater, max time.Duration) error {
|
||||
return h.RegisterCheckFunc(name, HeartbeatCheckFn(hb, max))
|
||||
}
|
||||
|
||||
// RegisterCheckFunc adds a Check with default options and the given CheckFn
|
||||
func (h *Health) RegisterCheckFunc(name string, checkFn CheckFn) error {
|
||||
check := defaultCheckOpts
|
||||
check.Name = name
|
||||
check.CheckFn = checkFn
|
||||
return h.RegisterCheck(check)
|
||||
}
|
||||
|
||||
// RegisterCheck adds the given Check
|
||||
func (h *Health) RegisterCheck(c Check) error {
|
||||
return h.health.RegisterCheck(&health.Config{
|
||||
InitialDelay: c.InitialDelay,
|
||||
ExecutionPeriod: c.ExecutionPeriod,
|
||||
InitiallyPassing: c.InitiallyPassing,
|
||||
Check: gosundheitCheck{c.Name, c.CheckFn},
|
||||
})
|
||||
}
|
||||
|
||||
// GetLivenessArgs are the arguments for GetLiveness
|
||||
type GetLivenessArgs struct{}
|
||||
|
||||
// GetLivenessReply is the response for GetLiveness
|
||||
type GetLivenessReply struct {
|
||||
Checks map[string]health.Result `json:"checks"`
|
||||
Healthy bool `json:"healthy"`
|
||||
}
|
||||
|
||||
// GetLiveness returns a summation of the health of the node
|
||||
func (h *Health) GetLiveness(_ *http.Request, _ *GetLivenessArgs, reply *GetLivenessReply) error {
|
||||
h.log.Debug("Health: GetLiveness called")
|
||||
reply.Checks, reply.Healthy = h.health.Results()
|
||||
return nil
|
||||
}
|
|
@ -8,11 +8,14 @@ import (
|
|||
"fmt"
|
||||
"net/http"
|
||||
"sync"
|
||||
"testing"
|
||||
|
||||
"github.com/gorilla/rpc/v2"
|
||||
|
||||
"github.com/ava-labs/gecko/chains/atomic"
|
||||
"github.com/ava-labs/gecko/database"
|
||||
"github.com/ava-labs/gecko/database/encdb"
|
||||
"github.com/ava-labs/gecko/database/memdb"
|
||||
"github.com/ava-labs/gecko/database/prefixdb"
|
||||
"github.com/ava-labs/gecko/ids"
|
||||
"github.com/ava-labs/gecko/snow/engine/common"
|
||||
|
@ -21,10 +24,39 @@ import (
|
|||
"github.com/ava-labs/gecko/vms/components/codec"
|
||||
|
||||
jsoncodec "github.com/ava-labs/gecko/utils/json"
|
||||
zxcvbn "github.com/nbutton23/zxcvbn-go"
|
||||
)
|
||||
|
||||
const (
|
||||
// maxUserPassLen is the maximum length of the username or password allowed
|
||||
maxUserPassLen = 1024
|
||||
|
||||
// maxCheckedPassLen limits the length of the password that should be
|
||||
// strength checked.
|
||||
//
|
||||
// As per issue https://github.com/ava-labs/gecko/issues/195 it was found
|
||||
// the longer the length of password the slower zxcvbn.PasswordStrength()
|
||||
// performs. To avoid performance issues, and a DoS vector, we only check
|
||||
// the first 50 characters of the password.
|
||||
maxCheckedPassLen = 50
|
||||
|
||||
// requiredPassScore defines the score a password must achieve to be
|
||||
// accepted as a password with strong characteristics by the zxcvbn package
|
||||
//
|
||||
// The scoring mechanism defined is as follows;
|
||||
//
|
||||
// 0 # too guessable: risky password. (guesses < 10^3)
|
||||
// 1 # very guessable: protection from throttled online attacks. (guesses < 10^6)
|
||||
// 2 # somewhat guessable: protection from unthrottled online attacks. (guesses < 10^8)
|
||||
// 3 # safely unguessable: moderate protection from offline slow-hash scenario. (guesses < 10^10)
|
||||
// 4 # very unguessable: strong protection from offline slow-hash scenario. (guesses >= 10^10)
|
||||
requiredPassScore = 2
|
||||
)
|
||||
|
||||
var (
|
||||
errEmptyUsername = errors.New("username can't be the empty string")
|
||||
errEmptyUsername = errors.New("username can't be the empty string")
|
||||
errUserPassMaxLength = fmt.Errorf("CreateUser call rejected due to username or password exceeding maximum length of %d chars", maxUserPassLen)
|
||||
errWeakPassword = errors.New("Failed to create user as the given password is too weak. A stronger password is one of 8 or more characters containing attributes of upper and lowercase letters, numbers, and/or special characters")
|
||||
)
|
||||
|
||||
// KeyValuePair ...
|
||||
|
@ -114,29 +146,11 @@ func (ks *Keystore) CreateUser(_ *http.Request, args *CreateUserArgs, reply *Cre
|
|||
ks.lock.Lock()
|
||||
defer ks.lock.Unlock()
|
||||
|
||||
ks.log.Verbo("CreateUser called with %s", args.Username)
|
||||
|
||||
if args.Username == "" {
|
||||
return errEmptyUsername
|
||||
}
|
||||
if usr, err := ks.getUser(args.Username); err == nil || usr != nil {
|
||||
return fmt.Errorf("user already exists: %s", args.Username)
|
||||
}
|
||||
|
||||
usr := &User{}
|
||||
if err := usr.Initialize(args.Password); err != nil {
|
||||
ks.log.Verbo("CreateUser called with %.*s", maxUserPassLen, args.Username)
|
||||
if err := ks.AddUser(args.Username, args.Password); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
usrBytes, err := ks.codec.Marshal(usr)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := ks.userDB.Put([]byte(args.Username), usrBytes); err != nil {
|
||||
return err
|
||||
}
|
||||
ks.users[args.Username] = usr
|
||||
reply.Success = true
|
||||
return nil
|
||||
}
|
||||
|
@ -174,7 +188,7 @@ type ExportUserArgs struct {
|
|||
|
||||
// ExportUserReply is the reply from ExportUser
|
||||
type ExportUserReply struct {
|
||||
User string `json:"user"`
|
||||
User formatting.CB58 `json:"user"`
|
||||
}
|
||||
|
||||
// ExportUser exports a serialized encoding of a user's information complete with encrypted database values
|
||||
|
@ -189,7 +203,7 @@ func (ks *Keystore) ExportUser(_ *http.Request, args *ExportUserArgs, reply *Exp
|
|||
return err
|
||||
}
|
||||
if !usr.CheckPassword(args.Password) {
|
||||
return fmt.Errorf("incorrect password for %s", args.Username)
|
||||
return fmt.Errorf("incorrect password for user %q", args.Username)
|
||||
}
|
||||
|
||||
userDB := prefixdb.New([]byte(args.Username), ks.bcDB)
|
||||
|
@ -214,16 +228,15 @@ func (ks *Keystore) ExportUser(_ *http.Request, args *ExportUserArgs, reply *Exp
|
|||
if err != nil {
|
||||
return err
|
||||
}
|
||||
cb58 := formatting.CB58{Bytes: b}
|
||||
reply.User = cb58.String()
|
||||
reply.User.Bytes = b
|
||||
return nil
|
||||
}
|
||||
|
||||
// ImportUserArgs are arguments for ImportUser
|
||||
type ImportUserArgs struct {
|
||||
Username string `json:"username"`
|
||||
Password string `json:"password"`
|
||||
User string `json:"user"`
|
||||
Username string `json:"username"`
|
||||
Password string `json:"password"`
|
||||
User formatting.CB58 `json:"user"`
|
||||
}
|
||||
|
||||
// ImportUserReply is the response for ImportUser
|
||||
|
@ -238,18 +251,20 @@ func (ks *Keystore) ImportUser(r *http.Request, args *ImportUserArgs, reply *Imp
|
|||
|
||||
ks.log.Verbo("ImportUser called for %s", args.Username)
|
||||
|
||||
if args.Username == "" {
|
||||
return errEmptyUsername
|
||||
}
|
||||
|
||||
if usr, err := ks.getUser(args.Username); err == nil || usr != nil {
|
||||
return fmt.Errorf("user already exists: %s", args.Username)
|
||||
}
|
||||
|
||||
cb58 := formatting.CB58{}
|
||||
if err := cb58.FromString(args.User); err != nil {
|
||||
userData := UserDB{}
|
||||
if err := ks.codec.Unmarshal(args.User.Bytes, &userData); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
userData := UserDB{}
|
||||
if err := ks.codec.Unmarshal(cb58.Bytes, &userData); err != nil {
|
||||
return err
|
||||
if !userData.User.CheckPassword(args.Password) {
|
||||
return fmt.Errorf("incorrect password for user %q", args.Username)
|
||||
}
|
||||
|
||||
usrBytes, err := ks.codec.Marshal(&userData.User)
|
||||
|
@ -257,22 +272,89 @@ func (ks *Keystore) ImportUser(r *http.Request, args *ImportUserArgs, reply *Imp
|
|||
return err
|
||||
}
|
||||
|
||||
// TODO: Should add batching to prevent creating a user without importing
|
||||
// the account
|
||||
if err := ks.userDB.Put([]byte(args.Username), usrBytes); err != nil {
|
||||
userBatch := ks.userDB.NewBatch()
|
||||
if err := userBatch.Put([]byte(args.Username), usrBytes); err != nil {
|
||||
return err
|
||||
}
|
||||
ks.users[args.Username] = &userData.User
|
||||
|
||||
userDB := prefixdb.New([]byte(args.Username), ks.bcDB)
|
||||
batch := userDB.NewBatch()
|
||||
|
||||
userDataDB := prefixdb.New([]byte(args.Username), ks.bcDB)
|
||||
dataBatch := userDataDB.NewBatch()
|
||||
for _, kvp := range userData.Data {
|
||||
batch.Put(kvp.Key, kvp.Value)
|
||||
dataBatch.Put(kvp.Key, kvp.Value)
|
||||
}
|
||||
|
||||
if err := atomic.WriteAll(dataBatch, userBatch); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
ks.users[args.Username] = &userData.User
|
||||
|
||||
reply.Success = true
|
||||
return batch.Write()
|
||||
return nil
|
||||
}
|
||||
|
||||
// DeleteUserArgs are arguments for passing into DeleteUser requests
|
||||
type DeleteUserArgs struct {
|
||||
Username string `json:"username"`
|
||||
Password string `json:"password"`
|
||||
}
|
||||
|
||||
// DeleteUserReply is the response from calling DeleteUser
|
||||
type DeleteUserReply struct {
|
||||
Success bool `json:"success"`
|
||||
}
|
||||
|
||||
// DeleteUser deletes user with the provided username and password.
|
||||
func (ks *Keystore) DeleteUser(_ *http.Request, args *DeleteUserArgs, reply *DeleteUserReply) error {
|
||||
ks.lock.Lock()
|
||||
defer ks.lock.Unlock()
|
||||
|
||||
ks.log.Verbo("DeleteUser called with %s", args.Username)
|
||||
|
||||
if args.Username == "" {
|
||||
return errEmptyUsername
|
||||
}
|
||||
|
||||
// check if user exists and valid user.
|
||||
usr, err := ks.getUser(args.Username)
|
||||
switch {
|
||||
case err != nil || usr == nil:
|
||||
return fmt.Errorf("user doesn't exist: %s", args.Username)
|
||||
case !usr.CheckPassword(args.Password):
|
||||
return fmt.Errorf("incorrect password for user %q", args.Username)
|
||||
}
|
||||
|
||||
userNameBytes := []byte(args.Username)
|
||||
userBatch := ks.userDB.NewBatch()
|
||||
if err := userBatch.Delete(userNameBytes); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
userDataDB := prefixdb.New(userNameBytes, ks.bcDB)
|
||||
dataBatch := userDataDB.NewBatch()
|
||||
|
||||
it := userDataDB.NewIterator()
|
||||
defer it.Release()
|
||||
|
||||
for it.Next() {
|
||||
if err = dataBatch.Delete(it.Key()); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
if err = it.Error(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := atomic.WriteAll(dataBatch, userBatch); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// delete from users map.
|
||||
delete(ks.users, args.Username)
|
||||
|
||||
reply.Success = true
|
||||
return nil
|
||||
}
|
||||
|
||||
// NewBlockchainKeyStore ...
|
||||
|
@ -293,7 +375,7 @@ func (ks *Keystore) GetDatabase(bID ids.ID, username, password string) (database
|
|||
return nil, err
|
||||
}
|
||||
if !usr.CheckPassword(password) {
|
||||
return nil, fmt.Errorf("incorrect password for user '%s'", username)
|
||||
return nil, fmt.Errorf("incorrect password for user %q", username)
|
||||
}
|
||||
|
||||
userDB := prefixdb.New([]byte(username), ks.bcDB)
|
||||
|
@ -306,3 +388,51 @@ func (ks *Keystore) GetDatabase(bID ids.ID, username, password string) (database
|
|||
|
||||
return encDB, nil
|
||||
}
|
||||
|
||||
// AddUser attempts to register this username and password as a new user of the
|
||||
// keystore.
|
||||
func (ks *Keystore) AddUser(username, password string) error {
|
||||
if len(username) > maxUserPassLen || len(password) > maxUserPassLen {
|
||||
return errUserPassMaxLength
|
||||
}
|
||||
|
||||
if username == "" {
|
||||
return errEmptyUsername
|
||||
}
|
||||
if usr, err := ks.getUser(username); err == nil || usr != nil {
|
||||
return fmt.Errorf("user already exists: %s", username)
|
||||
}
|
||||
|
||||
checkPass := password
|
||||
if len(password) > maxCheckedPassLen {
|
||||
checkPass = password[:maxCheckedPassLen]
|
||||
}
|
||||
|
||||
if zxcvbn.PasswordStrength(checkPass, nil).Score < requiredPassScore {
|
||||
return errWeakPassword
|
||||
}
|
||||
|
||||
usr := &User{}
|
||||
if err := usr.Initialize(password); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
usrBytes, err := ks.codec.Marshal(usr)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := ks.userDB.Put([]byte(username), usrBytes); err != nil {
|
||||
return err
|
||||
}
|
||||
ks.users[username] = usr
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// CreateTestKeystore returns a new keystore that can be utilized for testing
|
||||
func CreateTestKeystore(t *testing.T) *Keystore {
|
||||
ks := &Keystore{}
|
||||
ks.Initialize(logging.NoLog{}, memdb.New())
|
||||
return ks
|
||||
}
|
||||
|
|
|
@ -5,16 +5,22 @@ package keystore
|
|||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"math/rand"
|
||||
"reflect"
|
||||
"testing"
|
||||
|
||||
"github.com/ava-labs/gecko/database/memdb"
|
||||
"github.com/ava-labs/gecko/ids"
|
||||
"github.com/ava-labs/gecko/utils/logging"
|
||||
)
|
||||
|
||||
var (
|
||||
// strongPassword defines a password used for the following tests that
|
||||
// scores high enough to pass the password strength scoring system
|
||||
strongPassword = "N_+=_jJ;^(<;{4,:*m6CET}'&N;83FYK.wtNpwp-Jt"
|
||||
)
|
||||
|
||||
func TestServiceListNoUsers(t *testing.T) {
|
||||
ks := Keystore{}
|
||||
ks.Initialize(logging.NoLog{}, memdb.New())
|
||||
ks := CreateTestKeystore(t)
|
||||
|
||||
reply := ListUsersReply{}
|
||||
if err := ks.ListUsers(nil, &ListUsersArgs{}, &reply); err != nil {
|
||||
|
@ -26,14 +32,13 @@ func TestServiceListNoUsers(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestServiceCreateUser(t *testing.T) {
|
||||
ks := Keystore{}
|
||||
ks.Initialize(logging.NoLog{}, memdb.New())
|
||||
ks := CreateTestKeystore(t)
|
||||
|
||||
{
|
||||
reply := CreateUserReply{}
|
||||
if err := ks.CreateUser(nil, &CreateUserArgs{
|
||||
Username: "bob",
|
||||
Password: "launch",
|
||||
Password: strongPassword,
|
||||
}, &reply); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
@ -56,15 +61,84 @@ func TestServiceCreateUser(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
// genStr returns a string of given length
|
||||
func genStr(n int) string {
|
||||
b := make([]byte, n)
|
||||
rand.Read(b)
|
||||
return fmt.Sprintf("%x", b)[:n]
|
||||
}
|
||||
|
||||
// TestServiceCreateUserArgsChecks generates excessively long usernames or
|
||||
// passwords to assure the santity checks on string length are not exceeded
|
||||
func TestServiceCreateUserArgsCheck(t *testing.T) {
|
||||
ks := CreateTestKeystore(t)
|
||||
|
||||
{
|
||||
reply := CreateUserReply{}
|
||||
err := ks.CreateUser(nil, &CreateUserArgs{
|
||||
Username: genStr(maxUserPassLen + 1),
|
||||
Password: strongPassword,
|
||||
}, &reply)
|
||||
|
||||
if reply.Success || err != errUserPassMaxLength {
|
||||
t.Fatal("User was created when it should have been rejected due to too long a Username, err =", err)
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
reply := CreateUserReply{}
|
||||
err := ks.CreateUser(nil, &CreateUserArgs{
|
||||
Username: "shortuser",
|
||||
Password: genStr(maxUserPassLen + 1),
|
||||
}, &reply)
|
||||
|
||||
if reply.Success || err != errUserPassMaxLength {
|
||||
t.Fatal("User was created when it should have been rejected due to too long a Password, err =", err)
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
reply := ListUsersReply{}
|
||||
if err := ks.ListUsers(nil, &ListUsersArgs{}, &reply); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if len(reply.Users) > 0 {
|
||||
t.Fatalf("A user exists when there should be none")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// TestServiceCreateUserWeakPassword tests creating a new user with a weak
|
||||
// password to ensure the password strength check is working
|
||||
func TestServiceCreateUserWeakPassword(t *testing.T) {
|
||||
ks := CreateTestKeystore(t)
|
||||
|
||||
{
|
||||
reply := CreateUserReply{}
|
||||
err := ks.CreateUser(nil, &CreateUserArgs{
|
||||
Username: "bob",
|
||||
Password: "weak",
|
||||
}, &reply)
|
||||
|
||||
if err != errWeakPassword {
|
||||
t.Error("Unexpected error occurred when testing weak password:", err)
|
||||
}
|
||||
|
||||
if reply.Success {
|
||||
t.Fatal("User was created when it should have been rejected due to weak password")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestServiceCreateDuplicate(t *testing.T) {
|
||||
ks := Keystore{}
|
||||
ks.Initialize(logging.NoLog{}, memdb.New())
|
||||
ks := CreateTestKeystore(t)
|
||||
|
||||
{
|
||||
reply := CreateUserReply{}
|
||||
if err := ks.CreateUser(nil, &CreateUserArgs{
|
||||
Username: "bob",
|
||||
Password: "launch",
|
||||
Password: strongPassword,
|
||||
}, &reply); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
@ -77,7 +151,7 @@ func TestServiceCreateDuplicate(t *testing.T) {
|
|||
reply := CreateUserReply{}
|
||||
if err := ks.CreateUser(nil, &CreateUserArgs{
|
||||
Username: "bob",
|
||||
Password: "launch!",
|
||||
Password: strongPassword,
|
||||
}, &reply); err == nil {
|
||||
t.Fatalf("Should have errored due to the username already existing")
|
||||
}
|
||||
|
@ -85,26 +159,24 @@ func TestServiceCreateDuplicate(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestServiceCreateUserNoName(t *testing.T) {
|
||||
ks := Keystore{}
|
||||
ks.Initialize(logging.NoLog{}, memdb.New())
|
||||
ks := CreateTestKeystore(t)
|
||||
|
||||
reply := CreateUserReply{}
|
||||
if err := ks.CreateUser(nil, &CreateUserArgs{
|
||||
Password: "launch",
|
||||
Password: strongPassword,
|
||||
}, &reply); err == nil {
|
||||
t.Fatalf("Shouldn't have allowed empty username")
|
||||
}
|
||||
}
|
||||
|
||||
func TestServiceUseBlockchainDB(t *testing.T) {
|
||||
ks := Keystore{}
|
||||
ks.Initialize(logging.NoLog{}, memdb.New())
|
||||
ks := CreateTestKeystore(t)
|
||||
|
||||
{
|
||||
reply := CreateUserReply{}
|
||||
if err := ks.CreateUser(nil, &CreateUserArgs{
|
||||
Username: "bob",
|
||||
Password: "launch",
|
||||
Password: strongPassword,
|
||||
}, &reply); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
@ -114,7 +186,7 @@ func TestServiceUseBlockchainDB(t *testing.T) {
|
|||
}
|
||||
|
||||
{
|
||||
db, err := ks.GetDatabase(ids.Empty, "bob", "launch")
|
||||
db, err := ks.GetDatabase(ids.Empty, "bob", strongPassword)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
@ -124,7 +196,7 @@ func TestServiceUseBlockchainDB(t *testing.T) {
|
|||
}
|
||||
|
||||
{
|
||||
db, err := ks.GetDatabase(ids.Empty, "bob", "launch")
|
||||
db, err := ks.GetDatabase(ids.Empty, "bob", strongPassword)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
@ -137,14 +209,13 @@ func TestServiceUseBlockchainDB(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestServiceExportImport(t *testing.T) {
|
||||
ks := Keystore{}
|
||||
ks.Initialize(logging.NoLog{}, memdb.New())
|
||||
ks := CreateTestKeystore(t)
|
||||
|
||||
{
|
||||
reply := CreateUserReply{}
|
||||
if err := ks.CreateUser(nil, &CreateUserArgs{
|
||||
Username: "bob",
|
||||
Password: "launch",
|
||||
Password: strongPassword,
|
||||
}, &reply); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
@ -154,7 +225,7 @@ func TestServiceExportImport(t *testing.T) {
|
|||
}
|
||||
|
||||
{
|
||||
db, err := ks.GetDatabase(ids.Empty, "bob", "launch")
|
||||
db, err := ks.GetDatabase(ids.Empty, "bob", strongPassword)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
@ -166,19 +237,40 @@ func TestServiceExportImport(t *testing.T) {
|
|||
exportReply := ExportUserReply{}
|
||||
if err := ks.ExportUser(nil, &ExportUserArgs{
|
||||
Username: "bob",
|
||||
Password: "launch",
|
||||
Password: strongPassword,
|
||||
}, &exportReply); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
newKS := Keystore{}
|
||||
newKS.Initialize(logging.NoLog{}, memdb.New())
|
||||
newKS := CreateTestKeystore(t)
|
||||
|
||||
{
|
||||
reply := ImportUserReply{}
|
||||
if err := newKS.ImportUser(nil, &ImportUserArgs{
|
||||
Username: "bob",
|
||||
Password: "launch",
|
||||
Password: "",
|
||||
User: exportReply.User,
|
||||
}, &reply); err == nil {
|
||||
t.Fatal("Should have errored due to incorrect password")
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
reply := ImportUserReply{}
|
||||
if err := newKS.ImportUser(nil, &ImportUserArgs{
|
||||
Username: "",
|
||||
Password: "strongPassword",
|
||||
User: exportReply.User,
|
||||
}, &reply); err == nil {
|
||||
t.Fatal("Should have errored due to empty username")
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
reply := ImportUserReply{}
|
||||
if err := newKS.ImportUser(nil, &ImportUserArgs{
|
||||
Username: "bob",
|
||||
Password: strongPassword,
|
||||
User: exportReply.User,
|
||||
}, &reply); err != nil {
|
||||
t.Fatal(err)
|
||||
|
@ -189,7 +281,7 @@ func TestServiceExportImport(t *testing.T) {
|
|||
}
|
||||
|
||||
{
|
||||
db, err := newKS.GetDatabase(ids.Empty, "bob", "launch")
|
||||
db, err := newKS.GetDatabase(ids.Empty, "bob", strongPassword)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
@ -200,3 +292,88 @@ func TestServiceExportImport(t *testing.T) {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestServiceDeleteUser(t *testing.T) {
|
||||
testUser := "testUser"
|
||||
password := "passwTest@fake01ord"
|
||||
tests := []struct {
|
||||
desc string
|
||||
setup func(ks *Keystore) error
|
||||
request *DeleteUserArgs
|
||||
want *DeleteUserReply
|
||||
wantError bool
|
||||
}{{
|
||||
desc: "empty user name case",
|
||||
request: &DeleteUserArgs{},
|
||||
wantError: true,
|
||||
}, {
|
||||
desc: "user not exists case",
|
||||
request: &DeleteUserArgs{Username: "dummy"},
|
||||
wantError: true,
|
||||
}, {
|
||||
desc: "user exists and invalid password case",
|
||||
request: &DeleteUserArgs{Username: testUser, Password: "password"},
|
||||
wantError: true,
|
||||
}, {
|
||||
desc: "user exists and valid password case",
|
||||
setup: func(ks *Keystore) error {
|
||||
return ks.CreateUser(nil, &CreateUserArgs{Username: testUser, Password: password}, &CreateUserReply{})
|
||||
},
|
||||
request: &DeleteUserArgs{Username: testUser, Password: password},
|
||||
want: &DeleteUserReply{Success: true},
|
||||
}, {
|
||||
desc: "delete a user, imported from import api case",
|
||||
setup: func(ks *Keystore) error {
|
||||
|
||||
reply := CreateUserReply{}
|
||||
if err := ks.CreateUser(nil, &CreateUserArgs{Username: testUser, Password: password}, &reply); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// created data in bob db
|
||||
db, err := ks.GetDatabase(ids.Empty, testUser, password)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if err := db.Put([]byte("hello"), []byte("world")); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
},
|
||||
request: &DeleteUserArgs{Username: testUser, Password: password},
|
||||
want: &DeleteUserReply{Success: true},
|
||||
}}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.desc, func(t *testing.T) {
|
||||
ks := CreateTestKeystore(t)
|
||||
|
||||
if tt.setup != nil {
|
||||
if err := tt.setup(ks); err != nil {
|
||||
t.Fatalf("failed to create user setup in keystore: %v", err)
|
||||
}
|
||||
}
|
||||
got := &DeleteUserReply{}
|
||||
err := ks.DeleteUser(nil, tt.request, got)
|
||||
if (err != nil) != tt.wantError {
|
||||
t.Fatalf("DeleteUser() failed: error %v, wantError %v", err, tt.wantError)
|
||||
}
|
||||
|
||||
if !tt.wantError && !reflect.DeepEqual(tt.want, got) {
|
||||
t.Fatalf("DeleteUser() failed: got %v, want %v", got, tt.want)
|
||||
}
|
||||
|
||||
if err == nil && got.Success { // delete is successful
|
||||
if _, ok := ks.users[testUser]; ok {
|
||||
t.Fatalf("DeleteUser() failed: expected the user %s should be delete from users map", testUser)
|
||||
}
|
||||
|
||||
// deleted user details should be available to create user again.
|
||||
if err = ks.CreateUser(nil, &CreateUserArgs{Username: testUser, Password: password}, &CreateUserReply{}); err != nil {
|
||||
t.Fatalf("failed to create user: %v", err)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,6 +7,7 @@ import (
|
|||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"net"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"sync"
|
||||
|
@ -28,30 +29,40 @@ var (
|
|||
|
||||
// Server maintains the HTTP router
|
||||
type Server struct {
|
||||
log logging.Logger
|
||||
factory logging.Factory
|
||||
router *router
|
||||
portURL string
|
||||
log logging.Logger
|
||||
factory logging.Factory
|
||||
router *router
|
||||
listenAddress string
|
||||
}
|
||||
|
||||
// Initialize creates the API server at the provided port
|
||||
func (s *Server) Initialize(log logging.Logger, factory logging.Factory, port uint16) {
|
||||
// Initialize creates the API server at the provided host and port
|
||||
func (s *Server) Initialize(log logging.Logger, factory logging.Factory, host string, port uint16) {
|
||||
s.log = log
|
||||
s.factory = factory
|
||||
s.portURL = fmt.Sprintf(":%d", port)
|
||||
s.listenAddress = fmt.Sprintf("%s:%d", host, port)
|
||||
s.router = newRouter()
|
||||
}
|
||||
|
||||
// Dispatch starts the API server
|
||||
func (s *Server) Dispatch() error {
|
||||
handler := cors.Default().Handler(s.router)
|
||||
return http.ListenAndServe(s.portURL, handler)
|
||||
listener, err := net.Listen("tcp", s.listenAddress)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
s.log.Info("API server listening on %q", s.listenAddress)
|
||||
return http.Serve(listener, handler)
|
||||
}
|
||||
|
||||
// DispatchTLS starts the API server with the provided TLS certificate
|
||||
func (s *Server) DispatchTLS(certFile, keyFile string) error {
|
||||
handler := cors.Default().Handler(s.router)
|
||||
return http.ListenAndServeTLS(s.portURL, certFile, keyFile, handler)
|
||||
listener, err := net.Listen("tcp", s.listenAddress)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
s.log.Info("API server listening on %q", s.listenAddress)
|
||||
return http.ServeTLS(listener, handler, certFile, keyFile)
|
||||
}
|
||||
|
||||
// RegisterChain registers the API endpoints associated with this chain That
|
||||
|
@ -64,8 +75,9 @@ func (s *Server) RegisterChain(ctx *snow.Context, vmIntf interface{}) {
|
|||
}
|
||||
|
||||
// all subroutes to a chain begin with "bc/<the chain's ID>"
|
||||
defaultEndpoint := "bc/" + ctx.ChainID.String()
|
||||
httpLogger, err := s.factory.MakeChain(ctx.ChainID, "http")
|
||||
chainID := ctx.ChainID.String()
|
||||
defaultEndpoint := "bc/" + chainID
|
||||
httpLogger, err := s.factory.MakeChain(chainID, "http")
|
||||
if err != nil {
|
||||
s.log.Error("Failed to create new http logger: %s", err)
|
||||
return
|
||||
|
|
|
@ -30,7 +30,7 @@ func (s *Service) Call(_ *http.Request, args *Args, reply *Reply) error {
|
|||
|
||||
func TestCall(t *testing.T) {
|
||||
s := Server{}
|
||||
s.Initialize(logging.NoLog{}, logging.NoFactory{}, 8080)
|
||||
s.Initialize(logging.NoLog{}, logging.NoFactory{}, "localhost", 8080)
|
||||
|
||||
serv := &Service{}
|
||||
newServer := rpc.NewServer()
|
||||
|
|
9
bugs.txt
9
bugs.txt
|
@ -1,9 +0,0 @@
|
|||
Added bugs:
|
||||
|
||||
- Inside of gecko/snow/consensus/avalanche/topological.go#Topological.pushVotes the votes must be properly filtered. Specifically, a byzantine node should not be able to vote for two different transactions that conflict with each other during the same poll. If a node votes for conflicting transactions during the same poll, either all the node's votes should be dropped, or the votes for the conflicting transactions should be dropped.
|
||||
|
||||
- Inside of gecko/snow/consensus/snowball/unary_snowball.go#unarySnowball.Extend the confidence and bias fields should have been set to the values in the unary snowball instance.
|
||||
|
||||
- Inside of gecko/snow/engine/avalanche/bootstrapper.go#bootstrapper.Put and gecko/snow/engine/snowman/bootstrapper.go#bootstrapper.Put the engine must check that the provided vtx/blk ID is the ID of the parsed container. Otherwise, a byzantine node could send a container and report the wrong container ID for it. This would allow an un-intended container to be marked as accepted during bootstrapping.
|
||||
|
||||
- Inside of gecko/snow/engine/avalanche/polls.go#poll and gecko/snow/engine/snowman/polls.go#poll the poll should only allow a validator to vote once per poll. Also, this validator must have been part of set of validators that was polled during the query.
|
|
@ -0,0 +1,28 @@
|
|||
// (c) 2019-2020, Ava Labs, Inc. All rights reserved.
|
||||
// See the file LICENSE for licensing terms.
|
||||
|
||||
package atomic
|
||||
|
||||
import (
|
||||
"github.com/ava-labs/gecko/database"
|
||||
"github.com/ava-labs/gecko/ids"
|
||||
)
|
||||
|
||||
// BlockchainSharedMemory provides the API for a blockchain to interact with
|
||||
// shared memory of another blockchain
|
||||
type BlockchainSharedMemory struct {
|
||||
blockchainID ids.ID
|
||||
sm *SharedMemory
|
||||
}
|
||||
|
||||
// GetDatabase returns and locks the provided DB
|
||||
func (bsm *BlockchainSharedMemory) GetDatabase(id ids.ID) database.Database {
|
||||
sharedID := bsm.sm.sharedID(id, bsm.blockchainID)
|
||||
return bsm.sm.GetDatabase(sharedID)
|
||||
}
|
||||
|
||||
// ReleaseDatabase unlocks the provided DB
|
||||
func (bsm *BlockchainSharedMemory) ReleaseDatabase(id ids.ID) {
|
||||
sharedID := bsm.sm.sharedID(id, bsm.blockchainID)
|
||||
bsm.sm.ReleaseDatabase(sharedID)
|
||||
}
|
|
@ -0,0 +1,34 @@
|
|||
// (c) 2019-2020, Ava Labs, Inc. All rights reserved.
|
||||
// See the file LICENSE for licensing terms.
|
||||
|
||||
package atomic
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"testing"
|
||||
|
||||
"github.com/ava-labs/gecko/database/memdb"
|
||||
"github.com/ava-labs/gecko/utils/logging"
|
||||
)
|
||||
|
||||
func TestBlockchainSharedMemory(t *testing.T) {
|
||||
sm := SharedMemory{}
|
||||
sm.Initialize(logging.NoLog{}, memdb.New())
|
||||
|
||||
bsm0 := sm.NewBlockchainSharedMemory(blockchainID0)
|
||||
bsm1 := sm.NewBlockchainSharedMemory(blockchainID1)
|
||||
|
||||
sharedDB0 := bsm0.GetDatabase(blockchainID1)
|
||||
if err := sharedDB0.Put([]byte{1}, []byte{2}); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
bsm0.ReleaseDatabase(blockchainID1)
|
||||
|
||||
sharedDB1 := bsm1.GetDatabase(blockchainID0)
|
||||
if value, err := sharedDB1.Get([]byte{1}); err != nil {
|
||||
t.Fatal(err)
|
||||
} else if !bytes.Equal(value, []byte{2}) {
|
||||
t.Fatalf("database.Get Returned: 0x%x ; Expected: 0x%x", value, []byte{2})
|
||||
}
|
||||
bsm1.ReleaseDatabase(blockchainID0)
|
||||
}
|
|
@ -0,0 +1,105 @@
|
|||
// (c) 2019-2020, Ava Labs, Inc. All rights reserved.
|
||||
// See the file LICENSE for licensing terms.
|
||||
|
||||
package atomic
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"sync"
|
||||
|
||||
"github.com/ava-labs/gecko/database"
|
||||
"github.com/ava-labs/gecko/database/prefixdb"
|
||||
"github.com/ava-labs/gecko/ids"
|
||||
"github.com/ava-labs/gecko/utils/hashing"
|
||||
"github.com/ava-labs/gecko/utils/logging"
|
||||
"github.com/ava-labs/gecko/vms/components/codec"
|
||||
)
|
||||
|
||||
type rcLock struct {
|
||||
lock sync.Mutex
|
||||
count int
|
||||
}
|
||||
|
||||
// SharedMemory is the interface for shared memory inside a subnet
|
||||
type SharedMemory struct {
|
||||
lock sync.Mutex
|
||||
log logging.Logger
|
||||
codec codec.Codec
|
||||
locks map[[32]byte]*rcLock
|
||||
db database.Database
|
||||
}
|
||||
|
||||
// Initialize the SharedMemory
|
||||
func (sm *SharedMemory) Initialize(log logging.Logger, db database.Database) {
|
||||
sm.log = log
|
||||
sm.codec = codec.NewDefault()
|
||||
sm.locks = make(map[[32]byte]*rcLock)
|
||||
sm.db = db
|
||||
}
|
||||
|
||||
// NewBlockchainSharedMemory returns a new BlockchainSharedMemory
|
||||
func (sm *SharedMemory) NewBlockchainSharedMemory(id ids.ID) *BlockchainSharedMemory {
|
||||
return &BlockchainSharedMemory{
|
||||
blockchainID: id,
|
||||
sm: sm,
|
||||
}
|
||||
}
|
||||
|
||||
// GetDatabase returns and locks the provided DB
|
||||
func (sm *SharedMemory) GetDatabase(id ids.ID) database.Database {
|
||||
lock := sm.makeLock(id)
|
||||
lock.Lock()
|
||||
|
||||
return prefixdb.New(id.Bytes(), sm.db)
|
||||
}
|
||||
|
||||
// ReleaseDatabase unlocks the provided DB
|
||||
func (sm *SharedMemory) ReleaseDatabase(id ids.ID) {
|
||||
lock := sm.releaseLock(id)
|
||||
lock.Unlock()
|
||||
}
|
||||
|
||||
func (sm *SharedMemory) makeLock(id ids.ID) *sync.Mutex {
|
||||
sm.lock.Lock()
|
||||
defer sm.lock.Unlock()
|
||||
|
||||
key := id.Key()
|
||||
rc, exists := sm.locks[key]
|
||||
if !exists {
|
||||
rc = &rcLock{}
|
||||
sm.locks[key] = rc
|
||||
}
|
||||
rc.count++
|
||||
return &rc.lock
|
||||
}
|
||||
|
||||
func (sm *SharedMemory) releaseLock(id ids.ID) *sync.Mutex {
|
||||
sm.lock.Lock()
|
||||
defer sm.lock.Unlock()
|
||||
|
||||
key := id.Key()
|
||||
rc, exists := sm.locks[key]
|
||||
if !exists {
|
||||
panic("Attemping to free an unknown lock")
|
||||
}
|
||||
rc.count--
|
||||
if rc.count == 0 {
|
||||
delete(sm.locks, key)
|
||||
}
|
||||
return &rc.lock
|
||||
}
|
||||
|
||||
// sharedID calculates the ID of the shared memory space
|
||||
func (sm *SharedMemory) sharedID(id1, id2 ids.ID) ids.ID {
|
||||
idKey1 := id1.Key()
|
||||
idKey2 := id2.Key()
|
||||
|
||||
if bytes.Compare(idKey1[:], idKey2[:]) == 1 {
|
||||
idKey1, idKey2 = idKey2, idKey1
|
||||
}
|
||||
|
||||
combinedBytes, err := sm.codec.Marshal([2][32]byte{idKey1, idKey2})
|
||||
sm.log.AssertNoError(err)
|
||||
|
||||
return ids.NewID(hashing.ComputeHash256Array(combinedBytes))
|
||||
}
|
|
@ -0,0 +1,69 @@
|
|||
// (c) 2019-2020, Ava Labs, Inc. All rights reserved.
|
||||
// See the file LICENSE for licensing terms.
|
||||
|
||||
package atomic
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/ava-labs/gecko/database/memdb"
|
||||
"github.com/ava-labs/gecko/ids"
|
||||
"github.com/ava-labs/gecko/utils/logging"
|
||||
)
|
||||
|
||||
var (
|
||||
blockchainID0 = ids.Empty.Prefix(0)
|
||||
blockchainID1 = ids.Empty.Prefix(1)
|
||||
)
|
||||
|
||||
func TestSharedMemorySharedID(t *testing.T) {
|
||||
sm := SharedMemory{}
|
||||
sm.Initialize(logging.NoLog{}, memdb.New())
|
||||
|
||||
sharedID0 := sm.sharedID(blockchainID0, blockchainID1)
|
||||
sharedID1 := sm.sharedID(blockchainID1, blockchainID0)
|
||||
|
||||
if !sharedID0.Equals(sharedID1) {
|
||||
t.Fatalf("SharedMemory.sharedID should be communitive")
|
||||
}
|
||||
}
|
||||
|
||||
func TestSharedMemoryMakeReleaseLock(t *testing.T) {
|
||||
sm := SharedMemory{}
|
||||
sm.Initialize(logging.NoLog{}, memdb.New())
|
||||
|
||||
sharedID := sm.sharedID(blockchainID0, blockchainID1)
|
||||
|
||||
lock0 := sm.makeLock(sharedID)
|
||||
|
||||
if lock1 := sm.makeLock(sharedID); lock0 != lock1 {
|
||||
t.Fatalf("SharedMemory.makeLock should have returned the same lock")
|
||||
}
|
||||
sm.releaseLock(sharedID)
|
||||
|
||||
if lock2 := sm.makeLock(sharedID); lock0 != lock2 {
|
||||
t.Fatalf("SharedMemory.makeLock should have returned the same lock")
|
||||
}
|
||||
sm.releaseLock(sharedID)
|
||||
sm.releaseLock(sharedID)
|
||||
|
||||
if lock3 := sm.makeLock(sharedID); lock0 == lock3 {
|
||||
t.Fatalf("SharedMemory.releaseLock should have returned freed the lock")
|
||||
}
|
||||
sm.releaseLock(sharedID)
|
||||
}
|
||||
|
||||
func TestSharedMemoryUnknownFree(t *testing.T) {
|
||||
sm := SharedMemory{}
|
||||
sm.Initialize(logging.NoLog{}, memdb.New())
|
||||
|
||||
sharedID := sm.sharedID(blockchainID0, blockchainID1)
|
||||
|
||||
defer func() {
|
||||
if recover() == nil {
|
||||
t.Fatalf("Should have panicked due to an unknown free")
|
||||
}
|
||||
}()
|
||||
|
||||
sm.releaseLock(sharedID)
|
||||
}
|
|
@ -0,0 +1,21 @@
|
|||
// (c) 2019-2020, Ava Labs, Inc. All rights reserved.
|
||||
// See the file LICENSE for licensing terms.
|
||||
|
||||
package atomic
|
||||
|
||||
import (
|
||||
"github.com/ava-labs/gecko/database"
|
||||
)
|
||||
|
||||
// WriteAll assumes all batches have the same underlying database. Batches
|
||||
// should not be modified after being passed to this function.
|
||||
func WriteAll(baseBatch database.Batch, batches ...database.Batch) error {
|
||||
baseBatch = baseBatch.Inner()
|
||||
for _, batch := range batches {
|
||||
batch = batch.Inner()
|
||||
if err := batch.Replay(baseBatch); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return baseBatch.Write()
|
||||
}
|
|
@ -0,0 +1,61 @@
|
|||
// (c) 2019-2020, Ava Labs, Inc. All rights reserved.
|
||||
// See the file LICENSE for licensing terms.
|
||||
|
||||
package atomic
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"testing"
|
||||
|
||||
"github.com/ava-labs/gecko/database/memdb"
|
||||
"github.com/ava-labs/gecko/database/prefixdb"
|
||||
"github.com/ava-labs/gecko/database/versiondb"
|
||||
"github.com/ava-labs/gecko/utils/logging"
|
||||
)
|
||||
|
||||
func TestWriteAll(t *testing.T) {
|
||||
baseDB := memdb.New()
|
||||
prefixedDBChain := prefixdb.New([]byte{0}, baseDB)
|
||||
prefixedDBSharedMemory := prefixdb.New([]byte{1}, baseDB)
|
||||
|
||||
sm := SharedMemory{}
|
||||
sm.Initialize(logging.NoLog{}, prefixedDBSharedMemory)
|
||||
|
||||
sharedID := sm.sharedID(blockchainID0, blockchainID1)
|
||||
|
||||
sharedDB := sm.GetDatabase(sharedID)
|
||||
|
||||
writeDB0 := versiondb.New(prefixedDBChain)
|
||||
writeDB1 := versiondb.New(sharedDB)
|
||||
defer sm.ReleaseDatabase(sharedID)
|
||||
|
||||
if err := writeDB0.Put([]byte{1}, []byte{2}); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if err := writeDB1.Put([]byte{2}, []byte{3}); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
batch0, err := writeDB0.CommitBatch()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
batch1, err := writeDB1.CommitBatch()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if err := WriteAll(batch0, batch1); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if value, err := prefixedDBChain.Get([]byte{1}); err != nil {
|
||||
t.Fatal(err)
|
||||
} else if !bytes.Equal(value, []byte{2}) {
|
||||
t.Fatalf("database.Get Returned: 0x%x ; Expected: 0x%x", value, []byte{2})
|
||||
} else if value, err := sharedDB.Get([]byte{2}); err != nil {
|
||||
t.Fatal(err)
|
||||
} else if !bytes.Equal(value, []byte{3}) {
|
||||
t.Fatalf("database.Get Returned: 0x%x ; Expected: 0x%x", value, []byte{3})
|
||||
}
|
||||
}
|
|
@ -3,9 +3,44 @@
|
|||
|
||||
package chains
|
||||
|
||||
import "github.com/ava-labs/gecko/snow/networking"
|
||||
import (
|
||||
"github.com/ava-labs/gecko/ids"
|
||||
"github.com/ava-labs/gecko/snow"
|
||||
"github.com/ava-labs/gecko/snow/engine/common"
|
||||
"github.com/ava-labs/gecko/snow/validators"
|
||||
"github.com/ava-labs/gecko/utils/math"
|
||||
)
|
||||
|
||||
// Awaiter can await connections to be connected
|
||||
type Awaiter interface {
|
||||
AwaitConnections(awaiting *networking.AwaitingConnections)
|
||||
type awaiter struct {
|
||||
vdrs validators.Set
|
||||
reqWeight uint64
|
||||
weight uint64
|
||||
ctx *snow.Context
|
||||
eng common.Engine
|
||||
}
|
||||
|
||||
func (a *awaiter) Connected(vdrID ids.ShortID) bool {
|
||||
vdr, ok := a.vdrs.Get(vdrID)
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
weight, err := math.Add64(vdr.Weight(), a.weight)
|
||||
a.weight = weight
|
||||
if err == nil && a.weight < a.reqWeight {
|
||||
return false
|
||||
}
|
||||
|
||||
go func() {
|
||||
a.ctx.Lock.Lock()
|
||||
defer a.ctx.Lock.Unlock()
|
||||
a.eng.Startup()
|
||||
}()
|
||||
return true
|
||||
}
|
||||
|
||||
func (a *awaiter) Disconnected(vdrID ids.ShortID) bool {
|
||||
if vdr, ok := a.vdrs.Get(vdrID); ok {
|
||||
a.weight, _ = math.Sub64(vdr.Weight(), a.weight)
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
|
|
@ -9,23 +9,24 @@ import (
|
|||
|
||||
"github.com/ava-labs/gecko/api"
|
||||
"github.com/ava-labs/gecko/api/keystore"
|
||||
"github.com/ava-labs/gecko/chains/atomic"
|
||||
"github.com/ava-labs/gecko/database"
|
||||
"github.com/ava-labs/gecko/database/prefixdb"
|
||||
"github.com/ava-labs/gecko/ids"
|
||||
"github.com/ava-labs/gecko/network"
|
||||
"github.com/ava-labs/gecko/snow"
|
||||
"github.com/ava-labs/gecko/snow/consensus/snowball"
|
||||
"github.com/ava-labs/gecko/snow/engine/avalanche"
|
||||
"github.com/ava-labs/gecko/snow/engine/avalanche/state"
|
||||
"github.com/ava-labs/gecko/snow/engine/common"
|
||||
"github.com/ava-labs/gecko/snow/engine/common/queue"
|
||||
"github.com/ava-labs/gecko/snow/networking"
|
||||
"github.com/ava-labs/gecko/snow/networking/handler"
|
||||
"github.com/ava-labs/gecko/snow/networking/router"
|
||||
"github.com/ava-labs/gecko/snow/networking/sender"
|
||||
"github.com/ava-labs/gecko/snow/networking/timeout"
|
||||
"github.com/ava-labs/gecko/snow/triggers"
|
||||
"github.com/ava-labs/gecko/snow/validators"
|
||||
"github.com/ava-labs/gecko/utils/logging"
|
||||
"github.com/ava-labs/gecko/utils/math"
|
||||
"github.com/ava-labs/gecko/vms"
|
||||
|
||||
avacon "github.com/ava-labs/gecko/snow/consensus/avalanche"
|
||||
|
@ -37,7 +38,9 @@ import (
|
|||
|
||||
const (
|
||||
defaultChannelSize = 1000
|
||||
requestTimeout = 2 * time.Second
|
||||
requestTimeout = 4 * time.Second
|
||||
gossipFrequency = 10 * time.Second
|
||||
shutdownTimeout = 1 * time.Second
|
||||
)
|
||||
|
||||
// Manager manages the chains running on this node.
|
||||
|
@ -92,23 +95,24 @@ type manager struct {
|
|||
// That is, [chainID].String() is an alias for the chain, too
|
||||
ids.Aliaser
|
||||
|
||||
stakingEnabled bool // True iff the network has staking enabled
|
||||
log logging.Logger
|
||||
logFactory logging.Factory
|
||||
vmManager vms.Manager // Manage mappings from vm ID --> vm
|
||||
decisionEvents *triggers.EventDispatcher
|
||||
consensusEvents *triggers.EventDispatcher
|
||||
db database.Database
|
||||
chainRouter router.Router // Routes incoming messages to the appropriate chain
|
||||
sender sender.ExternalSender // Sends consensus messages to other validators
|
||||
timeoutManager *timeout.Manager // Manages request timeouts when sending messages to other validators
|
||||
consensusParams avacon.Parameters // The consensus parameters (alpha, beta, etc.) for new chains
|
||||
validators validators.Manager // Validators validating on this chain
|
||||
registrants []Registrant // Those notified when a chain is created
|
||||
nodeID ids.ShortID // The ID of this node
|
||||
networkID uint32 // ID of the network this node is connected to
|
||||
awaiter Awaiter // Waits for required connections before running bootstrapping
|
||||
server *api.Server // Handles HTTP API calls
|
||||
chainRouter router.Router // Routes incoming messages to the appropriate chain
|
||||
net network.Network // Sends consensus messages to other validators
|
||||
timeoutManager *timeout.Manager // Manages request timeouts when sending messages to other validators
|
||||
consensusParams avacon.Parameters // The consensus parameters (alpha, beta, etc.) for new chains
|
||||
validators validators.Manager // Validators validating on this chain
|
||||
registrants []Registrant // Those notified when a chain is created
|
||||
nodeID ids.ShortID // The ID of this node
|
||||
networkID uint32 // ID of the network this node is connected to
|
||||
server *api.Server // Handles HTTP API calls
|
||||
keystore *keystore.Keystore
|
||||
sharedMemory *atomic.SharedMemory
|
||||
|
||||
unblocked bool
|
||||
blockedChains []ChainParameters
|
||||
|
@ -120,6 +124,7 @@ type manager struct {
|
|||
// <validators> validate this chain
|
||||
// TODO: Make this function take less arguments
|
||||
func New(
|
||||
stakingEnabled bool,
|
||||
log logging.Logger,
|
||||
logFactory logging.Factory,
|
||||
vmManager vms.Manager,
|
||||
|
@ -127,22 +132,23 @@ func New(
|
|||
consensusEvents *triggers.EventDispatcher,
|
||||
db database.Database,
|
||||
router router.Router,
|
||||
sender sender.ExternalSender,
|
||||
net network.Network,
|
||||
consensusParams avacon.Parameters,
|
||||
validators validators.Manager,
|
||||
nodeID ids.ShortID,
|
||||
networkID uint32,
|
||||
awaiter Awaiter,
|
||||
server *api.Server,
|
||||
keystore *keystore.Keystore,
|
||||
sharedMemory *atomic.SharedMemory,
|
||||
) Manager {
|
||||
timeoutManager := timeout.Manager{}
|
||||
timeoutManager.Initialize(requestTimeout)
|
||||
go log.RecoverAndPanic(timeoutManager.Dispatch)
|
||||
|
||||
router.Initialize(log, &timeoutManager)
|
||||
router.Initialize(log, &timeoutManager, gossipFrequency, shutdownTimeout)
|
||||
|
||||
m := &manager{
|
||||
stakingEnabled: stakingEnabled,
|
||||
log: log,
|
||||
logFactory: logFactory,
|
||||
vmManager: vmManager,
|
||||
|
@ -150,15 +156,15 @@ func New(
|
|||
consensusEvents: consensusEvents,
|
||||
db: db,
|
||||
chainRouter: router,
|
||||
sender: sender,
|
||||
net: net,
|
||||
timeoutManager: &timeoutManager,
|
||||
consensusParams: consensusParams,
|
||||
validators: validators,
|
||||
nodeID: nodeID,
|
||||
networkID: networkID,
|
||||
awaiter: awaiter,
|
||||
server: server,
|
||||
keystore: keystore,
|
||||
sharedMemory: sharedMemory,
|
||||
}
|
||||
m.Initialize()
|
||||
return m
|
||||
|
@ -198,6 +204,31 @@ func (m *manager) ForceCreateChain(chain ChainParameters) {
|
|||
return
|
||||
}
|
||||
|
||||
primaryAlias, err := m.PrimaryAlias(chain.ID)
|
||||
if err != nil {
|
||||
primaryAlias = chain.ID.String()
|
||||
}
|
||||
|
||||
// Create the log and context of the chain
|
||||
chainLog, err := m.logFactory.MakeChain(primaryAlias, "")
|
||||
if err != nil {
|
||||
m.log.Error("error while creating chain's log %s", err)
|
||||
return
|
||||
}
|
||||
|
||||
ctx := &snow.Context{
|
||||
NetworkID: m.networkID,
|
||||
ChainID: chain.ID,
|
||||
Log: chainLog,
|
||||
DecisionDispatcher: m.decisionEvents,
|
||||
ConsensusDispatcher: m.consensusEvents,
|
||||
NodeID: m.nodeID,
|
||||
HTTP: m.server,
|
||||
Keystore: m.keystore.NewBlockchainKeyStore(chain.ID),
|
||||
SharedMemory: m.sharedMemory.NewBlockchainSharedMemory(chain.ID),
|
||||
BCLookup: m,
|
||||
}
|
||||
|
||||
// Get a factory for the vm we want to use on our chain
|
||||
vmFactory, err := m.vmManager.GetVMFactory(vmID)
|
||||
if err != nil {
|
||||
|
@ -206,7 +237,12 @@ func (m *manager) ForceCreateChain(chain ChainParameters) {
|
|||
}
|
||||
|
||||
// Create the chain
|
||||
vm := vmFactory.New()
|
||||
vm, err := vmFactory.New(ctx)
|
||||
if err != nil {
|
||||
m.log.Error("error while creating vm: %s", err)
|
||||
return
|
||||
}
|
||||
// TODO: Shutdown VM if an error occurs
|
||||
|
||||
fxs := make([]*common.Fx, len(chain.FxAliases))
|
||||
for i, fxAlias := range chain.FxAliases {
|
||||
|
@ -223,40 +259,30 @@ func (m *manager) ForceCreateChain(chain ChainParameters) {
|
|||
return
|
||||
}
|
||||
|
||||
fx, err := fxFactory.New(ctx)
|
||||
if err != nil {
|
||||
m.log.Error("error while creating fx: %s", err)
|
||||
return
|
||||
}
|
||||
|
||||
// Create the fx
|
||||
fxs[i] = &common.Fx{
|
||||
ID: fxID,
|
||||
Fx: fxFactory.New(),
|
||||
Fx: fx,
|
||||
}
|
||||
}
|
||||
|
||||
// Create the log and context of the chain
|
||||
chainLog, err := m.logFactory.MakeChain(chain.ID, "")
|
||||
if err != nil {
|
||||
m.log.Error("error while creating chain's log %s", err)
|
||||
return
|
||||
}
|
||||
|
||||
ctx := &snow.Context{
|
||||
NetworkID: m.networkID,
|
||||
ChainID: chain.ID,
|
||||
Log: chainLog,
|
||||
DecisionDispatcher: m.decisionEvents,
|
||||
ConsensusDispatcher: m.consensusEvents,
|
||||
NodeID: m.nodeID,
|
||||
HTTP: m.server,
|
||||
Keystore: m.keystore.NewBlockchainKeyStore(chain.ID),
|
||||
BCLookup: m,
|
||||
}
|
||||
consensusParams := m.consensusParams
|
||||
if alias, err := m.PrimaryAlias(ctx.ChainID); err == nil {
|
||||
consensusParams.Namespace = fmt.Sprintf("gecko_%s", alias)
|
||||
} else {
|
||||
consensusParams.Namespace = fmt.Sprintf("gecko_%s", ctx.ChainID)
|
||||
}
|
||||
consensusParams.Namespace = fmt.Sprintf("gecko_%s", primaryAlias)
|
||||
|
||||
// The validators of this blockchain
|
||||
validators, ok := m.validators.GetValidatorSet(ids.Empty) // TODO: Change argument to chain.SubnetID
|
||||
var validators validators.Set // Validators validating this blockchain
|
||||
var ok bool
|
||||
if m.stakingEnabled {
|
||||
validators, ok = m.validators.GetValidatorSet(chain.SubnetID)
|
||||
} else { // Staking is disabled. Every peer validates every subnet.
|
||||
validators, ok = m.validators.GetValidatorSet(ids.Empty) // ids.Empty is the default subnet ID. TODO: Move to const package so we can use it here.
|
||||
}
|
||||
if !ok {
|
||||
m.log.Error("couldn't get validator set of subnet with ID %s. The subnet may not exist", chain.SubnetID)
|
||||
return
|
||||
|
@ -336,8 +362,8 @@ func (m *manager) createAvalancheChain(
|
|||
db := prefixdb.New(ctx.ChainID.Bytes(), m.db)
|
||||
vmDB := prefixdb.New([]byte("vm"), db)
|
||||
vertexDB := prefixdb.New([]byte("vertex"), db)
|
||||
vertexBootstrappingDB := prefixdb.New([]byte("vertex_bootstrapping"), db)
|
||||
txBootstrappingDB := prefixdb.New([]byte("tx_bootstrapping"), db)
|
||||
vertexBootstrappingDB := prefixdb.New([]byte("vertex_bs"), db)
|
||||
txBootstrappingDB := prefixdb.New([]byte("tx_bs"), db)
|
||||
|
||||
vtxBlocker, err := queue.New(vertexBootstrappingDB)
|
||||
if err != nil {
|
||||
|
@ -353,7 +379,7 @@ func (m *manager) createAvalancheChain(
|
|||
msgChan := make(chan common.Message, defaultChannelSize)
|
||||
|
||||
if err := vm.Initialize(ctx, vmDB, genesisData, msgChan, fxs); err != nil {
|
||||
return err
|
||||
return fmt.Errorf("error during vm's Initialize: %w", err)
|
||||
}
|
||||
|
||||
// Handles serialization/deserialization of vertices and also the
|
||||
|
@ -363,7 +389,7 @@ func (m *manager) createAvalancheChain(
|
|||
|
||||
// Passes messages from the consensus engine to the network
|
||||
sender := sender.Sender{}
|
||||
sender.Initialize(ctx, m.sender, m.chainRouter, m.timeoutManager)
|
||||
sender.Initialize(ctx, m.net, m.chainRouter, m.timeoutManager)
|
||||
|
||||
// The engine handles consensus
|
||||
engine := avaeng.Transitive{
|
||||
|
@ -376,13 +402,22 @@ func (m *manager) createAvalancheChain(
|
|||
},
|
||||
}
|
||||
|
||||
bootstrapWeight := uint64(0)
|
||||
for _, beacon := range beacons.List() {
|
||||
newWeight, err := math.Add64(bootstrapWeight, beacon.Weight())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
bootstrapWeight = newWeight
|
||||
}
|
||||
|
||||
engine.Initialize(avaeng.Config{
|
||||
BootstrapConfig: avaeng.BootstrapConfig{
|
||||
Config: common.Config{
|
||||
Context: ctx,
|
||||
Validators: validators,
|
||||
Beacons: beacons,
|
||||
Alpha: (beacons.Len() + 1) / 2,
|
||||
Alpha: bootstrapWeight/2 + 1, // must be > 50%
|
||||
Sender: &sender,
|
||||
},
|
||||
VtxBlocked: vtxBlocker,
|
||||
|
@ -395,26 +430,30 @@ func (m *manager) createAvalancheChain(
|
|||
})
|
||||
|
||||
// Asynchronously passes messages from the network to the consensus engine
|
||||
handler := &handler.Handler{}
|
||||
handler.Initialize(&engine, msgChan, defaultChannelSize)
|
||||
handler := &router.Handler{}
|
||||
handler.Initialize(
|
||||
&engine,
|
||||
msgChan,
|
||||
defaultChannelSize,
|
||||
fmt.Sprintf("%s_handler", consensusParams.Namespace),
|
||||
consensusParams.Metrics,
|
||||
)
|
||||
|
||||
// Allows messages to be routed to the new chain
|
||||
m.chainRouter.AddChain(handler)
|
||||
go ctx.Log.RecoverAndPanic(handler.Dispatch)
|
||||
|
||||
awaiting := &networking.AwaitingConnections{
|
||||
Finish: func() {
|
||||
ctx.Lock.Lock()
|
||||
defer ctx.Lock.Unlock()
|
||||
|
||||
engine.Startup()
|
||||
},
|
||||
reqWeight := (3*bootstrapWeight + 3) / 4
|
||||
if reqWeight == 0 {
|
||||
engine.Startup()
|
||||
} else {
|
||||
go m.net.RegisterHandler(&awaiter{
|
||||
vdrs: beacons,
|
||||
reqWeight: reqWeight, // 75% must be connected to
|
||||
ctx: ctx,
|
||||
eng: &engine,
|
||||
})
|
||||
}
|
||||
for _, vdr := range beacons.List() {
|
||||
awaiting.Requested.Add(vdr.ID())
|
||||
}
|
||||
awaiting.NumRequired = (3*awaiting.Requested.Len() + 3) / 4 // 75% must be connected to
|
||||
m.awaiter.AwaitConnections(awaiting)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
@ -434,7 +473,7 @@ func (m *manager) createSnowmanChain(
|
|||
|
||||
db := prefixdb.New(ctx.ChainID.Bytes(), m.db)
|
||||
vmDB := prefixdb.New([]byte("vm"), db)
|
||||
bootstrappingDB := prefixdb.New([]byte("bootstrapping"), db)
|
||||
bootstrappingDB := prefixdb.New([]byte("bs"), db)
|
||||
|
||||
blocked, err := queue.New(bootstrappingDB)
|
||||
if err != nil {
|
||||
|
@ -452,7 +491,16 @@ func (m *manager) createSnowmanChain(
|
|||
|
||||
// Passes messages from the consensus engine to the network
|
||||
sender := sender.Sender{}
|
||||
sender.Initialize(ctx, m.sender, m.chainRouter, m.timeoutManager)
|
||||
sender.Initialize(ctx, m.net, m.chainRouter, m.timeoutManager)
|
||||
|
||||
bootstrapWeight := uint64(0)
|
||||
for _, beacon := range beacons.List() {
|
||||
newWeight, err := math.Add64(bootstrapWeight, beacon.Weight())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
bootstrapWeight = newWeight
|
||||
}
|
||||
|
||||
// The engine handles consensus
|
||||
engine := smeng.Transitive{}
|
||||
|
@ -462,7 +510,7 @@ func (m *manager) createSnowmanChain(
|
|||
Context: ctx,
|
||||
Validators: validators,
|
||||
Beacons: beacons,
|
||||
Alpha: (beacons.Len() + 1) / 2,
|
||||
Alpha: bootstrapWeight/2 + 1, // must be > 50%
|
||||
Sender: &sender,
|
||||
},
|
||||
Blocked: blocked,
|
||||
|
@ -474,26 +522,30 @@ func (m *manager) createSnowmanChain(
|
|||
})
|
||||
|
||||
// Asynchronously passes messages from the network to the consensus engine
|
||||
handler := &handler.Handler{}
|
||||
handler.Initialize(&engine, msgChan, defaultChannelSize)
|
||||
handler := &router.Handler{}
|
||||
handler.Initialize(
|
||||
&engine,
|
||||
msgChan,
|
||||
defaultChannelSize,
|
||||
fmt.Sprintf("%s_handler", consensusParams.Namespace),
|
||||
consensusParams.Metrics,
|
||||
)
|
||||
|
||||
// Allow incoming messages to be routed to the new chain
|
||||
m.chainRouter.AddChain(handler)
|
||||
go ctx.Log.RecoverAndPanic(handler.Dispatch)
|
||||
|
||||
awaiting := &networking.AwaitingConnections{
|
||||
Finish: func() {
|
||||
ctx.Lock.Lock()
|
||||
defer ctx.Lock.Unlock()
|
||||
|
||||
engine.Startup()
|
||||
},
|
||||
reqWeight := (3*bootstrapWeight + 3) / 4
|
||||
if reqWeight == 0 {
|
||||
engine.Startup()
|
||||
} else {
|
||||
go m.net.RegisterHandler(&awaiter{
|
||||
vdrs: beacons,
|
||||
reqWeight: reqWeight, // 75% must be connected to
|
||||
ctx: ctx,
|
||||
eng: &engine,
|
||||
})
|
||||
}
|
||||
for _, vdr := range beacons.List() {
|
||||
awaiting.Requested.Add(vdr.ID())
|
||||
}
|
||||
awaiting.NumRequired = (3*awaiting.Requested.Len() + 3) / 4 // 75% must be connected to
|
||||
m.awaiter.AwaitConnections(awaiting)
|
||||
return nil
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,37 @@
|
|||
package chains
|
||||
|
||||
import (
|
||||
"github.com/ava-labs/gecko/ids"
|
||||
"github.com/ava-labs/gecko/snow/networking/router"
|
||||
)
|
||||
|
||||
// MockManager implements Manager but does nothing. Always returns nil error.
|
||||
// To be used only in tests (namely in package platformvm)
|
||||
type MockManager struct{}
|
||||
|
||||
// Router ...
|
||||
func (mm MockManager) Router() router.Router { return nil }
|
||||
|
||||
// CreateChain ...
|
||||
func (mm MockManager) CreateChain(ChainParameters) {}
|
||||
|
||||
// ForceCreateChain ...
|
||||
func (mm MockManager) ForceCreateChain(ChainParameters) {}
|
||||
|
||||
// AddRegistrant ...
|
||||
func (mm MockManager) AddRegistrant(Registrant) {}
|
||||
|
||||
// Lookup ...
|
||||
func (mm MockManager) Lookup(string) (ids.ID, error) { return ids.ID{}, nil }
|
||||
|
||||
// LookupVM ...
|
||||
func (mm MockManager) LookupVM(string) (ids.ID, error) { return ids.ID{}, nil }
|
||||
|
||||
// Aliases ...
|
||||
func (mm MockManager) Aliases(ids.ID) []string { return nil }
|
||||
|
||||
// Alias ...
|
||||
func (mm MockManager) Alias(ids.ID, string) error { return nil }
|
||||
|
||||
// Shutdown ...
|
||||
func (mm MockManager) Shutdown() {}
|
|
@ -23,6 +23,11 @@ type Batch interface {
|
|||
|
||||
// Replay replays the batch contents.
|
||||
Replay(w KeyValueWriter) error
|
||||
|
||||
// Inner returns a Batch writing to the inner database, if one exists. If
|
||||
// this batch is already writing to the base DB, then itself should be
|
||||
// returned.
|
||||
Inner() Batch
|
||||
}
|
||||
|
||||
// Batcher wraps the NewBatch method of a backing data store.
|
||||
|
|
|
@ -12,6 +12,7 @@ import (
|
|||
|
||||
"github.com/ava-labs/gecko/database"
|
||||
"github.com/ava-labs/gecko/database/nodb"
|
||||
"github.com/ava-labs/gecko/utils"
|
||||
"github.com/ava-labs/gecko/utils/hashing"
|
||||
"github.com/ava-labs/gecko/vms/components/codec"
|
||||
)
|
||||
|
@ -174,7 +175,7 @@ type batch struct {
|
|||
}
|
||||
|
||||
func (b *batch) Put(key, value []byte) error {
|
||||
b.writes = append(b.writes, keyValue{copyBytes(key), copyBytes(value), false})
|
||||
b.writes = append(b.writes, keyValue{utils.CopyBytes(key), utils.CopyBytes(value), false})
|
||||
encValue, err := b.db.encrypt(value)
|
||||
if err != nil {
|
||||
return err
|
||||
|
@ -183,7 +184,7 @@ func (b *batch) Put(key, value []byte) error {
|
|||
}
|
||||
|
||||
func (b *batch) Delete(key []byte) error {
|
||||
b.writes = append(b.writes, keyValue{copyBytes(key), nil, true})
|
||||
b.writes = append(b.writes, keyValue{utils.CopyBytes(key), nil, true})
|
||||
return b.Batch.Delete(key)
|
||||
}
|
||||
|
||||
|
@ -251,12 +252,6 @@ func (it *iterator) Error() error {
|
|||
|
||||
func (it *iterator) Value() []byte { return it.val }
|
||||
|
||||
func copyBytes(bytes []byte) []byte {
|
||||
copiedBytes := make([]byte, len(bytes))
|
||||
copy(copiedBytes, bytes)
|
||||
return copiedBytes
|
||||
}
|
||||
|
||||
type encryptedValue struct {
|
||||
Ciphertext []byte `serialize:"true"`
|
||||
Nonce []byte `serialize:"true"`
|
|
@ -17,46 +17,42 @@ package database
|
|||
// iterator until exhaustion. An iterator is not safe for concurrent use, but it
|
||||
// is safe to use multiple iterators concurrently.
|
||||
type Iterator interface {
|
||||
// Next moves the iterator to the next key/value pair. It returns whether the
|
||||
// iterator is exhausted.
|
||||
// Next moves the iterator to the next key/value pair. It returns whether
|
||||
// the iterator is exhausted.
|
||||
Next() bool
|
||||
|
||||
// Error returns any accumulated error. Exhausting all the key/value pairs
|
||||
// is not considered to be an error.
|
||||
Error() error
|
||||
|
||||
// Key returns the key of the current key/value pair, or nil if done. The caller
|
||||
// should not modify the contents of the returned slice, and its contents may
|
||||
// change on the next call to Next.
|
||||
// Key returns the key of the current key/value pair, or nil if done.
|
||||
Key() []byte
|
||||
|
||||
// Value returns the value of the current key/value pair, or nil if done. The
|
||||
// caller should not modify the contents of the returned slice, and its contents
|
||||
// may change on the next call to Next.
|
||||
// Value returns the value of the current key/value pair, or nil if done.
|
||||
Value() []byte
|
||||
|
||||
// Release releases associated resources. Release should always succeed and can
|
||||
// be called multiple times without causing error.
|
||||
// Release releases associated resources. Release should always succeed and
|
||||
// can be called multiple times without causing error.
|
||||
Release()
|
||||
}
|
||||
|
||||
// Iteratee wraps the NewIterator methods of a backing data store.
|
||||
type Iteratee interface {
|
||||
// NewIterator creates a binary-alphabetical iterator over the entire keyspace
|
||||
// contained within the key-value database.
|
||||
// NewIterator creates a binary-alphabetical iterator over the entire
|
||||
// keyspace contained within the key-value database.
|
||||
NewIterator() Iterator
|
||||
|
||||
// NewIteratorWithStart creates a binary-alphabetical iterator over a subset of
|
||||
// database content starting at a particular initial key (or after, if it does
|
||||
// not exist).
|
||||
// NewIteratorWithStart creates a binary-alphabetical iterator over a subset
|
||||
// of database content starting at a particular initial key (or after, if it
|
||||
// does not exist).
|
||||
NewIteratorWithStart(start []byte) Iterator
|
||||
|
||||
// NewIteratorWithPrefix creates a binary-alphabetical iterator over a subset
|
||||
// of database content with a particular key prefix.
|
||||
// NewIteratorWithPrefix creates a binary-alphabetical iterator over a
|
||||
// subset of database content with a particular key prefix.
|
||||
NewIteratorWithPrefix(prefix []byte) Iterator
|
||||
|
||||
// NewIteratorWithStartAndPrefix creates a binary-alphabetical iterator over a
|
||||
// subset of database content with a particular key prefix starting at a
|
||||
// NewIteratorWithStartAndPrefix creates a binary-alphabetical iterator over
|
||||
// a subset of database content with a particular key prefix starting at a
|
||||
// specified key.
|
||||
NewIteratorWithStartAndPrefix(start, prefix []byte) Iterator
|
||||
}
|
||||
|
|
|
@ -7,6 +7,7 @@ import (
|
|||
"bytes"
|
||||
|
||||
"github.com/ava-labs/gecko/database"
|
||||
"github.com/ava-labs/gecko/utils"
|
||||
"github.com/syndtr/goleveldb/leveldb"
|
||||
"github.com/syndtr/goleveldb/leveldb/errors"
|
||||
"github.com/syndtr/goleveldb/leveldb/filter"
|
||||
|
@ -184,6 +185,9 @@ func (b *batch) Replay(w database.KeyValueWriter) error {
|
|||
return updateError(replay.err)
|
||||
}
|
||||
|
||||
// Inner returns itself
|
||||
func (b *batch) Inner() database.Batch { return b }
|
||||
|
||||
type replayer struct {
|
||||
writer database.KeyValueWriter
|
||||
err error
|
||||
|
@ -205,7 +209,14 @@ func (r *replayer) Delete(key []byte) {
|
|||
|
||||
type iter struct{ iterator.Iterator }
|
||||
|
||||
func (i *iter) Error() error { return updateError(i.Iterator.Error()) }
|
||||
// Error implements the Iterator interface
|
||||
func (it *iter) Error() error { return updateError(it.Iterator.Error()) }
|
||||
|
||||
// Key implements the Iterator interface
|
||||
func (it *iter) Key() []byte { return utils.CopyBytes(it.Iterator.Key()) }
|
||||
|
||||
// Value implements the Iterator interface
|
||||
func (it *iter) Value() []byte { return utils.CopyBytes(it.Iterator.Value()) }
|
||||
|
||||
func updateError(err error) error {
|
||||
switch err {
|
|
@ -10,6 +10,7 @@ import (
|
|||
|
||||
"github.com/ava-labs/gecko/database"
|
||||
"github.com/ava-labs/gecko/database/nodb"
|
||||
"github.com/ava-labs/gecko/utils"
|
||||
)
|
||||
|
||||
// DefaultSize is the default initial size of the memory database
|
||||
|
@ -62,7 +63,7 @@ func (db *Database) Get(key []byte) ([]byte, error) {
|
|||
return nil, database.ErrClosed
|
||||
}
|
||||
if entry, ok := db.db[string(key)]; ok {
|
||||
return copyBytes(entry), nil
|
||||
return utils.CopyBytes(entry), nil
|
||||
}
|
||||
return nil, database.ErrNotFound
|
||||
}
|
||||
|
@ -75,7 +76,7 @@ func (db *Database) Put(key []byte, value []byte) error {
|
|||
if db.db == nil {
|
||||
return database.ErrClosed
|
||||
}
|
||||
db.db[string(key)] = copyBytes(value)
|
||||
db.db[string(key)] = utils.CopyBytes(value)
|
||||
return nil
|
||||
}
|
||||
|
||||
|
@ -154,13 +155,13 @@ type batch struct {
|
|||
}
|
||||
|
||||
func (b *batch) Put(key, value []byte) error {
|
||||
b.writes = append(b.writes, keyValue{copyBytes(key), copyBytes(value), false})
|
||||
b.writes = append(b.writes, keyValue{utils.CopyBytes(key), utils.CopyBytes(value), false})
|
||||
b.size += len(value)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (b *batch) Delete(key []byte) error {
|
||||
b.writes = append(b.writes, keyValue{copyBytes(key), nil, true})
|
||||
b.writes = append(b.writes, keyValue{utils.CopyBytes(key), nil, true})
|
||||
b.size++
|
||||
return nil
|
||||
}
|
||||
|
@ -208,6 +209,9 @@ func (b *batch) Replay(w database.KeyValueWriter) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
// Inner returns itself
|
||||
func (b *batch) Inner() database.Batch { return b }
|
||||
|
||||
type iterator struct {
|
||||
initialized bool
|
||||
keys []string
|
||||
|
@ -250,9 +254,3 @@ func (it *iterator) Value() []byte {
|
|||
|
||||
// Release implements the Iterator interface
|
||||
func (it *iterator) Release() { it.keys = nil; it.values = nil }
|
||||
|
||||
func copyBytes(bytes []byte) []byte {
|
||||
copiedBytes := make([]byte, len(bytes))
|
||||
copy(copiedBytes, bytes)
|
||||
return copiedBytes
|
||||
}
|
|
@ -69,6 +69,9 @@ func (*Batch) Reset() {}
|
|||
// Replay does nothing
|
||||
func (*Batch) Replay(database.KeyValueWriter) error { return database.ErrClosed }
|
||||
|
||||
// Inner returns itself
|
||||
func (b *Batch) Inner() database.Batch { return b }
|
||||
|
||||
// Iterator does nothing
|
||||
type Iterator struct{ Err error }
|
||||
|
|
@ -8,6 +8,7 @@ import (
|
|||
|
||||
"github.com/ava-labs/gecko/database"
|
||||
"github.com/ava-labs/gecko/database/nodb"
|
||||
"github.com/ava-labs/gecko/utils"
|
||||
"github.com/ava-labs/gecko/utils/hashing"
|
||||
)
|
||||
|
||||
|
@ -174,13 +175,13 @@ type batch struct {
|
|||
|
||||
// Put implements the Batch interface
|
||||
func (b *batch) Put(key, value []byte) error {
|
||||
b.writes = append(b.writes, keyValue{copyBytes(key), copyBytes(value), false})
|
||||
b.writes = append(b.writes, keyValue{utils.CopyBytes(key), utils.CopyBytes(value), false})
|
||||
return b.Batch.Put(b.db.prefix(key), value)
|
||||
}
|
||||
|
||||
// Delete implements the Batch interface
|
||||
func (b *batch) Delete(key []byte) error {
|
||||
b.writes = append(b.writes, keyValue{copyBytes(key), nil, true})
|
||||
b.writes = append(b.writes, keyValue{utils.CopyBytes(key), nil, true})
|
||||
return b.Batch.Delete(b.db.prefix(key))
|
||||
}
|
||||
|
||||
|
@ -229,9 +230,3 @@ func (it *iterator) Key() []byte {
|
|||
}
|
||||
return key
|
||||
}
|
||||
|
||||
func copyBytes(bytes []byte) []byte {
|
||||
copiedBytes := make([]byte, len(bytes))
|
||||
copy(copiedBytes, bytes)
|
||||
return copiedBytes
|
||||
}
|
|
@ -0,0 +1,263 @@
|
|||
// (c) 2019-2020, Ava Labs, Inc. All rights reserved.
|
||||
// See the file LICENSE for licensing terms.
|
||||
|
||||
package rpcdb
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"golang.org/x/net/context"
|
||||
|
||||
"github.com/ava-labs/gecko/database"
|
||||
"github.com/ava-labs/gecko/database/nodb"
|
||||
"github.com/ava-labs/gecko/database/rpcdb/rpcdbproto"
|
||||
"github.com/ava-labs/gecko/utils"
|
||||
)
|
||||
|
||||
var (
|
||||
errClosed = fmt.Sprintf("rpc error: code = Unknown desc = %s", database.ErrClosed)
|
||||
errNotFound = fmt.Sprintf("rpc error: code = Unknown desc = %s", database.ErrNotFound)
|
||||
)
|
||||
|
||||
// DatabaseClient is an implementation of database that talks over RPC.
|
||||
type DatabaseClient struct{ client rpcdbproto.DatabaseClient }
|
||||
|
||||
// NewClient returns a database instance connected to a remote database instance
|
||||
func NewClient(client rpcdbproto.DatabaseClient) *DatabaseClient {
|
||||
return &DatabaseClient{client: client}
|
||||
}
|
||||
|
||||
// Has returns false, nil
|
||||
func (db *DatabaseClient) Has(key []byte) (bool, error) {
|
||||
resp, err := db.client.Has(context.Background(), &rpcdbproto.HasRequest{
|
||||
Key: key,
|
||||
})
|
||||
if err != nil {
|
||||
return false, updateError(err)
|
||||
}
|
||||
return resp.Has, nil
|
||||
}
|
||||
|
||||
// Get returns nil, error
|
||||
func (db *DatabaseClient) Get(key []byte) ([]byte, error) {
|
||||
resp, err := db.client.Get(context.Background(), &rpcdbproto.GetRequest{
|
||||
Key: key,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, updateError(err)
|
||||
}
|
||||
return resp.Value, nil
|
||||
}
|
||||
|
||||
// Put returns nil
|
||||
func (db *DatabaseClient) Put(key, value []byte) error {
|
||||
_, err := db.client.Put(context.Background(), &rpcdbproto.PutRequest{
|
||||
Key: key,
|
||||
Value: value,
|
||||
})
|
||||
return updateError(err)
|
||||
}
|
||||
|
||||
// Delete returns nil
|
||||
func (db *DatabaseClient) Delete(key []byte) error {
|
||||
_, err := db.client.Delete(context.Background(), &rpcdbproto.DeleteRequest{
|
||||
Key: key,
|
||||
})
|
||||
return updateError(err)
|
||||
}
|
||||
|
||||
// NewBatch returns a new batch
|
||||
func (db *DatabaseClient) NewBatch() database.Batch { return &batch{db: db} }
|
||||
|
||||
// NewIterator implements the Database interface
|
||||
func (db *DatabaseClient) NewIterator() database.Iterator {
|
||||
return db.NewIteratorWithStartAndPrefix(nil, nil)
|
||||
}
|
||||
|
||||
// NewIteratorWithStart implements the Database interface
|
||||
func (db *DatabaseClient) NewIteratorWithStart(start []byte) database.Iterator {
|
||||
return db.NewIteratorWithStartAndPrefix(start, nil)
|
||||
}
|
||||
|
||||
// NewIteratorWithPrefix implements the Database interface
|
||||
func (db *DatabaseClient) NewIteratorWithPrefix(prefix []byte) database.Iterator {
|
||||
return db.NewIteratorWithStartAndPrefix(nil, prefix)
|
||||
}
|
||||
|
||||
// NewIteratorWithStartAndPrefix returns a new empty iterator
|
||||
func (db *DatabaseClient) NewIteratorWithStartAndPrefix(start, prefix []byte) database.Iterator {
|
||||
resp, err := db.client.NewIteratorWithStartAndPrefix(context.Background(), &rpcdbproto.NewIteratorWithStartAndPrefixRequest{
|
||||
Start: start,
|
||||
Prefix: prefix,
|
||||
})
|
||||
if err != nil {
|
||||
return &nodb.Iterator{Err: updateError(err)}
|
||||
}
|
||||
return &iterator{
|
||||
db: db,
|
||||
id: resp.Id,
|
||||
}
|
||||
}
|
||||
|
||||
// Stat returns an error
|
||||
func (db *DatabaseClient) Stat(property string) (string, error) {
|
||||
resp, err := db.client.Stat(context.Background(), &rpcdbproto.StatRequest{
|
||||
Property: property,
|
||||
})
|
||||
if err != nil {
|
||||
return "", updateError(err)
|
||||
}
|
||||
return resp.Stat, nil
|
||||
}
|
||||
|
||||
// Compact returns nil
|
||||
func (db *DatabaseClient) Compact(start, limit []byte) error {
|
||||
_, err := db.client.Compact(context.Background(), &rpcdbproto.CompactRequest{
|
||||
Start: start,
|
||||
Limit: limit,
|
||||
})
|
||||
return updateError(err)
|
||||
}
|
||||
|
||||
// Close returns nil
|
||||
func (db *DatabaseClient) Close() error {
|
||||
_, err := db.client.Close(context.Background(), &rpcdbproto.CloseRequest{})
|
||||
return updateError(err)
|
||||
}
|
||||
|
||||
type keyValue struct {
|
||||
key []byte
|
||||
value []byte
|
||||
delete bool
|
||||
}
|
||||
|
||||
type batch struct {
|
||||
db *DatabaseClient
|
||||
writes []keyValue
|
||||
size int
|
||||
}
|
||||
|
||||
func (b *batch) Put(key, value []byte) error {
|
||||
b.writes = append(b.writes, keyValue{utils.CopyBytes(key), utils.CopyBytes(value), false})
|
||||
b.size += len(value)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (b *batch) Delete(key []byte) error {
|
||||
b.writes = append(b.writes, keyValue{utils.CopyBytes(key), nil, true})
|
||||
b.size++
|
||||
return nil
|
||||
}
|
||||
|
||||
func (b *batch) ValueSize() int { return b.size }
|
||||
|
||||
func (b *batch) Write() error {
|
||||
request := &rpcdbproto.WriteBatchRequest{}
|
||||
|
||||
keySet := make(map[string]struct{}, len(b.writes))
|
||||
for i := len(b.writes) - 1; i >= 0; i-- {
|
||||
kv := b.writes[i]
|
||||
key := string(kv.key)
|
||||
if _, overwritten := keySet[key]; overwritten {
|
||||
continue
|
||||
}
|
||||
keySet[key] = struct{}{}
|
||||
|
||||
if kv.delete {
|
||||
request.Deletes = append(request.Deletes, &rpcdbproto.DeleteRequest{
|
||||
Key: kv.key,
|
||||
})
|
||||
} else {
|
||||
request.Puts = append(request.Puts, &rpcdbproto.PutRequest{
|
||||
Key: kv.key,
|
||||
Value: kv.value,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
_, err := b.db.client.WriteBatch(context.Background(), request)
|
||||
return updateError(err)
|
||||
}
|
||||
|
||||
func (b *batch) Reset() {
|
||||
b.writes = b.writes[:0]
|
||||
b.size = 0
|
||||
}
|
||||
|
||||
func (b *batch) Replay(w database.KeyValueWriter) error {
|
||||
for _, keyvalue := range b.writes {
|
||||
if keyvalue.delete {
|
||||
if err := w.Delete(keyvalue.key); err != nil {
|
||||
return err
|
||||
}
|
||||
} else if err := w.Put(keyvalue.key, keyvalue.value); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (b *batch) Inner() database.Batch { return b }
|
||||
|
||||
type iterator struct {
|
||||
db *DatabaseClient
|
||||
id uint64
|
||||
key []byte
|
||||
value []byte
|
||||
err error
|
||||
}
|
||||
|
||||
// Next returns false
|
||||
func (it *iterator) Next() bool {
|
||||
resp, err := it.db.client.IteratorNext(context.Background(), &rpcdbproto.IteratorNextRequest{
|
||||
Id: it.id,
|
||||
})
|
||||
if err != nil {
|
||||
it.err = err
|
||||
return false
|
||||
}
|
||||
it.key = resp.Key
|
||||
it.value = resp.Value
|
||||
return resp.FoundNext
|
||||
}
|
||||
|
||||
// Error returns any errors
|
||||
func (it *iterator) Error() error {
|
||||
if it.err != nil {
|
||||
return it.err
|
||||
}
|
||||
|
||||
_, err := it.db.client.IteratorError(context.Background(), &rpcdbproto.IteratorErrorRequest{
|
||||
Id: it.id,
|
||||
})
|
||||
it.err = updateError(err)
|
||||
return it.err
|
||||
}
|
||||
|
||||
// Key returns nil
|
||||
func (it *iterator) Key() []byte { return it.key }
|
||||
|
||||
// Value returns nil
|
||||
func (it *iterator) Value() []byte { return it.value }
|
||||
|
||||
// Release does nothing
|
||||
func (it *iterator) Release() {
|
||||
it.db.client.IteratorRelease(context.Background(), &rpcdbproto.IteratorReleaseRequest{
|
||||
Id: it.id,
|
||||
})
|
||||
}
|
||||
|
||||
func updateError(err error) error {
|
||||
if err == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
switch err.Error() {
|
||||
case errClosed:
|
||||
return database.ErrClosed
|
||||
case errNotFound:
|
||||
return database.ErrNotFound
|
||||
default:
|
||||
return err
|
||||
}
|
||||
}
|
|
@ -0,0 +1,143 @@
|
|||
// (c) 2019-2020, Ava Labs, Inc. All rights reserved.
|
||||
// See the file LICENSE for licensing terms.
|
||||
|
||||
package rpcdb
|
||||
|
||||
import (
|
||||
"errors"
|
||||
|
||||
"golang.org/x/net/context"
|
||||
|
||||
"github.com/ava-labs/gecko/database"
|
||||
"github.com/ava-labs/gecko/database/rpcdb/rpcdbproto"
|
||||
)
|
||||
|
||||
var (
|
||||
errUnknownIterator = errors.New("unknown iterator")
|
||||
)
|
||||
|
||||
// DatabaseServer is a database that is managed over RPC.
|
||||
type DatabaseServer struct {
|
||||
db database.Database
|
||||
batch database.Batch
|
||||
|
||||
nextIteratorID uint64
|
||||
iterators map[uint64]database.Iterator
|
||||
}
|
||||
|
||||
// NewServer returns a database instance that is managed remotely
|
||||
func NewServer(db database.Database) *DatabaseServer {
|
||||
return &DatabaseServer{
|
||||
db: db,
|
||||
batch: db.NewBatch(),
|
||||
iterators: make(map[uint64]database.Iterator),
|
||||
}
|
||||
}
|
||||
|
||||
// Has ...
|
||||
func (db *DatabaseServer) Has(_ context.Context, req *rpcdbproto.HasRequest) (*rpcdbproto.HasResponse, error) {
|
||||
has, err := db.db.Has(req.Key)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &rpcdbproto.HasResponse{Has: has}, nil
|
||||
}
|
||||
|
||||
// Get ...
|
||||
func (db *DatabaseServer) Get(_ context.Context, req *rpcdbproto.GetRequest) (*rpcdbproto.GetResponse, error) {
|
||||
value, err := db.db.Get(req.Key)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &rpcdbproto.GetResponse{Value: value}, nil
|
||||
}
|
||||
|
||||
// Put ...
|
||||
func (db *DatabaseServer) Put(_ context.Context, req *rpcdbproto.PutRequest) (*rpcdbproto.PutResponse, error) {
|
||||
return &rpcdbproto.PutResponse{}, db.db.Put(req.Key, req.Value)
|
||||
}
|
||||
|
||||
// Delete ...
|
||||
func (db *DatabaseServer) Delete(_ context.Context, req *rpcdbproto.DeleteRequest) (*rpcdbproto.DeleteResponse, error) {
|
||||
return &rpcdbproto.DeleteResponse{}, db.db.Delete(req.Key)
|
||||
}
|
||||
|
||||
// Stat ...
|
||||
func (db *DatabaseServer) Stat(_ context.Context, req *rpcdbproto.StatRequest) (*rpcdbproto.StatResponse, error) {
|
||||
stat, err := db.db.Stat(req.Property)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &rpcdbproto.StatResponse{Stat: stat}, nil
|
||||
}
|
||||
|
||||
// Compact ...
|
||||
func (db *DatabaseServer) Compact(_ context.Context, req *rpcdbproto.CompactRequest) (*rpcdbproto.CompactResponse, error) {
|
||||
return &rpcdbproto.CompactResponse{}, db.db.Compact(req.Start, req.Limit)
|
||||
}
|
||||
|
||||
// Close ...
|
||||
func (db *DatabaseServer) Close(_ context.Context, _ *rpcdbproto.CloseRequest) (*rpcdbproto.CloseResponse, error) {
|
||||
return &rpcdbproto.CloseResponse{}, db.db.Close()
|
||||
}
|
||||
|
||||
// WriteBatch ...
|
||||
func (db *DatabaseServer) WriteBatch(_ context.Context, req *rpcdbproto.WriteBatchRequest) (*rpcdbproto.WriteBatchResponse, error) {
|
||||
db.batch.Reset()
|
||||
|
||||
for _, put := range req.Puts {
|
||||
if err := db.batch.Put(put.Key, put.Value); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
for _, del := range req.Deletes {
|
||||
if err := db.batch.Delete(del.Key); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
return &rpcdbproto.WriteBatchResponse{}, db.batch.Write()
|
||||
}
|
||||
|
||||
// NewIteratorWithStartAndPrefix ...
|
||||
func (db *DatabaseServer) NewIteratorWithStartAndPrefix(_ context.Context, req *rpcdbproto.NewIteratorWithStartAndPrefixRequest) (*rpcdbproto.NewIteratorWithStartAndPrefixResponse, error) {
|
||||
id := db.nextIteratorID
|
||||
it := db.db.NewIteratorWithStartAndPrefix(req.Start, req.Prefix)
|
||||
db.iterators[id] = it
|
||||
|
||||
db.nextIteratorID++
|
||||
return &rpcdbproto.NewIteratorWithStartAndPrefixResponse{Id: id}, nil
|
||||
}
|
||||
|
||||
// IteratorNext ...
|
||||
func (db *DatabaseServer) IteratorNext(_ context.Context, req *rpcdbproto.IteratorNextRequest) (*rpcdbproto.IteratorNextResponse, error) {
|
||||
it, exists := db.iterators[req.Id]
|
||||
if !exists {
|
||||
return nil, errUnknownIterator
|
||||
}
|
||||
return &rpcdbproto.IteratorNextResponse{
|
||||
FoundNext: it.Next(),
|
||||
Key: it.Key(),
|
||||
Value: it.Value(),
|
||||
}, nil
|
||||
}
|
||||
|
||||
// IteratorError ...
|
||||
func (db *DatabaseServer) IteratorError(_ context.Context, req *rpcdbproto.IteratorErrorRequest) (*rpcdbproto.IteratorErrorResponse, error) {
|
||||
it, exists := db.iterators[req.Id]
|
||||
if !exists {
|
||||
return nil, errUnknownIterator
|
||||
}
|
||||
return &rpcdbproto.IteratorErrorResponse{}, it.Error()
|
||||
}
|
||||
|
||||
// IteratorRelease ...
|
||||
func (db *DatabaseServer) IteratorRelease(_ context.Context, req *rpcdbproto.IteratorReleaseRequest) (*rpcdbproto.IteratorReleaseResponse, error) {
|
||||
it, exists := db.iterators[req.Id]
|
||||
if exists {
|
||||
delete(db.iterators, req.Id)
|
||||
it.Release()
|
||||
}
|
||||
return &rpcdbproto.IteratorReleaseResponse{}, nil
|
||||
}
|
|
@ -0,0 +1,51 @@
|
|||
// (c) 2019-2020, Ava Labs, Inc. All rights reserved.
|
||||
// See the file LICENSE for licensing terms.
|
||||
|
||||
package rpcdb
|
||||
|
||||
import (
|
||||
"log"
|
||||
"net"
|
||||
"testing"
|
||||
|
||||
"golang.org/x/net/context"
|
||||
|
||||
"google.golang.org/grpc"
|
||||
"google.golang.org/grpc/test/bufconn"
|
||||
|
||||
"github.com/ava-labs/gecko/database"
|
||||
"github.com/ava-labs/gecko/database/memdb"
|
||||
"github.com/ava-labs/gecko/database/rpcdb/rpcdbproto"
|
||||
)
|
||||
|
||||
const (
|
||||
bufSize = 1 << 20
|
||||
)
|
||||
|
||||
func TestInterface(t *testing.T) {
|
||||
for _, test := range database.Tests {
|
||||
listener := bufconn.Listen(bufSize)
|
||||
server := grpc.NewServer()
|
||||
rpcdbproto.RegisterDatabaseServer(server, NewServer(memdb.New()))
|
||||
go func() {
|
||||
if err := server.Serve(listener); err != nil {
|
||||
log.Fatalf("Server exited with error: %v", err)
|
||||
}
|
||||
}()
|
||||
|
||||
dialer := grpc.WithContextDialer(
|
||||
func(context.Context, string) (net.Conn, error) {
|
||||
return listener.Dial()
|
||||
})
|
||||
|
||||
ctx := context.Background()
|
||||
conn, err := grpc.DialContext(ctx, "", dialer, grpc.WithInsecure())
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to dial: %s", err)
|
||||
}
|
||||
|
||||
db := NewClient(rpcdbproto.NewDatabaseClient(conn))
|
||||
test(t, db)
|
||||
conn.Close()
|
||||
}
|
||||
}
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,108 @@
|
|||
syntax = "proto3";
|
||||
package rpcdbproto;
|
||||
|
||||
message HasRequest {
|
||||
bytes key = 1;
|
||||
}
|
||||
|
||||
message HasResponse {
|
||||
bool has = 1;
|
||||
}
|
||||
|
||||
message GetRequest {
|
||||
bytes key = 1;
|
||||
}
|
||||
|
||||
message GetResponse {
|
||||
bytes value = 1;
|
||||
}
|
||||
|
||||
message PutRequest {
|
||||
bytes key = 1;
|
||||
bytes value = 2;
|
||||
}
|
||||
|
||||
message PutResponse {}
|
||||
|
||||
message DeleteRequest {
|
||||
bytes key = 1;
|
||||
}
|
||||
|
||||
message DeleteResponse {}
|
||||
|
||||
message StatRequest {
|
||||
string property = 1;
|
||||
}
|
||||
|
||||
message StatResponse {
|
||||
string stat = 1;
|
||||
}
|
||||
|
||||
message CompactRequest {
|
||||
bytes start = 1;
|
||||
bytes limit = 2;
|
||||
}
|
||||
|
||||
message CompactResponse {}
|
||||
|
||||
message CloseRequest {}
|
||||
|
||||
message CloseResponse {}
|
||||
|
||||
message WriteBatchRequest {
|
||||
repeated PutRequest puts = 1;
|
||||
repeated DeleteRequest deletes = 2;
|
||||
}
|
||||
|
||||
message WriteBatchResponse {}
|
||||
|
||||
message NewIteratorRequest {}
|
||||
|
||||
message NewIteratorWithStartAndPrefixRequest {
|
||||
bytes start = 1;
|
||||
bytes prefix = 2;
|
||||
}
|
||||
|
||||
message NewIteratorWithStartAndPrefixResponse {
|
||||
uint64 id = 1;
|
||||
}
|
||||
|
||||
message IteratorNextRequest {
|
||||
uint64 id = 1;
|
||||
}
|
||||
|
||||
message IteratorNextResponse {
|
||||
bool foundNext = 1;
|
||||
bytes key = 2;
|
||||
bytes value = 3;
|
||||
}
|
||||
|
||||
message IteratorErrorRequest {
|
||||
uint64 id = 1;
|
||||
}
|
||||
|
||||
message IteratorErrorResponse {}
|
||||
|
||||
message IteratorReleaseRequest {
|
||||
uint64 id = 1;
|
||||
}
|
||||
|
||||
message IteratorReleaseResponse {}
|
||||
|
||||
service Database {
|
||||
rpc Has(HasRequest) returns (HasResponse);
|
||||
rpc Get(GetRequest) returns (GetResponse);
|
||||
rpc Put(PutRequest) returns (PutResponse);
|
||||
rpc Delete(DeleteRequest) returns (DeleteResponse);
|
||||
rpc Stat(StatRequest) returns (StatResponse);
|
||||
rpc Compact(CompactRequest) returns (CompactResponse);
|
||||
rpc Close(CloseRequest) returns (CloseResponse);
|
||||
|
||||
rpc WriteBatch(WriteBatchRequest) returns (WriteBatchResponse);
|
||||
|
||||
rpc NewIteratorWithStartAndPrefix(NewIteratorWithStartAndPrefixRequest) returns (NewIteratorWithStartAndPrefixResponse);
|
||||
|
||||
rpc IteratorNext(IteratorNextRequest) returns (IteratorNextResponse);
|
||||
rpc IteratorError(IteratorErrorRequest) returns (IteratorErrorResponse);
|
||||
rpc IteratorRelease(IteratorReleaseRequest) returns (IteratorReleaseResponse);
|
||||
}
|
|
@ -16,11 +16,15 @@ var (
|
|||
TestBatchPut,
|
||||
TestBatchDelete,
|
||||
TestBatchReset,
|
||||
TestBatchReuse,
|
||||
TestBatchRewrite,
|
||||
TestBatchReplay,
|
||||
TestBatchInner,
|
||||
TestIterator,
|
||||
TestIteratorStart,
|
||||
TestIteratorPrefix,
|
||||
TestIteratorStartPrefix,
|
||||
TestIteratorMemorySafety,
|
||||
TestIteratorClosed,
|
||||
TestStatNoPanic,
|
||||
TestCompactNoPanic,
|
||||
|
@ -235,6 +239,105 @@ func TestBatchReset(t *testing.T, db Database) {
|
|||
}
|
||||
}
|
||||
|
||||
// TestBatchReuse ...
|
||||
func TestBatchReuse(t *testing.T, db Database) {
|
||||
key1 := []byte("hello1")
|
||||
value1 := []byte("world1")
|
||||
|
||||
key2 := []byte("hello2")
|
||||
value2 := []byte("world2")
|
||||
|
||||
batch := db.NewBatch()
|
||||
if batch == nil {
|
||||
t.Fatalf("db.NewBatch returned nil")
|
||||
}
|
||||
|
||||
if err := batch.Put(key1, value1); err != nil {
|
||||
t.Fatalf("Unexpected error on batch.Put: %s", err)
|
||||
}
|
||||
|
||||
if err := batch.Write(); err != nil {
|
||||
t.Fatalf("Unexpected error on batch.Write: %s", err)
|
||||
}
|
||||
|
||||
if err := db.Delete(key1); err != nil {
|
||||
t.Fatalf("Unexpected error on database.Delete: %s", err)
|
||||
}
|
||||
|
||||
if has, err := db.Has(key1); err != nil {
|
||||
t.Fatalf("Unexpected error on db.Has: %s", err)
|
||||
} else if has {
|
||||
t.Fatalf("db.Has unexpectedly returned true on key %s", key1)
|
||||
}
|
||||
|
||||
batch.Reset()
|
||||
|
||||
if err := batch.Put(key2, value2); err != nil {
|
||||
t.Fatalf("Unexpected error on batch.Put: %s", err)
|
||||
}
|
||||
|
||||
if err := batch.Write(); err != nil {
|
||||
t.Fatalf("Unexpected error on batch.Write: %s", err)
|
||||
}
|
||||
|
||||
if has, err := db.Has(key1); err != nil {
|
||||
t.Fatalf("Unexpected error on db.Has: %s", err)
|
||||
} else if has {
|
||||
t.Fatalf("db.Has unexpectedly returned true on key %s", key1)
|
||||
} else if has, err := db.Has(key2); err != nil {
|
||||
t.Fatalf("Unexpected error on db.Has: %s", err)
|
||||
} else if !has {
|
||||
t.Fatalf("db.Has unexpectedly returned false on key %s", key2)
|
||||
} else if v, err := db.Get(key2); err != nil {
|
||||
t.Fatalf("Unexpected error on db.Get: %s", err)
|
||||
} else if !bytes.Equal(value2, v) {
|
||||
t.Fatalf("db.Get: Returned: 0x%x ; Expected: 0x%x", v, value2)
|
||||
}
|
||||
}
|
||||
|
||||
// TestBatchRewrite ...
|
||||
func TestBatchRewrite(t *testing.T, db Database) {
|
||||
key := []byte("hello1")
|
||||
value := []byte("world1")
|
||||
|
||||
batch := db.NewBatch()
|
||||
if batch == nil {
|
||||
t.Fatalf("db.NewBatch returned nil")
|
||||
}
|
||||
|
||||
if err := batch.Put(key, value); err != nil {
|
||||
t.Fatalf("Unexpected error on batch.Put: %s", err)
|
||||
}
|
||||
|
||||
if err := batch.Write(); err != nil {
|
||||
t.Fatalf("Unexpected error on batch.Write: %s", err)
|
||||
}
|
||||
|
||||
if err := db.Delete(key); err != nil {
|
||||
t.Fatalf("Unexpected error on database.Delete: %s", err)
|
||||
}
|
||||
|
||||
if has, err := db.Has(key); err != nil {
|
||||
t.Fatalf("Unexpected error on db.Has: %s", err)
|
||||
} else if has {
|
||||
t.Fatalf("db.Has unexpectedly returned true on key %s", key)
|
||||
}
|
||||
|
||||
if err := batch.Write(); err != nil {
|
||||
t.Fatalf("Unexpected error on batch.Write: %s", err)
|
||||
}
|
||||
|
||||
if has, err := db.Has(key); err != nil {
|
||||
t.Fatalf("Unexpected error on db.Has: %s", err)
|
||||
} else if !has {
|
||||
t.Fatalf("db.Has unexpectedly returned false on key %s", key)
|
||||
} else if v, err := db.Get(key); err != nil {
|
||||
t.Fatalf("Unexpected error on db.Get: %s", err)
|
||||
} else if !bytes.Equal(value, v) {
|
||||
t.Fatalf("db.Get: Returned: 0x%x ; Expected: 0x%x", v, value)
|
||||
}
|
||||
}
|
||||
|
||||
// TestBatchReplay ...
|
||||
func TestBatchReplay(t *testing.T, db Database) {
|
||||
key1 := []byte("hello1")
|
||||
|
@ -299,6 +402,62 @@ func TestBatchReplay(t *testing.T, db Database) {
|
|||
}
|
||||
}
|
||||
|
||||
// TestBatchInner ...
|
||||
func TestBatchInner(t *testing.T, db Database) {
|
||||
key1 := []byte("hello1")
|
||||
value1 := []byte("world1")
|
||||
|
||||
key2 := []byte("hello2")
|
||||
value2 := []byte("world2")
|
||||
|
||||
firstBatch := db.NewBatch()
|
||||
if firstBatch == nil {
|
||||
t.Fatalf("db.NewBatch returned nil")
|
||||
}
|
||||
|
||||
if err := firstBatch.Put(key1, value1); err != nil {
|
||||
t.Fatalf("Unexpected error on batch.Put: %s", err)
|
||||
}
|
||||
|
||||
secondBatch := db.NewBatch()
|
||||
if secondBatch == nil {
|
||||
t.Fatalf("db.NewBatch returned nil")
|
||||
}
|
||||
|
||||
if err := secondBatch.Put(key2, value2); err != nil {
|
||||
t.Fatalf("Unexpected error on batch.Put: %s", err)
|
||||
}
|
||||
|
||||
innerFirstBatch := firstBatch.Inner()
|
||||
innerSecondBatch := secondBatch.Inner()
|
||||
|
||||
if err := innerFirstBatch.Replay(innerSecondBatch); err != nil {
|
||||
t.Fatalf("Unexpected error on batch.Replay: %s", err)
|
||||
}
|
||||
|
||||
if err := innerSecondBatch.Write(); err != nil {
|
||||
t.Fatalf("Unexpected error on batch.Write: %s", err)
|
||||
}
|
||||
|
||||
if has, err := db.Has(key1); err != nil {
|
||||
t.Fatalf("Unexpected error on db.Has: %s", err)
|
||||
} else if !has {
|
||||
t.Fatalf("db.Has unexpectedly returned false on key %s", key1)
|
||||
} else if v, err := db.Get(key1); err != nil {
|
||||
t.Fatalf("Unexpected error on db.Get: %s", err)
|
||||
} else if !bytes.Equal(value1, v) {
|
||||
t.Fatalf("db.Get: Returned: 0x%x ; Expected: 0x%x", v, value1)
|
||||
} else if has, err := db.Has(key2); err != nil {
|
||||
t.Fatalf("Unexpected error on db.Has: %s", err)
|
||||
} else if !has {
|
||||
t.Fatalf("db.Has unexpectedly returned false on key %s", key2)
|
||||
} else if v, err := db.Get(key2); err != nil {
|
||||
t.Fatalf("Unexpected error on db.Get: %s", err)
|
||||
} else if !bytes.Equal(value2, v) {
|
||||
t.Fatalf("db.Get: Returned: 0x%x ; Expected: 0x%x", v, value2)
|
||||
}
|
||||
}
|
||||
|
||||
// TestIterator ...
|
||||
func TestIterator(t *testing.T, db Database) {
|
||||
key1 := []byte("hello1")
|
||||
|
@ -464,6 +623,63 @@ func TestIteratorStartPrefix(t *testing.T, db Database) {
|
|||
}
|
||||
}
|
||||
|
||||
// TestIteratorMemorySafety ...
|
||||
func TestIteratorMemorySafety(t *testing.T, db Database) {
|
||||
key1 := []byte("hello1")
|
||||
value1 := []byte("world1")
|
||||
|
||||
key2 := []byte("z")
|
||||
value2 := []byte("world2")
|
||||
|
||||
key3 := []byte("hello3")
|
||||
value3 := []byte("world3")
|
||||
|
||||
if err := db.Put(key1, value1); err != nil {
|
||||
t.Fatalf("Unexpected error on batch.Put: %s", err)
|
||||
} else if err := db.Put(key2, value2); err != nil {
|
||||
t.Fatalf("Unexpected error on batch.Put: %s", err)
|
||||
} else if err := db.Put(key3, value3); err != nil {
|
||||
t.Fatalf("Unexpected error on batch.Put: %s", err)
|
||||
}
|
||||
|
||||
iterator := db.NewIterator()
|
||||
if iterator == nil {
|
||||
t.Fatalf("db.NewIterator returned nil")
|
||||
}
|
||||
defer iterator.Release()
|
||||
|
||||
keys := [][]byte{}
|
||||
values := [][]byte{}
|
||||
for iterator.Next() {
|
||||
keys = append(keys, iterator.Key())
|
||||
values = append(values, iterator.Value())
|
||||
}
|
||||
|
||||
expectedKeys := [][]byte{
|
||||
key1,
|
||||
key3,
|
||||
key2,
|
||||
}
|
||||
expectedValues := [][]byte{
|
||||
value1,
|
||||
value3,
|
||||
value2,
|
||||
}
|
||||
|
||||
for i, key := range keys {
|
||||
value := values[i]
|
||||
expectedKey := expectedKeys[i]
|
||||
expectedValue := expectedValues[i]
|
||||
|
||||
if !bytes.Equal(key, expectedKey) {
|
||||
t.Fatalf("Wrong key")
|
||||
}
|
||||
if !bytes.Equal(value, expectedValue) {
|
||||
t.Fatalf("Wrong key")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// TestIteratorClosed ...
|
||||
func TestIteratorClosed(t *testing.T, db Database) {
|
||||
key1 := []byte("hello1")
|
||||
|
|
|
@ -11,6 +11,7 @@ import (
|
|||
"github.com/ava-labs/gecko/database"
|
||||
"github.com/ava-labs/gecko/database/memdb"
|
||||
"github.com/ava-labs/gecko/database/nodb"
|
||||
"github.com/ava-labs/gecko/utils"
|
||||
)
|
||||
|
||||
// Database implements the Database interface by living on top of another
|
||||
|
@ -61,7 +62,7 @@ func (db *Database) Get(key []byte) ([]byte, error) {
|
|||
if val.delete {
|
||||
return nil, database.ErrNotFound
|
||||
}
|
||||
return copyBytes(val.value), nil
|
||||
return utils.CopyBytes(val.value), nil
|
||||
}
|
||||
return db.db.Get(key)
|
||||
}
|
||||
|
@ -184,29 +185,55 @@ func (db *Database) Commit() error {
|
|||
db.lock.Lock()
|
||||
defer db.lock.Unlock()
|
||||
|
||||
if db.mem == nil {
|
||||
return database.ErrClosed
|
||||
batch, err := db.commitBatch()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if len(db.mem) == 0 {
|
||||
return nil
|
||||
if err := batch.Write(); err != nil {
|
||||
return err
|
||||
}
|
||||
db.abort()
|
||||
return nil
|
||||
}
|
||||
|
||||
// Abort all changes to the underlying database
|
||||
func (db *Database) Abort() {
|
||||
db.lock.Lock()
|
||||
defer db.lock.Unlock()
|
||||
|
||||
db.abort()
|
||||
}
|
||||
|
||||
func (db *Database) abort() { db.mem = make(map[string]valueDelete, memdb.DefaultSize) }
|
||||
|
||||
// CommitBatch returns a batch that will commit all pending writes to the underlying database
|
||||
func (db *Database) CommitBatch() (database.Batch, error) {
|
||||
db.lock.Lock()
|
||||
defer db.lock.Unlock()
|
||||
|
||||
return db.commitBatch()
|
||||
}
|
||||
|
||||
func (db *Database) commitBatch() (database.Batch, error) {
|
||||
if db.mem == nil {
|
||||
return nil, database.ErrClosed
|
||||
}
|
||||
|
||||
batch := db.db.NewBatch()
|
||||
for key, value := range db.mem {
|
||||
if value.delete {
|
||||
if err := batch.Delete([]byte(key)); err != nil {
|
||||
return err
|
||||
return nil, err
|
||||
}
|
||||
} else if err := batch.Put([]byte(key), value.value); err != nil {
|
||||
return err
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
if err := batch.Write(); err != nil {
|
||||
return err
|
||||
return nil, err
|
||||
}
|
||||
|
||||
db.mem = make(map[string]valueDelete, memdb.DefaultSize)
|
||||
return nil
|
||||
return batch, nil
|
||||
}
|
||||
|
||||
// Close implements the database.Database interface
|
||||
|
@ -236,14 +263,14 @@ type batch struct {
|
|||
|
||||
// Put implements the Database interface
|
||||
func (b *batch) Put(key, value []byte) error {
|
||||
b.writes = append(b.writes, keyValue{copyBytes(key), copyBytes(value), false})
|
||||
b.writes = append(b.writes, keyValue{utils.CopyBytes(key), utils.CopyBytes(value), false})
|
||||
b.size += len(value)
|
||||
return nil
|
||||
}
|
||||
|
||||
// Delete implements the Database interface
|
||||
func (b *batch) Delete(key []byte) error {
|
||||
b.writes = append(b.writes, keyValue{copyBytes(key), nil, true})
|
||||
b.writes = append(b.writes, keyValue{utils.CopyBytes(key), nil, true})
|
||||
b.size++
|
||||
return nil
|
||||
}
|
||||
|
@ -289,6 +316,9 @@ func (b *batch) Replay(w database.KeyValueWriter) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
// Inner returns itself
|
||||
func (b *batch) Inner() database.Batch { return b }
|
||||
|
||||
// iterator walks over both the in memory database and the underlying database
|
||||
// at the same time.
|
||||
type iterator struct {
|
||||
|
@ -385,9 +415,3 @@ func (it *iterator) Release() {
|
|||
it.values = nil
|
||||
it.Iterator.Release()
|
||||
}
|
||||
|
||||
func copyBytes(bytes []byte) []byte {
|
||||
copiedBytes := make([]byte, len(bytes))
|
||||
copy(copiedBytes, bytes)
|
||||
return copiedBytes
|
||||
}
|
|
@ -256,6 +256,72 @@ func TestCommitClosedDelete(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
func TestAbort(t *testing.T) {
|
||||
baseDB := memdb.New()
|
||||
db := New(baseDB)
|
||||
|
||||
key1 := []byte("hello1")
|
||||
value1 := []byte("world1")
|
||||
|
||||
if err := db.Put(key1, value1); err != nil {
|
||||
t.Fatalf("Unexpected error on db.Put: %s", err)
|
||||
}
|
||||
|
||||
if value, err := db.Get(key1); err != nil {
|
||||
t.Fatalf("Unexpected error on db.Get: %s", err)
|
||||
} else if !bytes.Equal(value, value1) {
|
||||
t.Fatalf("db.Get Returned: 0x%x ; Expected: 0x%x", value, value1)
|
||||
} else if has, err := baseDB.Has(key1); err != nil {
|
||||
t.Fatalf("Unexpected error on db.Has: %s", err)
|
||||
} else if has {
|
||||
t.Fatalf("db.Has Returned: %v ; Expected: %v", has, false)
|
||||
}
|
||||
|
||||
db.Abort()
|
||||
|
||||
if has, err := db.Has(key1); err != nil {
|
||||
t.Fatalf("Unexpected error on db.Has: %s", err)
|
||||
} else if has {
|
||||
t.Fatalf("db.Has Returned: %v ; Expected: %v", has, false)
|
||||
} else if has, err := baseDB.Has(key1); err != nil {
|
||||
t.Fatalf("Unexpected error on db.Has: %s", err)
|
||||
} else if has {
|
||||
t.Fatalf("db.Has Returned: %v ; Expected: %v", has, false)
|
||||
}
|
||||
}
|
||||
|
||||
func TestCommitBatch(t *testing.T) {
|
||||
baseDB := memdb.New()
|
||||
db := New(baseDB)
|
||||
|
||||
key1 := []byte("hello1")
|
||||
value1 := []byte("world1")
|
||||
|
||||
if err := db.Put(key1, value1); err != nil {
|
||||
t.Fatalf("Unexpected error on db.Put: %s", err)
|
||||
}
|
||||
|
||||
batch, err := db.CommitBatch()
|
||||
if err != nil {
|
||||
t.Fatalf("Unexpected error on db.CommitBatch: %s", err)
|
||||
}
|
||||
db.Abort()
|
||||
|
||||
if err := batch.Write(); err != nil {
|
||||
t.Fatalf("Unexpected error on batch.Write: %s", err)
|
||||
}
|
||||
|
||||
if value, err := db.Get(key1); err != nil {
|
||||
t.Fatalf("Unexpected error on db.Get: %s", err)
|
||||
} else if !bytes.Equal(value, value1) {
|
||||
t.Fatalf("db.Get Returned: 0x%x ; Expected: 0x%x", value, value1)
|
||||
} else if value, err := baseDB.Get(key1); err != nil {
|
||||
t.Fatalf("Unexpected error on db.Get: %s", err)
|
||||
} else if !bytes.Equal(value, value1) {
|
||||
t.Fatalf("db.Get Returned: 0x%x ; Expected: 0x%x", value, value1)
|
||||
}
|
||||
}
|
||||
|
||||
func TestSetDatabase(t *testing.T) {
|
||||
baseDB := memdb.New()
|
||||
newDB := memdb.New()
|
|
@ -0,0 +1,77 @@
|
|||
// (c) 2019-2020, Ava Labs, Inc. All rights reserved.
|
||||
// See the file LICENSE for licensing terms.
|
||||
|
||||
package genesis
|
||||
|
||||
import (
|
||||
"github.com/ava-labs/gecko/ids"
|
||||
"github.com/ava-labs/gecko/vms/avm"
|
||||
"github.com/ava-labs/gecko/vms/nftfx"
|
||||
"github.com/ava-labs/gecko/vms/platformvm"
|
||||
"github.com/ava-labs/gecko/vms/propertyfx"
|
||||
"github.com/ava-labs/gecko/vms/secp256k1fx"
|
||||
"github.com/ava-labs/gecko/vms/spchainvm"
|
||||
"github.com/ava-labs/gecko/vms/spdagvm"
|
||||
"github.com/ava-labs/gecko/vms/timestampvm"
|
||||
)
|
||||
|
||||
// Aliases returns the default aliases based on the network ID
|
||||
func Aliases(networkID uint32) (map[string][]string, map[[32]byte][]string, map[[32]byte][]string, error) {
|
||||
generalAliases := map[string][]string{
|
||||
"vm/" + platformvm.ID.String(): []string{"vm/platform"},
|
||||
"vm/" + avm.ID.String(): []string{"vm/avm"},
|
||||
"vm/" + EVMID.String(): []string{"vm/evm"},
|
||||
"vm/" + spdagvm.ID.String(): []string{"vm/spdag"},
|
||||
"vm/" + spchainvm.ID.String(): []string{"vm/spchain"},
|
||||
"vm/" + timestampvm.ID.String(): []string{"vm/timestamp"},
|
||||
"bc/" + ids.Empty.String(): []string{"P", "platform", "bc/P", "bc/platform"},
|
||||
}
|
||||
chainAliases := map[[32]byte][]string{
|
||||
ids.Empty.Key(): []string{"P", "platform"},
|
||||
}
|
||||
vmAliases := map[[32]byte][]string{
|
||||
platformvm.ID.Key(): []string{"platform"},
|
||||
avm.ID.Key(): []string{"avm"},
|
||||
EVMID.Key(): []string{"evm"},
|
||||
spdagvm.ID.Key(): []string{"spdag"},
|
||||
spchainvm.ID.Key(): []string{"spchain"},
|
||||
timestampvm.ID.Key(): []string{"timestamp"},
|
||||
secp256k1fx.ID.Key(): []string{"secp256k1fx"},
|
||||
nftfx.ID.Key(): []string{"nftfx"},
|
||||
propertyfx.ID.Key(): []string{"propertyfx"},
|
||||
}
|
||||
|
||||
genesisBytes, err := Genesis(networkID)
|
||||
if err != nil {
|
||||
return nil, nil, nil, err
|
||||
}
|
||||
|
||||
genesis := &platformvm.Genesis{} // TODO let's not re-create genesis to do aliasing
|
||||
if err := platformvm.Codec.Unmarshal(genesisBytes, genesis); err != nil {
|
||||
return nil, nil, nil, err
|
||||
}
|
||||
if err := genesis.Initialize(); err != nil {
|
||||
return nil, nil, nil, err
|
||||
}
|
||||
|
||||
for _, chain := range genesis.Chains {
|
||||
switch {
|
||||
case avm.ID.Equals(chain.VMID):
|
||||
generalAliases["bc/"+chain.ID().String()] = []string{"X", "avm", "bc/X", "bc/avm"}
|
||||
chainAliases[chain.ID().Key()] = []string{"X", "avm"}
|
||||
case EVMID.Equals(chain.VMID):
|
||||
generalAliases["bc/"+chain.ID().String()] = []string{"C", "evm", "bc/C", "bc/evm"}
|
||||
chainAliases[chain.ID().Key()] = []string{"C", "evm"}
|
||||
case spdagvm.ID.Equals(chain.VMID):
|
||||
generalAliases["bc/"+chain.ID().String()] = []string{"bc/spdag"}
|
||||
chainAliases[chain.ID().Key()] = []string{"spdag"}
|
||||
case spchainvm.ID.Equals(chain.VMID):
|
||||
generalAliases["bc/"+chain.ID().String()] = []string{"bc/spchain"}
|
||||
chainAliases[chain.ID().Key()] = []string{"spchain"}
|
||||
case timestampvm.ID.Equals(chain.VMID):
|
||||
generalAliases["bc/"+chain.ID().String()] = []string{"bc/timestamp"}
|
||||
chainAliases[chain.ID().Key()] = []string{"timestamp"}
|
||||
}
|
||||
}
|
||||
return generalAliases, chainAliases, vmAliases, nil
|
||||
}
|
|
@ -0,0 +1,403 @@
|
|||
// (c) 2019-2020, Ava Labs, Inc. All rights reserved.
|
||||
// See the file LICENSE for licensing terms.
|
||||
|
||||
package genesis
|
||||
|
||||
import (
|
||||
"github.com/ava-labs/gecko/ids"
|
||||
)
|
||||
|
||||
// Note that since an AVA network has exactly one Platform Chain,
|
||||
// and the Platform Chain defines the genesis state of the network
|
||||
// (who is staking, which chains exist, etc.), defining the genesis
|
||||
// state of the Platform Chain is the same as defining the genesis
|
||||
// state of the network.
|
||||
|
||||
// Config contains the genesis addresses used to construct a genesis
|
||||
type Config struct {
|
||||
MintAddresses, FundedAddresses, StakerIDs []string
|
||||
ParsedMintAddresses, ParsedFundedAddresses, ParsedStakerIDs []ids.ShortID
|
||||
EVMBytes []byte
|
||||
}
|
||||
|
||||
func (c *Config) init() error {
|
||||
c.ParsedMintAddresses = nil
|
||||
for _, addrStr := range c.MintAddresses {
|
||||
addr, err := ids.ShortFromString(addrStr)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
c.ParsedMintAddresses = append(c.ParsedMintAddresses, addr)
|
||||
}
|
||||
c.ParsedFundedAddresses = nil
|
||||
for _, addrStr := range c.FundedAddresses {
|
||||
addr, err := ids.ShortFromString(addrStr)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
c.ParsedFundedAddresses = append(c.ParsedFundedAddresses, addr)
|
||||
}
|
||||
c.ParsedStakerIDs = nil
|
||||
for _, addrStr := range c.StakerIDs {
|
||||
addr, err := ids.ShortFromString(addrStr)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
c.ParsedStakerIDs = append(c.ParsedStakerIDs, addr)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Hard coded genesis constants
|
||||
var (
|
||||
DenaliConfig = Config{
|
||||
MintAddresses: []string{
|
||||
"95YUFjhDG892VePMzpwKF9JzewGKvGRi3",
|
||||
},
|
||||
FundedAddresses: []string{
|
||||
"9uKvvA7E35QCwLvAaohXTCfFejbf3Rv17",
|
||||
"JLrYNMYXANGj43BfWXBxMMAEenUBp1Sbn",
|
||||
"7TUTzwrU6nbZtWHjTHEpdneUvjKBxb3EM",
|
||||
"77mPUXBdQKwQpPoX6rckCZGLGGdkuG1G6",
|
||||
"4gGWdFZ4Gax1B466YKXyKRRpWLb42Afdt",
|
||||
"CKTkzAPsRxCreyiDTnjGxLmjMarxF28fi",
|
||||
"4ABm9gFHVtsNdcKSd1xsacFkGneSgzpaa",
|
||||
"DpL8PTsrjtLzv5J8LL3D2A6YcnCTqrNH9",
|
||||
"ZdhZv6oZrmXLyFDy6ovXAu6VxmbTsT2h",
|
||||
"6cesTteH62Y5mLoDBUASaBvCXuL2AthL",
|
||||
},
|
||||
StakerIDs: []string{
|
||||
"LQwRLm4cbJ7T2kxcxp4uXCU5XD8DFrE1C",
|
||||
"hArafGhY2HFTbwaaVh1CSCUCUCiJ2Vfb",
|
||||
"2m38qc95mhHXtrhjyGbe7r2NhniqHHJRB",
|
||||
"4QBwET5o8kUhvt9xArhir4d3R25CtmZho",
|
||||
"NpagUxt6KQiwPch9Sd4osv8kD1TZnkjdk",
|
||||
},
|
||||
EVMBytes: []byte{
|
||||
0x7b, 0x22, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67,
|
||||
0x22, 0x3a, 0x7b, 0x22, 0x63, 0x68, 0x61, 0x69,
|
||||
0x6e, 0x49, 0x64, 0x22, 0x3a, 0x34, 0x33, 0x31,
|
||||
0x31, 0x30, 0x2c, 0x22, 0x68, 0x6f, 0x6d, 0x65,
|
||||
0x73, 0x74, 0x65, 0x61, 0x64, 0x42, 0x6c, 0x6f,
|
||||
0x63, 0x6b, 0x22, 0x3a, 0x30, 0x2c, 0x22, 0x64,
|
||||
0x61, 0x6f, 0x46, 0x6f, 0x72, 0x6b, 0x42, 0x6c,
|
||||
0x6f, 0x63, 0x6b, 0x22, 0x3a, 0x30, 0x2c, 0x22,
|
||||
0x64, 0x61, 0x6f, 0x46, 0x6f, 0x72, 0x6b, 0x53,
|
||||
0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x22, 0x3a,
|
||||
0x74, 0x72, 0x75, 0x65, 0x2c, 0x22, 0x65, 0x69,
|
||||
0x70, 0x31, 0x35, 0x30, 0x42, 0x6c, 0x6f, 0x63,
|
||||
0x6b, 0x22, 0x3a, 0x30, 0x2c, 0x22, 0x65, 0x69,
|
||||
0x70, 0x31, 0x35, 0x30, 0x48, 0x61, 0x73, 0x68,
|
||||
0x22, 0x3a, 0x22, 0x30, 0x78, 0x32, 0x30, 0x38,
|
||||
0x36, 0x37, 0x39, 0x39, 0x61, 0x65, 0x65, 0x62,
|
||||
0x65, 0x61, 0x65, 0x31, 0x33, 0x35, 0x63, 0x32,
|
||||
0x34, 0x36, 0x63, 0x36, 0x35, 0x30, 0x32, 0x31,
|
||||
0x63, 0x38, 0x32, 0x62, 0x34, 0x65, 0x31, 0x35,
|
||||
0x61, 0x32, 0x63, 0x34, 0x35, 0x31, 0x33, 0x34,
|
||||
0x30, 0x39, 0x39, 0x33, 0x61, 0x61, 0x63, 0x66,
|
||||
0x64, 0x32, 0x37, 0x35, 0x31, 0x38, 0x38, 0x36,
|
||||
0x35, 0x31, 0x34, 0x66, 0x30, 0x22, 0x2c, 0x22,
|
||||
0x65, 0x69, 0x70, 0x31, 0x35, 0x35, 0x42, 0x6c,
|
||||
0x6f, 0x63, 0x6b, 0x22, 0x3a, 0x30, 0x2c, 0x22,
|
||||
0x65, 0x69, 0x70, 0x31, 0x35, 0x38, 0x42, 0x6c,
|
||||
0x6f, 0x63, 0x6b, 0x22, 0x3a, 0x30, 0x2c, 0x22,
|
||||
0x62, 0x79, 0x7a, 0x61, 0x6e, 0x74, 0x69, 0x75,
|
||||
0x6d, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x22, 0x3a,
|
||||
0x30, 0x2c, 0x22, 0x63, 0x6f, 0x6e, 0x73, 0x74,
|
||||
0x61, 0x6e, 0x74, 0x69, 0x6e, 0x6f, 0x70, 0x6c,
|
||||
0x65, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x22, 0x3a,
|
||||
0x30, 0x2c, 0x22, 0x70, 0x65, 0x74, 0x65, 0x72,
|
||||
0x73, 0x62, 0x75, 0x72, 0x67, 0x42, 0x6c, 0x6f,
|
||||
0x63, 0x6b, 0x22, 0x3a, 0x30, 0x7d, 0x2c, 0x22,
|
||||
0x6e, 0x6f, 0x6e, 0x63, 0x65, 0x22, 0x3a, 0x22,
|
||||
0x30, 0x78, 0x30, 0x22, 0x2c, 0x22, 0x74, 0x69,
|
||||
0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x22,
|
||||
0x3a, 0x22, 0x30, 0x78, 0x30, 0x22, 0x2c, 0x22,
|
||||
0x65, 0x78, 0x74, 0x72, 0x61, 0x44, 0x61, 0x74,
|
||||
0x61, 0x22, 0x3a, 0x22, 0x30, 0x78, 0x30, 0x30,
|
||||
0x22, 0x2c, 0x22, 0x67, 0x61, 0x73, 0x4c, 0x69,
|
||||
0x6d, 0x69, 0x74, 0x22, 0x3a, 0x22, 0x30, 0x78,
|
||||
0x35, 0x66, 0x35, 0x65, 0x31, 0x30, 0x30, 0x22,
|
||||
0x2c, 0x22, 0x64, 0x69, 0x66, 0x66, 0x69, 0x63,
|
||||
0x75, 0x6c, 0x74, 0x79, 0x22, 0x3a, 0x22, 0x30,
|
||||
0x78, 0x30, 0x22, 0x2c, 0x22, 0x6d, 0x69, 0x78,
|
||||
0x48, 0x61, 0x73, 0x68, 0x22, 0x3a, 0x22, 0x30,
|
||||
0x78, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
|
||||
0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
|
||||
0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
|
||||
0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
|
||||
0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
|
||||
0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
|
||||
0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
|
||||
0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
|
||||
0x30, 0x22, 0x2c, 0x22, 0x63, 0x6f, 0x69, 0x6e,
|
||||
0x62, 0x61, 0x73, 0x65, 0x22, 0x3a, 0x22, 0x30,
|
||||
0x78, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
|
||||
0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
|
||||
0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
|
||||
0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
|
||||
0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
|
||||
0x30, 0x22, 0x2c, 0x22, 0x61, 0x6c, 0x6c, 0x6f,
|
||||
0x63, 0x22, 0x3a, 0x7b, 0x22, 0x35, 0x37, 0x32,
|
||||
0x66, 0x34, 0x64, 0x38, 0x30, 0x66, 0x31, 0x30,
|
||||
0x66, 0x36, 0x36, 0x33, 0x62, 0x35, 0x30, 0x34,
|
||||
0x39, 0x66, 0x37, 0x38, 0x39, 0x35, 0x34, 0x36,
|
||||
0x66, 0x32, 0x35, 0x66, 0x37, 0x30, 0x62, 0x62,
|
||||
0x36, 0x32, 0x61, 0x37, 0x66, 0x22, 0x3a, 0x7b,
|
||||
0x22, 0x62, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x65,
|
||||
0x22, 0x3a, 0x22, 0x30, 0x78, 0x33, 0x33, 0x62,
|
||||
0x32, 0x65, 0x33, 0x63, 0x39, 0x66, 0x64, 0x30,
|
||||
0x38, 0x30, 0x34, 0x30, 0x30, 0x30, 0x30, 0x30,
|
||||
0x30, 0x30, 0x30, 0x30, 0x22, 0x7d, 0x7d, 0x2c,
|
||||
0x22, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x22,
|
||||
0x3a, 0x22, 0x30, 0x78, 0x30, 0x22, 0x2c, 0x22,
|
||||
0x67, 0x61, 0x73, 0x55, 0x73, 0x65, 0x64, 0x22,
|
||||
0x3a, 0x22, 0x30, 0x78, 0x30, 0x22, 0x2c, 0x22,
|
||||
0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x48, 0x61,
|
||||
0x73, 0x68, 0x22, 0x3a, 0x22, 0x30, 0x78, 0x30,
|
||||
0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
|
||||
0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
|
||||
0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
|
||||
0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
|
||||
0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
|
||||
0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
|
||||
0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
|
||||
0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x22,
|
||||
0x7d,
|
||||
},
|
||||
}
|
||||
CascadeConfig = Config{
|
||||
MintAddresses: []string{
|
||||
"95YUFjhDG892VePMzpwKF9JzewGKvGRi3",
|
||||
},
|
||||
FundedAddresses: []string{
|
||||
"9uKvvA7E35QCwLvAaohXTCfFejbf3Rv17",
|
||||
"JLrYNMYXANGj43BfWXBxMMAEenUBp1Sbn",
|
||||
"7TUTzwrU6nbZtWHjTHEpdneUvjKBxb3EM",
|
||||
"77mPUXBdQKwQpPoX6rckCZGLGGdkuG1G6",
|
||||
"4gGWdFZ4Gax1B466YKXyKRRpWLb42Afdt",
|
||||
"CKTkzAPsRxCreyiDTnjGxLmjMarxF28fi",
|
||||
"4ABm9gFHVtsNdcKSd1xsacFkGneSgzpaa",
|
||||
"DpL8PTsrjtLzv5J8LL3D2A6YcnCTqrNH9",
|
||||
"ZdhZv6oZrmXLyFDy6ovXAu6VxmbTsT2h",
|
||||
"6cesTteH62Y5mLoDBUASaBvCXuL2AthL",
|
||||
},
|
||||
StakerIDs: []string{
|
||||
"NX4zVkuiRJZYe6Nzzav7GXN3TakUet3Co",
|
||||
"CMsa8cMw4eib1Hb8GG4xiUKAq5eE1BwUX",
|
||||
"DsMP6jLhi1MkDVc3qx9xx9AAZWx8e87Jd",
|
||||
"N86eodVZja3GEyZJTo3DFUPGpxEEvjGHs",
|
||||
"EkKeGSLUbHrrtuayBtbwgWDRUiAziC3ao",
|
||||
},
|
||||
EVMBytes: []byte{
|
||||
0x7b, 0x22, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67,
|
||||
0x22, 0x3a, 0x7b, 0x22, 0x63, 0x68, 0x61, 0x69,
|
||||
0x6e, 0x49, 0x64, 0x22, 0x3a, 0x34, 0x33, 0x31,
|
||||
0x31, 0x30, 0x2c, 0x22, 0x68, 0x6f, 0x6d, 0x65,
|
||||
0x73, 0x74, 0x65, 0x61, 0x64, 0x42, 0x6c, 0x6f,
|
||||
0x63, 0x6b, 0x22, 0x3a, 0x30, 0x2c, 0x22, 0x64,
|
||||
0x61, 0x6f, 0x46, 0x6f, 0x72, 0x6b, 0x42, 0x6c,
|
||||
0x6f, 0x63, 0x6b, 0x22, 0x3a, 0x30, 0x2c, 0x22,
|
||||
0x64, 0x61, 0x6f, 0x46, 0x6f, 0x72, 0x6b, 0x53,
|
||||
0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x22, 0x3a,
|
||||
0x74, 0x72, 0x75, 0x65, 0x2c, 0x22, 0x65, 0x69,
|
||||
0x70, 0x31, 0x35, 0x30, 0x42, 0x6c, 0x6f, 0x63,
|
||||
0x6b, 0x22, 0x3a, 0x30, 0x2c, 0x22, 0x65, 0x69,
|
||||
0x70, 0x31, 0x35, 0x30, 0x48, 0x61, 0x73, 0x68,
|
||||
0x22, 0x3a, 0x22, 0x30, 0x78, 0x32, 0x30, 0x38,
|
||||
0x36, 0x37, 0x39, 0x39, 0x61, 0x65, 0x65, 0x62,
|
||||
0x65, 0x61, 0x65, 0x31, 0x33, 0x35, 0x63, 0x32,
|
||||
0x34, 0x36, 0x63, 0x36, 0x35, 0x30, 0x32, 0x31,
|
||||
0x63, 0x38, 0x32, 0x62, 0x34, 0x65, 0x31, 0x35,
|
||||
0x61, 0x32, 0x63, 0x34, 0x35, 0x31, 0x33, 0x34,
|
||||
0x30, 0x39, 0x39, 0x33, 0x61, 0x61, 0x63, 0x66,
|
||||
0x64, 0x32, 0x37, 0x35, 0x31, 0x38, 0x38, 0x36,
|
||||
0x35, 0x31, 0x34, 0x66, 0x30, 0x22, 0x2c, 0x22,
|
||||
0x65, 0x69, 0x70, 0x31, 0x35, 0x35, 0x42, 0x6c,
|
||||
0x6f, 0x63, 0x6b, 0x22, 0x3a, 0x30, 0x2c, 0x22,
|
||||
0x65, 0x69, 0x70, 0x31, 0x35, 0x38, 0x42, 0x6c,
|
||||
0x6f, 0x63, 0x6b, 0x22, 0x3a, 0x30, 0x2c, 0x22,
|
||||
0x62, 0x79, 0x7a, 0x61, 0x6e, 0x74, 0x69, 0x75,
|
||||
0x6d, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x22, 0x3a,
|
||||
0x30, 0x2c, 0x22, 0x63, 0x6f, 0x6e, 0x73, 0x74,
|
||||
0x61, 0x6e, 0x74, 0x69, 0x6e, 0x6f, 0x70, 0x6c,
|
||||
0x65, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x22, 0x3a,
|
||||
0x30, 0x2c, 0x22, 0x70, 0x65, 0x74, 0x65, 0x72,
|
||||
0x73, 0x62, 0x75, 0x72, 0x67, 0x42, 0x6c, 0x6f,
|
||||
0x63, 0x6b, 0x22, 0x3a, 0x30, 0x7d, 0x2c, 0x22,
|
||||
0x6e, 0x6f, 0x6e, 0x63, 0x65, 0x22, 0x3a, 0x22,
|
||||
0x30, 0x78, 0x30, 0x22, 0x2c, 0x22, 0x74, 0x69,
|
||||
0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x22,
|
||||
0x3a, 0x22, 0x30, 0x78, 0x30, 0x22, 0x2c, 0x22,
|
||||
0x65, 0x78, 0x74, 0x72, 0x61, 0x44, 0x61, 0x74,
|
||||
0x61, 0x22, 0x3a, 0x22, 0x30, 0x78, 0x30, 0x30,
|
||||
0x22, 0x2c, 0x22, 0x67, 0x61, 0x73, 0x4c, 0x69,
|
||||
0x6d, 0x69, 0x74, 0x22, 0x3a, 0x22, 0x30, 0x78,
|
||||
0x35, 0x66, 0x35, 0x65, 0x31, 0x30, 0x30, 0x22,
|
||||
0x2c, 0x22, 0x64, 0x69, 0x66, 0x66, 0x69, 0x63,
|
||||
0x75, 0x6c, 0x74, 0x79, 0x22, 0x3a, 0x22, 0x30,
|
||||
0x78, 0x30, 0x22, 0x2c, 0x22, 0x6d, 0x69, 0x78,
|
||||
0x48, 0x61, 0x73, 0x68, 0x22, 0x3a, 0x22, 0x30,
|
||||
0x78, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
|
||||
0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
|
||||
0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
|
||||
0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
|
||||
0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
|
||||
0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
|
||||
0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
|
||||
0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
|
||||
0x30, 0x22, 0x2c, 0x22, 0x63, 0x6f, 0x69, 0x6e,
|
||||
0x62, 0x61, 0x73, 0x65, 0x22, 0x3a, 0x22, 0x30,
|
||||
0x78, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
|
||||
0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
|
||||
0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
|
||||
0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
|
||||
0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
|
||||
0x30, 0x22, 0x2c, 0x22, 0x61, 0x6c, 0x6c, 0x6f,
|
||||
0x63, 0x22, 0x3a, 0x7b, 0x22, 0x35, 0x37, 0x32,
|
||||
0x66, 0x34, 0x64, 0x38, 0x30, 0x66, 0x31, 0x30,
|
||||
0x66, 0x36, 0x36, 0x33, 0x62, 0x35, 0x30, 0x34,
|
||||
0x39, 0x66, 0x37, 0x38, 0x39, 0x35, 0x34, 0x36,
|
||||
0x66, 0x32, 0x35, 0x66, 0x37, 0x30, 0x62, 0x62,
|
||||
0x36, 0x32, 0x61, 0x37, 0x66, 0x22, 0x3a, 0x7b,
|
||||
0x22, 0x62, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x65,
|
||||
0x22, 0x3a, 0x22, 0x30, 0x78, 0x33, 0x33, 0x62,
|
||||
0x32, 0x65, 0x33, 0x63, 0x39, 0x66, 0x64, 0x30,
|
||||
0x38, 0x30, 0x34, 0x30, 0x30, 0x30, 0x30, 0x30,
|
||||
0x30, 0x30, 0x30, 0x30, 0x22, 0x7d, 0x7d, 0x2c,
|
||||
0x22, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x22,
|
||||
0x3a, 0x22, 0x30, 0x78, 0x30, 0x22, 0x2c, 0x22,
|
||||
0x67, 0x61, 0x73, 0x55, 0x73, 0x65, 0x64, 0x22,
|
||||
0x3a, 0x22, 0x30, 0x78, 0x30, 0x22, 0x2c, 0x22,
|
||||
0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x48, 0x61,
|
||||
0x73, 0x68, 0x22, 0x3a, 0x22, 0x30, 0x78, 0x30,
|
||||
0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
|
||||
0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
|
||||
0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
|
||||
0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
|
||||
0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
|
||||
0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
|
||||
0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
|
||||
0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x22,
|
||||
0x7d,
|
||||
},
|
||||
}
|
||||
DefaultConfig = Config{
|
||||
MintAddresses: []string{},
|
||||
FundedAddresses: []string{
|
||||
// Private key: ewoqjP7PxY4yr3iLTpLisriqt94hdyDFNgchSxGGztUrTXtNN
|
||||
"6Y3kysjF9jnHnYkdS9yGAuoHyae2eNmeV",
|
||||
},
|
||||
StakerIDs: []string{
|
||||
"7Xhw2mDxuDS44j42TCB6U5579esbSt3Lg",
|
||||
"MFrZFVCXPv5iCn6M9K6XduxGTYp891xXZ",
|
||||
"NFBbbJ4qCmNaCzeW7sxErhvWqvEQMnYcN",
|
||||
"GWPcbFJZFfZreETSoWjPimr846mXEKCtu",
|
||||
"P7oB2McjBGgW2NXXWVYjV8JEDFoW9xDE5",
|
||||
},
|
||||
EVMBytes: []byte{
|
||||
0x7b, 0x22, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67,
|
||||
0x22, 0x3a, 0x7b, 0x22, 0x63, 0x68, 0x61, 0x69,
|
||||
0x6e, 0x49, 0x64, 0x22, 0x3a, 0x34, 0x33, 0x31,
|
||||
0x31, 0x30, 0x2c, 0x22, 0x68, 0x6f, 0x6d, 0x65,
|
||||
0x73, 0x74, 0x65, 0x61, 0x64, 0x42, 0x6c, 0x6f,
|
||||
0x63, 0x6b, 0x22, 0x3a, 0x30, 0x2c, 0x22, 0x64,
|
||||
0x61, 0x6f, 0x46, 0x6f, 0x72, 0x6b, 0x42, 0x6c,
|
||||
0x6f, 0x63, 0x6b, 0x22, 0x3a, 0x30, 0x2c, 0x22,
|
||||
0x64, 0x61, 0x6f, 0x46, 0x6f, 0x72, 0x6b, 0x53,
|
||||
0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x22, 0x3a,
|
||||
0x74, 0x72, 0x75, 0x65, 0x2c, 0x22, 0x65, 0x69,
|
||||
0x70, 0x31, 0x35, 0x30, 0x42, 0x6c, 0x6f, 0x63,
|
||||
0x6b, 0x22, 0x3a, 0x30, 0x2c, 0x22, 0x65, 0x69,
|
||||
0x70, 0x31, 0x35, 0x30, 0x48, 0x61, 0x73, 0x68,
|
||||
0x22, 0x3a, 0x22, 0x30, 0x78, 0x32, 0x30, 0x38,
|
||||
0x36, 0x37, 0x39, 0x39, 0x61, 0x65, 0x65, 0x62,
|
||||
0x65, 0x61, 0x65, 0x31, 0x33, 0x35, 0x63, 0x32,
|
||||
0x34, 0x36, 0x63, 0x36, 0x35, 0x30, 0x32, 0x31,
|
||||
0x63, 0x38, 0x32, 0x62, 0x34, 0x65, 0x31, 0x35,
|
||||
0x61, 0x32, 0x63, 0x34, 0x35, 0x31, 0x33, 0x34,
|
||||
0x30, 0x39, 0x39, 0x33, 0x61, 0x61, 0x63, 0x66,
|
||||
0x64, 0x32, 0x37, 0x35, 0x31, 0x38, 0x38, 0x36,
|
||||
0x35, 0x31, 0x34, 0x66, 0x30, 0x22, 0x2c, 0x22,
|
||||
0x65, 0x69, 0x70, 0x31, 0x35, 0x35, 0x42, 0x6c,
|
||||
0x6f, 0x63, 0x6b, 0x22, 0x3a, 0x30, 0x2c, 0x22,
|
||||
0x65, 0x69, 0x70, 0x31, 0x35, 0x38, 0x42, 0x6c,
|
||||
0x6f, 0x63, 0x6b, 0x22, 0x3a, 0x30, 0x2c, 0x22,
|
||||
0x62, 0x79, 0x7a, 0x61, 0x6e, 0x74, 0x69, 0x75,
|
||||
0x6d, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x22, 0x3a,
|
||||
0x30, 0x2c, 0x22, 0x63, 0x6f, 0x6e, 0x73, 0x74,
|
||||
0x61, 0x6e, 0x74, 0x69, 0x6e, 0x6f, 0x70, 0x6c,
|
||||
0x65, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x22, 0x3a,
|
||||
0x30, 0x2c, 0x22, 0x70, 0x65, 0x74, 0x65, 0x72,
|
||||
0x73, 0x62, 0x75, 0x72, 0x67, 0x42, 0x6c, 0x6f,
|
||||
0x63, 0x6b, 0x22, 0x3a, 0x30, 0x7d, 0x2c, 0x22,
|
||||
0x6e, 0x6f, 0x6e, 0x63, 0x65, 0x22, 0x3a, 0x22,
|
||||
0x30, 0x78, 0x30, 0x22, 0x2c, 0x22, 0x74, 0x69,
|
||||
0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x22,
|
||||
0x3a, 0x22, 0x30, 0x78, 0x30, 0x22, 0x2c, 0x22,
|
||||
0x65, 0x78, 0x74, 0x72, 0x61, 0x44, 0x61, 0x74,
|
||||
0x61, 0x22, 0x3a, 0x22, 0x30, 0x78, 0x30, 0x30,
|
||||
0x22, 0x2c, 0x22, 0x67, 0x61, 0x73, 0x4c, 0x69,
|
||||
0x6d, 0x69, 0x74, 0x22, 0x3a, 0x22, 0x30, 0x78,
|
||||
0x35, 0x66, 0x35, 0x65, 0x31, 0x30, 0x30, 0x22,
|
||||
0x2c, 0x22, 0x64, 0x69, 0x66, 0x66, 0x69, 0x63,
|
||||
0x75, 0x6c, 0x74, 0x79, 0x22, 0x3a, 0x22, 0x30,
|
||||
0x78, 0x30, 0x22, 0x2c, 0x22, 0x6d, 0x69, 0x78,
|
||||
0x48, 0x61, 0x73, 0x68, 0x22, 0x3a, 0x22, 0x30,
|
||||
0x78, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
|
||||
0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
|
||||
0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
|
||||
0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
|
||||
0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
|
||||
0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
|
||||
0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
|
||||
0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
|
||||
0x30, 0x22, 0x2c, 0x22, 0x63, 0x6f, 0x69, 0x6e,
|
||||
0x62, 0x61, 0x73, 0x65, 0x22, 0x3a, 0x22, 0x30,
|
||||
0x78, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
|
||||
0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
|
||||
0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
|
||||
0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
|
||||
0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
|
||||
0x30, 0x22, 0x2c, 0x22, 0x61, 0x6c, 0x6c, 0x6f,
|
||||
0x63, 0x22, 0x3a, 0x7b, 0x22, 0x37, 0x35, 0x31,
|
||||
0x61, 0x30, 0x62, 0x39, 0x36, 0x65, 0x31, 0x30,
|
||||
0x34, 0x32, 0x62, 0x65, 0x65, 0x37, 0x38, 0x39,
|
||||
0x34, 0x35, 0x32, 0x65, 0x63, 0x62, 0x32, 0x30,
|
||||
0x32, 0x35, 0x33, 0x66, 0x62, 0x61, 0x34, 0x30,
|
||||
0x64, 0x62, 0x65, 0x38, 0x35, 0x22, 0x3a, 0x7b,
|
||||
0x22, 0x62, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x65,
|
||||
0x22, 0x3a, 0x22, 0x30, 0x78, 0x33, 0x33, 0x62,
|
||||
0x32, 0x65, 0x33, 0x63, 0x39, 0x66, 0x64, 0x30,
|
||||
0x38, 0x30, 0x34, 0x30, 0x30, 0x30, 0x30, 0x30,
|
||||
0x30, 0x30, 0x30, 0x30, 0x22, 0x7d, 0x7d, 0x2c,
|
||||
0x22, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x22,
|
||||
0x3a, 0x22, 0x30, 0x78, 0x30, 0x22, 0x2c, 0x22,
|
||||
0x67, 0x61, 0x73, 0x55, 0x73, 0x65, 0x64, 0x22,
|
||||
0x3a, 0x22, 0x30, 0x78, 0x30, 0x22, 0x2c, 0x22,
|
||||
0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x48, 0x61,
|
||||
0x73, 0x68, 0x22, 0x3a, 0x22, 0x30, 0x78, 0x30,
|
||||
0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
|
||||
0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
|
||||
0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
|
||||
0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
|
||||
0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
|
||||
0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
|
||||
0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
|
||||
0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x22,
|
||||
0x7d,
|
||||
},
|
||||
}
|
||||
)
|
||||
|
||||
// GetConfig ...
|
||||
func GetConfig(networkID uint32) *Config {
|
||||
switch networkID {
|
||||
case DenaliID:
|
||||
return &DenaliConfig
|
||||
case CascadeID:
|
||||
return &CascadeConfig
|
||||
default:
|
||||
return &DefaultConfig
|
||||
}
|
||||
}
|
|
@ -3,511 +3,270 @@
|
|||
|
||||
package genesis
|
||||
|
||||
// TODO: Move this to a separate repo and leave only a byte array
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"math"
|
||||
"regexp"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/ava-labs/gecko/ids"
|
||||
"github.com/ava-labs/gecko/utils/formatting"
|
||||
"github.com/ava-labs/gecko/utils/json"
|
||||
"github.com/ava-labs/gecko/utils/units"
|
||||
"github.com/ava-labs/gecko/utils/wrappers"
|
||||
"github.com/ava-labs/gecko/vms/avm"
|
||||
"github.com/ava-labs/gecko/vms/evm"
|
||||
"github.com/ava-labs/gecko/vms/components/codec"
|
||||
"github.com/ava-labs/gecko/vms/nftfx"
|
||||
"github.com/ava-labs/gecko/vms/platformvm"
|
||||
"github.com/ava-labs/gecko/vms/propertyfx"
|
||||
"github.com/ava-labs/gecko/vms/secp256k1fx"
|
||||
"github.com/ava-labs/gecko/vms/spchainvm"
|
||||
"github.com/ava-labs/gecko/vms/spdagvm"
|
||||
"github.com/ava-labs/gecko/vms/timestampvm"
|
||||
)
|
||||
|
||||
// Note that since an AVA network has exactly one Platform Chain,
|
||||
// and the Platform Chain defines the genesis state of the network
|
||||
// (who is staking, which chains exist, etc.), defining the genesis
|
||||
// state of the Platform Chain is the same as defining the genesis
|
||||
// state of the network.
|
||||
|
||||
// Hardcoded network IDs
|
||||
const (
|
||||
MainnetID uint32 = 1
|
||||
TestnetID uint32 = 2
|
||||
BorealisID uint32 = 2
|
||||
LocalID uint32 = 12345
|
||||
|
||||
MainnetName = "mainnet"
|
||||
TestnetName = "testnet"
|
||||
BorealisName = "borealis"
|
||||
LocalName = "local"
|
||||
)
|
||||
|
||||
// ID of the EVM VM
|
||||
var (
|
||||
validNetworkName = regexp.MustCompile(`network-[0-9]+`)
|
||||
EVMID = ids.NewID([32]byte{'e', 'v', 'm'})
|
||||
)
|
||||
|
||||
// Hard coded genesis constants
|
||||
var (
|
||||
// Give special names to the mainnet and testnet
|
||||
NetworkIDToNetworkName = map[uint32]string{
|
||||
MainnetID: MainnetName,
|
||||
TestnetID: BorealisName,
|
||||
LocalID: LocalName,
|
||||
}
|
||||
NetworkNameToNetworkID = map[string]uint32{
|
||||
MainnetName: MainnetID,
|
||||
TestnetName: TestnetID,
|
||||
BorealisName: BorealisID,
|
||||
LocalName: LocalID,
|
||||
}
|
||||
Keys = []string{
|
||||
"ewoqjP7PxY4yr3iLTpLisriqt94hdyDFNgchSxGGztUrTXtNN",
|
||||
}
|
||||
Addresses = []string{
|
||||
"6Y3kysjF9jnHnYkdS9yGAuoHyae2eNmeV",
|
||||
}
|
||||
ParsedAddresses = []ids.ShortID{}
|
||||
StakerIDs = []string{
|
||||
"7Xhw2mDxuDS44j42TCB6U5579esbSt3Lg",
|
||||
"MFrZFVCXPv5iCn6M9K6XduxGTYp891xXZ",
|
||||
"NFBbbJ4qCmNaCzeW7sxErhvWqvEQMnYcN",
|
||||
"GWPcbFJZFfZreETSoWjPimr846mXEKCtu",
|
||||
"P7oB2McjBGgW2NXXWVYjV8JEDFoW9xDE5",
|
||||
}
|
||||
ParsedStakerIDs = []ids.ShortID{}
|
||||
)
|
||||
|
||||
func init() {
|
||||
for _, addrStr := range Addresses {
|
||||
addr, err := ids.ShortFromString(addrStr)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
ParsedAddresses = append(ParsedAddresses, addr)
|
||||
}
|
||||
for _, stakerIDStr := range StakerIDs {
|
||||
stakerID, err := ids.ShortFromString(stakerIDStr)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
ParsedStakerIDs = append(ParsedStakerIDs, stakerID)
|
||||
}
|
||||
}
|
||||
|
||||
// NetworkName returns a human readable name for the network with
|
||||
// ID [networkID]
|
||||
func NetworkName(networkID uint32) string {
|
||||
if name, exists := NetworkIDToNetworkName[networkID]; exists {
|
||||
return name
|
||||
}
|
||||
return fmt.Sprintf("network-%d", networkID)
|
||||
}
|
||||
|
||||
// NetworkID returns the ID of the network with name [networkName]
|
||||
func NetworkID(networkName string) (uint32, error) {
|
||||
networkName = strings.ToLower(networkName)
|
||||
if id, exists := NetworkNameToNetworkID[networkName]; exists {
|
||||
return id, nil
|
||||
}
|
||||
|
||||
if id, err := strconv.ParseUint(networkName, 10, 0); err == nil {
|
||||
if id > math.MaxUint32 {
|
||||
return 0, fmt.Errorf("NetworkID %s not in [0, 2^32)", networkName)
|
||||
}
|
||||
return uint32(id), nil
|
||||
}
|
||||
if validNetworkName.MatchString(networkName) {
|
||||
if id, err := strconv.Atoi(networkName[8:]); err == nil {
|
||||
if id > math.MaxUint32 {
|
||||
return 0, fmt.Errorf("NetworkID %s not in [0, 2^32)", networkName)
|
||||
}
|
||||
return uint32(id), nil
|
||||
}
|
||||
}
|
||||
|
||||
return 0, fmt.Errorf("Failed to parse %s as a network name", networkName)
|
||||
}
|
||||
|
||||
// Aliases returns the default aliases based on the network ID
|
||||
func Aliases(networkID uint32) (generalAliases map[string][]string, chainAliases map[[32]byte][]string, vmAliases map[[32]byte][]string) {
|
||||
generalAliases = map[string][]string{
|
||||
"vm/" + platformvm.ID.String(): []string{"vm/platform"},
|
||||
"vm/" + avm.ID.String(): []string{"vm/avm"},
|
||||
"vm/" + evm.ID.String(): []string{"vm/evm"},
|
||||
"vm/" + spdagvm.ID.String(): []string{"vm/spdag"},
|
||||
"vm/" + spchainvm.ID.String(): []string{"vm/spchain"},
|
||||
"vm/" + timestampvm.ID.String(): []string{"vm/timestamp"},
|
||||
"bc/" + ids.Empty.String(): []string{"P", "platform", "bc/P", "bc/platform"},
|
||||
}
|
||||
chainAliases = map[[32]byte][]string{
|
||||
ids.Empty.Key(): []string{"P", "platform"},
|
||||
}
|
||||
vmAliases = map[[32]byte][]string{
|
||||
platformvm.ID.Key(): []string{"platform"},
|
||||
avm.ID.Key(): []string{"avm"},
|
||||
evm.ID.Key(): []string{"evm"},
|
||||
spdagvm.ID.Key(): []string{"spdag"},
|
||||
spchainvm.ID.Key(): []string{"spchain"},
|
||||
timestampvm.ID.Key(): []string{"timestamp"},
|
||||
}
|
||||
|
||||
genesisBytes := Genesis(networkID)
|
||||
genesis := &platformvm.Genesis{} // TODO let's not re-create genesis to do aliasing
|
||||
platformvm.Codec.Unmarshal(genesisBytes, genesis) // TODO check for error
|
||||
genesis.Initialize()
|
||||
|
||||
for _, chain := range genesis.Chains {
|
||||
switch {
|
||||
case avm.ID.Equals(chain.VMID):
|
||||
generalAliases["bc/"+chain.ID().String()] = []string{"X", "avm", "bc/X", "bc/avm"}
|
||||
chainAliases[chain.ID().Key()] = []string{"X", "avm"}
|
||||
case evm.ID.Equals(chain.VMID):
|
||||
generalAliases["bc/"+chain.ID().String()] = []string{"C", "evm", "bc/C", "bc/evm"}
|
||||
chainAliases[chain.ID().Key()] = []string{"C", "evm"}
|
||||
case spdagvm.ID.Equals(chain.VMID):
|
||||
generalAliases["bc/"+chain.ID().String()] = []string{"bc/spdag"}
|
||||
chainAliases[chain.ID().Key()] = []string{"spdag"}
|
||||
case spchainvm.ID.Equals(chain.VMID):
|
||||
generalAliases["bc/"+chain.ID().String()] = []string{"bc/spchain"}
|
||||
chainAliases[chain.ID().Key()] = []string{"spchain"}
|
||||
case timestampvm.ID.Equals(chain.VMID):
|
||||
generalAliases["bc/"+chain.ID().String()] = []string{"bc/timestamp"}
|
||||
chainAliases[chain.ID().Key()] = []string{"timestamp"}
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// Genesis returns the genesis data of the Platform Chain.
|
||||
// Since the Platform Chain causes the creation of all other
|
||||
// chains, this function returns the genesis data of the entire network.
|
||||
// Since an AVA network has exactly one Platform Chain, and the Platform Chain
|
||||
// defines the genesis state of the network (who is staking, which chains exist,
|
||||
// etc.), defining the genesis state of the Platform Chain is the same as
|
||||
// defining the genesis state of the network.
|
||||
// The ID of the new network is [networkID].
|
||||
func Genesis(networkID uint32) []byte {
|
||||
if networkID != LocalID {
|
||||
panic("unknown network ID provided")
|
||||
|
||||
// FromConfig ...
|
||||
func FromConfig(networkID uint32, config *Config) ([]byte, error) {
|
||||
if err := config.init(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return []byte{
|
||||
0x00, 0x00, 0x00, 0x01, 0x3c, 0xb7, 0xd3, 0x84,
|
||||
0x2e, 0x8c, 0xee, 0x6a, 0x0e, 0xbd, 0x09, 0xf1,
|
||||
0xfe, 0x88, 0x4f, 0x68, 0x61, 0xe1, 0xb2, 0x9c,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x12, 0x30, 0x9c, 0xe5, 0x40, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00,
|
||||
0x05, 0xde, 0x31, 0xb4, 0xd8, 0xb2, 0x29, 0x91,
|
||||
0xd5, 0x1a, 0xa6, 0xaa, 0x1f, 0xc7, 0x33, 0xf2,
|
||||
0x3a, 0x85, 0x1a, 0x8c, 0x94, 0x00, 0x00, 0x12,
|
||||
0x30, 0x9c, 0xe5, 0x40, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x5d, 0xbb, 0x75, 0x80, 0x00, 0x00, 0x00,
|
||||
0x00, 0x5f, 0x9c, 0xa9, 0x00, 0x00, 0x00, 0x30,
|
||||
0x39, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x3c, 0xb7, 0xd3, 0x84, 0x2e, 0x8c, 0xee,
|
||||
0x6a, 0x0e, 0xbd, 0x09, 0xf1, 0xfe, 0x88, 0x4f,
|
||||
0x68, 0x61, 0xe1, 0xb2, 0x9c, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0xaa, 0x18,
|
||||
0xd3, 0x99, 0x1c, 0xf6, 0x37, 0xaa, 0x6c, 0x16,
|
||||
0x2f, 0x5e, 0x95, 0xcf, 0x16, 0x3f, 0x69, 0xcd,
|
||||
0x82, 0x91, 0x00, 0x00, 0x12, 0x30, 0x9c, 0xe5,
|
||||
0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5d, 0xbb,
|
||||
0x75, 0x80, 0x00, 0x00, 0x00, 0x00, 0x5f, 0x9c,
|
||||
0xa9, 0x00, 0x00, 0x00, 0x30, 0x39, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0xb7,
|
||||
0xd3, 0x84, 0x2e, 0x8c, 0xee, 0x6a, 0x0e, 0xbd,
|
||||
0x09, 0xf1, 0xfe, 0x88, 0x4f, 0x68, 0x61, 0xe1,
|
||||
0xb2, 0x9c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x05, 0xe9, 0x09, 0x4f, 0x73, 0x69,
|
||||
0x80, 0x02, 0xfd, 0x52, 0xc9, 0x08, 0x19, 0xb4,
|
||||
0x57, 0xb9, 0xfb, 0xc8, 0x66, 0xab, 0x80, 0x00,
|
||||
0x00, 0x12, 0x30, 0x9c, 0xe5, 0x40, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x5d, 0xbb, 0x75, 0x80, 0x00,
|
||||
0x00, 0x00, 0x00, 0x5f, 0x9c, 0xa9, 0x00, 0x00,
|
||||
0x00, 0x30, 0x39, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x3c, 0xb7, 0xd3, 0x84, 0x2e,
|
||||
0x8c, 0xee, 0x6a, 0x0e, 0xbd, 0x09, 0xf1, 0xfe,
|
||||
0x88, 0x4f, 0x68, 0x61, 0xe1, 0xb2, 0x9c, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05,
|
||||
0x47, 0x9f, 0x66, 0xc8, 0xbe, 0x89, 0x58, 0x30,
|
||||
0x54, 0x7e, 0x70, 0xb4, 0xb2, 0x98, 0xca, 0xfd,
|
||||
0x43, 0x3d, 0xba, 0x6e, 0x00, 0x00, 0x12, 0x30,
|
||||
0x9c, 0xe5, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x5d, 0xbb, 0x75, 0x80, 0x00, 0x00, 0x00, 0x00,
|
||||
0x5f, 0x9c, 0xa9, 0x00, 0x00, 0x00, 0x30, 0x39,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x3c, 0xb7, 0xd3, 0x84, 0x2e, 0x8c, 0xee, 0x6a,
|
||||
0x0e, 0xbd, 0x09, 0xf1, 0xfe, 0x88, 0x4f, 0x68,
|
||||
0x61, 0xe1, 0xb2, 0x9c, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x05, 0xf2, 0x9b, 0xce,
|
||||
0x5f, 0x34, 0xa7, 0x43, 0x01, 0xeb, 0x0d, 0xe7,
|
||||
0x16, 0xd5, 0x19, 0x4e, 0x4a, 0x4a, 0xea, 0x5d,
|
||||
0x7a, 0x00, 0x00, 0x12, 0x30, 0x9c, 0xe5, 0x40,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x5d, 0xbb, 0x75,
|
||||
0x80, 0x00, 0x00, 0x00, 0x00, 0x5f, 0x9c, 0xa9,
|
||||
0x00, 0x00, 0x00, 0x30, 0x39, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0xb7, 0xd3,
|
||||
0x84, 0x2e, 0x8c, 0xee, 0x6a, 0x0e, 0xbd, 0x09,
|
||||
0xf1, 0xfe, 0x88, 0x4f, 0x68, 0x61, 0xe1, 0xb2,
|
||||
0x9c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x05, 0x00, 0x00, 0x30, 0x39, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03,
|
||||
0x41, 0x56, 0x4d, 0x61, 0x76, 0x6d, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x73,
|
||||
0x65, 0x63, 0x70, 0x32, 0x35, 0x36, 0x6b, 0x31,
|
||||
0x66, 0x78, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x7c, 0x00, 0x00, 0x00, 0x01, 0x00,
|
||||
0x03, 0x41, 0x56, 0x41, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x03, 0x41, 0x56, 0x41, 0x00, 0x03, 0x41,
|
||||
0x56, 0x41, 0x09, 0x00, 0x00, 0x00, 0x01, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00,
|
||||
0x00, 0x00, 0x04, 0x00, 0x9f, 0xdf, 0x42, 0xf6,
|
||||
0xe4, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00,
|
||||
0x00, 0x00, 0x01, 0x3c, 0xb7, 0xd3, 0x84, 0x2e,
|
||||
0x8c, 0xee, 0x6a, 0x0e, 0xbd, 0x09, 0xf1, 0xfe,
|
||||
0x88, 0x4f, 0x68, 0x61, 0xe1, 0xb2, 0x9c, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x30, 0x39, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x41, 0x74,
|
||||
0x68, 0x65, 0x72, 0x65, 0x75, 0x6d, 0x65, 0x76,
|
||||
0x6d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x02, 0xc9, 0x7b, 0x22,
|
||||
0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x22, 0x3a,
|
||||
0x7b, 0x22, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x49,
|
||||
0x64, 0x22, 0x3a, 0x34, 0x33, 0x31, 0x31, 0x30,
|
||||
0x2c, 0x22, 0x68, 0x6f, 0x6d, 0x65, 0x73, 0x74,
|
||||
0x65, 0x61, 0x64, 0x42, 0x6c, 0x6f, 0x63, 0x6b,
|
||||
0x22, 0x3a, 0x30, 0x2c, 0x22, 0x64, 0x61, 0x6f,
|
||||
0x46, 0x6f, 0x72, 0x6b, 0x42, 0x6c, 0x6f, 0x63,
|
||||
0x6b, 0x22, 0x3a, 0x30, 0x2c, 0x22, 0x64, 0x61,
|
||||
0x6f, 0x46, 0x6f, 0x72, 0x6b, 0x53, 0x75, 0x70,
|
||||
0x70, 0x6f, 0x72, 0x74, 0x22, 0x3a, 0x74, 0x72,
|
||||
0x75, 0x65, 0x2c, 0x22, 0x65, 0x69, 0x70, 0x31,
|
||||
0x35, 0x30, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x22,
|
||||
0x3a, 0x30, 0x2c, 0x22, 0x65, 0x69, 0x70, 0x31,
|
||||
0x35, 0x30, 0x48, 0x61, 0x73, 0x68, 0x22, 0x3a,
|
||||
0x22, 0x30, 0x78, 0x32, 0x30, 0x38, 0x36, 0x37,
|
||||
0x39, 0x39, 0x61, 0x65, 0x65, 0x62, 0x65, 0x61,
|
||||
0x65, 0x31, 0x33, 0x35, 0x63, 0x32, 0x34, 0x36,
|
||||
0x63, 0x36, 0x35, 0x30, 0x32, 0x31, 0x63, 0x38,
|
||||
0x32, 0x62, 0x34, 0x65, 0x31, 0x35, 0x61, 0x32,
|
||||
0x63, 0x34, 0x35, 0x31, 0x33, 0x34, 0x30, 0x39,
|
||||
0x39, 0x33, 0x61, 0x61, 0x63, 0x66, 0x64, 0x32,
|
||||
0x37, 0x35, 0x31, 0x38, 0x38, 0x36, 0x35, 0x31,
|
||||
0x34, 0x66, 0x30, 0x22, 0x2c, 0x22, 0x65, 0x69,
|
||||
0x70, 0x31, 0x35, 0x35, 0x42, 0x6c, 0x6f, 0x63,
|
||||
0x6b, 0x22, 0x3a, 0x30, 0x2c, 0x22, 0x65, 0x69,
|
||||
0x70, 0x31, 0x35, 0x38, 0x42, 0x6c, 0x6f, 0x63,
|
||||
0x6b, 0x22, 0x3a, 0x30, 0x2c, 0x22, 0x62, 0x79,
|
||||
0x7a, 0x61, 0x6e, 0x74, 0x69, 0x75, 0x6d, 0x42,
|
||||
0x6c, 0x6f, 0x63, 0x6b, 0x22, 0x3a, 0x30, 0x2c,
|
||||
0x22, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x61, 0x6e,
|
||||
0x74, 0x69, 0x6e, 0x6f, 0x70, 0x6c, 0x65, 0x42,
|
||||
0x6c, 0x6f, 0x63, 0x6b, 0x22, 0x3a, 0x30, 0x2c,
|
||||
0x22, 0x70, 0x65, 0x74, 0x65, 0x72, 0x73, 0x62,
|
||||
0x75, 0x72, 0x67, 0x42, 0x6c, 0x6f, 0x63, 0x6b,
|
||||
0x22, 0x3a, 0x30, 0x7d, 0x2c, 0x22, 0x6e, 0x6f,
|
||||
0x6e, 0x63, 0x65, 0x22, 0x3a, 0x22, 0x30, 0x78,
|
||||
0x30, 0x22, 0x2c, 0x22, 0x74, 0x69, 0x6d, 0x65,
|
||||
0x73, 0x74, 0x61, 0x6d, 0x70, 0x22, 0x3a, 0x22,
|
||||
0x30, 0x78, 0x30, 0x22, 0x2c, 0x22, 0x65, 0x78,
|
||||
0x74, 0x72, 0x61, 0x44, 0x61, 0x74, 0x61, 0x22,
|
||||
0x3a, 0x22, 0x30, 0x78, 0x30, 0x30, 0x22, 0x2c,
|
||||
0x22, 0x67, 0x61, 0x73, 0x4c, 0x69, 0x6d, 0x69,
|
||||
0x74, 0x22, 0x3a, 0x22, 0x30, 0x78, 0x35, 0x66,
|
||||
0x35, 0x65, 0x31, 0x30, 0x30, 0x22, 0x2c, 0x22,
|
||||
0x64, 0x69, 0x66, 0x66, 0x69, 0x63, 0x75, 0x6c,
|
||||
0x74, 0x79, 0x22, 0x3a, 0x22, 0x30, 0x78, 0x30,
|
||||
0x22, 0x2c, 0x22, 0x6d, 0x69, 0x78, 0x48, 0x61,
|
||||
0x73, 0x68, 0x22, 0x3a, 0x22, 0x30, 0x78, 0x30,
|
||||
0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
|
||||
0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
|
||||
0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
|
||||
0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
|
||||
0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
|
||||
0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
|
||||
0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
|
||||
0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x22,
|
||||
0x2c, 0x22, 0x63, 0x6f, 0x69, 0x6e, 0x62, 0x61,
|
||||
0x73, 0x65, 0x22, 0x3a, 0x22, 0x30, 0x78, 0x30,
|
||||
0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
|
||||
0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
|
||||
0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
|
||||
0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
|
||||
0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x22,
|
||||
0x2c, 0x22, 0x61, 0x6c, 0x6c, 0x6f, 0x63, 0x22,
|
||||
0x3a, 0x7b, 0x22, 0x37, 0x35, 0x31, 0x61, 0x30,
|
||||
0x62, 0x39, 0x36, 0x65, 0x31, 0x30, 0x34, 0x32,
|
||||
0x62, 0x65, 0x65, 0x37, 0x38, 0x39, 0x34, 0x35,
|
||||
0x32, 0x65, 0x63, 0x62, 0x32, 0x30, 0x32, 0x35,
|
||||
0x33, 0x66, 0x62, 0x61, 0x34, 0x30, 0x64, 0x62,
|
||||
0x65, 0x38, 0x35, 0x22, 0x3a, 0x7b, 0x22, 0x62,
|
||||
0x61, 0x6c, 0x61, 0x6e, 0x63, 0x65, 0x22, 0x3a,
|
||||
0x22, 0x30, 0x78, 0x33, 0x33, 0x62, 0x32, 0x65,
|
||||
0x33, 0x63, 0x39, 0x66, 0x64, 0x30, 0x38, 0x30,
|
||||
0x34, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
|
||||
0x30, 0x30, 0x22, 0x7d, 0x7d, 0x2c, 0x22, 0x6e,
|
||||
0x75, 0x6d, 0x62, 0x65, 0x72, 0x22, 0x3a, 0x22,
|
||||
0x30, 0x78, 0x30, 0x22, 0x2c, 0x22, 0x67, 0x61,
|
||||
0x73, 0x55, 0x73, 0x65, 0x64, 0x22, 0x3a, 0x22,
|
||||
0x30, 0x78, 0x30, 0x22, 0x2c, 0x22, 0x70, 0x61,
|
||||
0x72, 0x65, 0x6e, 0x74, 0x48, 0x61, 0x73, 0x68,
|
||||
0x22, 0x3a, 0x22, 0x30, 0x78, 0x30, 0x30, 0x30,
|
||||
0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
|
||||
0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
|
||||
0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
|
||||
0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
|
||||
0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
|
||||
0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
|
||||
0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
|
||||
0x30, 0x30, 0x30, 0x30, 0x30, 0x22, 0x7d, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x30, 0x39, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x13, 0x53, 0x69,
|
||||
0x6d, 0x70, 0x6c, 0x65, 0x20, 0x44, 0x41, 0x47,
|
||||
0x20, 0x50, 0x61, 0x79, 0x6d, 0x65, 0x6e, 0x74,
|
||||
0x73, 0x73, 0x70, 0x64, 0x61, 0x67, 0x76, 0x6d,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x60, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x12, 0x30, 0x9c, 0xe5, 0x40,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
|
||||
0x01, 0x3c, 0xb7, 0xd3, 0x84, 0x2e, 0x8c, 0xee,
|
||||
0x6a, 0x0e, 0xbd, 0x09, 0xf1, 0xfe, 0x88, 0x4f,
|
||||
0x68, 0x61, 0xe1, 0xb2, 0x9c, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x30, 0x39, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15,
|
||||
0x53, 0x69, 0x6d, 0x70, 0x6c, 0x65, 0x20, 0x43,
|
||||
0x68, 0x61, 0x69, 0x6e, 0x20, 0x50, 0x61, 0x79,
|
||||
0x6d, 0x65, 0x6e, 0x74, 0x73, 0x73, 0x70, 0x63,
|
||||
0x68, 0x61, 0x69, 0x6e, 0x76, 0x6d, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00,
|
||||
0x01, 0x3c, 0xb7, 0xd3, 0x84, 0x2e, 0x8c, 0xee,
|
||||
0x6a, 0x0e, 0xbd, 0x09, 0xf1, 0xfe, 0x88, 0x4f,
|
||||
0x68, 0x61, 0xe1, 0xb2, 0x9c, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12,
|
||||
0x30, 0x9c, 0xe5, 0x40, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x30, 0x39, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x17, 0x53, 0x69, 0x6d, 0x70,
|
||||
0x6c, 0x65, 0x20, 0x54, 0x69, 0x6d, 0x65, 0x73,
|
||||
0x74, 0x61, 0x6d, 0x70, 0x20, 0x53, 0x65, 0x72,
|
||||
0x76, 0x65, 0x72, 0x74, 0x69, 0x6d, 0x65, 0x73,
|
||||
0x74, 0x61, 0x6d, 0x70, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x5d, 0xbb, 0x75, 0x80,
|
||||
}
|
||||
}
|
||||
// Specify the genesis state of the AVM
|
||||
avmArgs := avm.BuildGenesisArgs{}
|
||||
{
|
||||
ava := avm.AssetDefinition{
|
||||
Name: "AVA",
|
||||
Symbol: "AVA",
|
||||
Denomination: 9,
|
||||
InitialState: map[string][]interface{}{},
|
||||
}
|
||||
|
||||
// VMGenesis ...
|
||||
func VMGenesis(networkID uint32, vmID ids.ID) *platformvm.CreateChainTx {
|
||||
genesisBytes := Genesis(networkID)
|
||||
genesis := platformvm.Genesis{}
|
||||
platformvm.Codec.Unmarshal(genesisBytes, &genesis)
|
||||
for _, chain := range genesis.Chains {
|
||||
if chain.VMID.Equals(vmID) {
|
||||
return chain
|
||||
if len(config.MintAddresses) > 0 {
|
||||
ava.InitialState["variableCap"] = []interface{}{avm.Owners{
|
||||
Threshold: 1,
|
||||
Minters: config.MintAddresses,
|
||||
}}
|
||||
}
|
||||
for _, addr := range config.FundedAddresses {
|
||||
ava.InitialState["fixedCap"] = append(ava.InitialState["fixedCap"], avm.Holder{
|
||||
Amount: json.Uint64(45 * units.MegaAva),
|
||||
Address: addr,
|
||||
})
|
||||
}
|
||||
|
||||
avmArgs.GenesisData = map[string]avm.AssetDefinition{
|
||||
// The AVM starts out with one asset, $AVA
|
||||
"AVA": ava,
|
||||
}
|
||||
}
|
||||
return nil
|
||||
avmReply := avm.BuildGenesisReply{}
|
||||
|
||||
avmSS := avm.StaticService{}
|
||||
err := avmSS.BuildGenesis(nil, &avmArgs, &avmReply)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Specify the genesis state of the simple payments DAG
|
||||
spdagvmArgs := spdagvm.BuildGenesisArgs{}
|
||||
for _, addr := range config.ParsedFundedAddresses {
|
||||
spdagvmArgs.Outputs = append(spdagvmArgs.Outputs,
|
||||
spdagvm.APIOutput{
|
||||
Amount: json.Uint64(20 * units.KiloAva),
|
||||
Threshold: 1,
|
||||
Addresses: []ids.ShortID{addr},
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
spdagvmReply := spdagvm.BuildGenesisReply{}
|
||||
spdagvmSS := spdagvm.StaticService{}
|
||||
if err := spdagvmSS.BuildGenesis(nil, &spdagvmArgs, &spdagvmReply); err != nil {
|
||||
return nil, fmt.Errorf("problem creating simple payments DAG: %w", err)
|
||||
}
|
||||
|
||||
// Specify the genesis state of the simple payments chain
|
||||
spchainvmArgs := spchainvm.BuildGenesisArgs{}
|
||||
for _, addr := range config.ParsedFundedAddresses {
|
||||
spchainvmArgs.Accounts = append(spchainvmArgs.Accounts,
|
||||
spchainvm.APIAccount{
|
||||
Address: addr,
|
||||
Balance: json.Uint64(20 * units.KiloAva),
|
||||
},
|
||||
)
|
||||
}
|
||||
spchainvmReply := spchainvm.BuildGenesisReply{}
|
||||
|
||||
spchainvmSS := spchainvm.StaticService{}
|
||||
if err := spchainvmSS.BuildGenesis(nil, &spchainvmArgs, &spchainvmReply); err != nil {
|
||||
return nil, fmt.Errorf("problem creating simple payments chain: %w", err)
|
||||
}
|
||||
|
||||
// Specify the initial state of the Platform Chain
|
||||
platformvmArgs := platformvm.BuildGenesisArgs{
|
||||
NetworkID: json.Uint32(networkID),
|
||||
}
|
||||
for _, addr := range config.ParsedFundedAddresses {
|
||||
platformvmArgs.Accounts = append(platformvmArgs.Accounts,
|
||||
platformvm.APIAccount{
|
||||
Address: addr,
|
||||
Balance: json.Uint64(20 * units.KiloAva),
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
genesisTime := time.Date(
|
||||
/*year=*/ 2019,
|
||||
/*month=*/ time.November,
|
||||
/*day=*/ 1,
|
||||
/*hour=*/ 0,
|
||||
/*minute=*/ 0,
|
||||
/*second=*/ 0,
|
||||
/*nano-second=*/ 0,
|
||||
/*location=*/ time.UTC,
|
||||
)
|
||||
stakingDuration := 365 * 24 * time.Hour // ~ 1 year
|
||||
endStakingTime := genesisTime.Add(stakingDuration)
|
||||
|
||||
for i, validatorID := range config.ParsedStakerIDs {
|
||||
weight := json.Uint64(20 * units.KiloAva)
|
||||
platformvmArgs.Validators = append(platformvmArgs.Validators,
|
||||
platformvm.APIDefaultSubnetValidator{
|
||||
APIValidator: platformvm.APIValidator{
|
||||
StartTime: json.Uint64(genesisTime.Unix()),
|
||||
EndTime: json.Uint64(endStakingTime.Unix()),
|
||||
Weight: &weight,
|
||||
ID: validatorID,
|
||||
},
|
||||
Destination: config.ParsedFundedAddresses[i%len(config.ParsedFundedAddresses)],
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
// Specify the chains that exist upon this network's creation
|
||||
platformvmArgs.Chains = []platformvm.APIChain{
|
||||
platformvm.APIChain{
|
||||
GenesisData: avmReply.Bytes,
|
||||
SubnetID: platformvm.DefaultSubnetID,
|
||||
VMID: avm.ID,
|
||||
FxIDs: []ids.ID{
|
||||
secp256k1fx.ID,
|
||||
nftfx.ID,
|
||||
propertyfx.ID,
|
||||
},
|
||||
Name: "X-Chain",
|
||||
},
|
||||
platformvm.APIChain{
|
||||
GenesisData: formatting.CB58{Bytes: config.EVMBytes},
|
||||
SubnetID: platformvm.DefaultSubnetID,
|
||||
VMID: EVMID,
|
||||
Name: "C-Chain",
|
||||
},
|
||||
platformvm.APIChain{
|
||||
GenesisData: spdagvmReply.Bytes,
|
||||
SubnetID: platformvm.DefaultSubnetID,
|
||||
VMID: spdagvm.ID,
|
||||
Name: "Simple DAG Payments",
|
||||
},
|
||||
platformvm.APIChain{
|
||||
GenesisData: spchainvmReply.Bytes,
|
||||
SubnetID: platformvm.DefaultSubnetID,
|
||||
VMID: spchainvm.ID,
|
||||
Name: "Simple Chain Payments",
|
||||
},
|
||||
platformvm.APIChain{
|
||||
GenesisData: formatting.CB58{Bytes: []byte{}}, // There is no genesis data
|
||||
SubnetID: platformvm.DefaultSubnetID,
|
||||
VMID: timestampvm.ID,
|
||||
Name: "Simple Timestamp Server",
|
||||
},
|
||||
}
|
||||
|
||||
platformvmArgs.Time = json.Uint64(genesisTime.Unix())
|
||||
platformvmReply := platformvm.BuildGenesisReply{}
|
||||
|
||||
platformvmSS := platformvm.StaticService{}
|
||||
if err := platformvmSS.BuildGenesis(nil, &platformvmArgs, &platformvmReply); err != nil {
|
||||
return nil, fmt.Errorf("problem while building platform chain's genesis state: %w", err)
|
||||
}
|
||||
|
||||
return platformvmReply.Bytes.Bytes, nil
|
||||
}
|
||||
|
||||
// Genesis ...
|
||||
func Genesis(networkID uint32) ([]byte, error) { return FromConfig(networkID, GetConfig(networkID)) }
|
||||
|
||||
// VMGenesis ...
|
||||
func VMGenesis(networkID uint32, vmID ids.ID) (*platformvm.CreateChainTx, error) {
|
||||
genesisBytes, err := Genesis(networkID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
genesis := platformvm.Genesis{}
|
||||
platformvm.Codec.Unmarshal(genesisBytes, &genesis)
|
||||
if err := genesis.Initialize(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
for _, chain := range genesis.Chains {
|
||||
if chain.VMID.Equals(vmID) {
|
||||
return chain, nil
|
||||
}
|
||||
}
|
||||
return nil, fmt.Errorf("couldn't find subnet with VM ID %s", vmID)
|
||||
}
|
||||
|
||||
// AVAAssetID ...
|
||||
func AVAAssetID(networkID uint32) (ids.ID, error) {
|
||||
createAVM, err := VMGenesis(networkID, avm.ID)
|
||||
if err != nil {
|
||||
return ids.ID{}, err
|
||||
}
|
||||
|
||||
c := codec.NewDefault()
|
||||
errs := wrappers.Errs{}
|
||||
errs.Add(
|
||||
c.RegisterType(&avm.BaseTx{}),
|
||||
c.RegisterType(&avm.CreateAssetTx{}),
|
||||
c.RegisterType(&avm.OperationTx{}),
|
||||
c.RegisterType(&avm.ImportTx{}),
|
||||
c.RegisterType(&avm.ExportTx{}),
|
||||
c.RegisterType(&secp256k1fx.TransferInput{}),
|
||||
c.RegisterType(&secp256k1fx.MintOutput{}),
|
||||
c.RegisterType(&secp256k1fx.TransferOutput{}),
|
||||
c.RegisterType(&secp256k1fx.MintOperation{}),
|
||||
c.RegisterType(&secp256k1fx.Credential{}),
|
||||
)
|
||||
if errs.Errored() {
|
||||
return ids.ID{}, errs.Err
|
||||
}
|
||||
|
||||
genesis := avm.Genesis{}
|
||||
if err := c.Unmarshal(createAVM.GenesisData, &genesis); err != nil {
|
||||
return ids.ID{}, err
|
||||
}
|
||||
|
||||
if len(genesis.Txs) == 0 {
|
||||
return ids.ID{}, errors.New("genesis creates no transactions")
|
||||
}
|
||||
genesisTx := genesis.Txs[0]
|
||||
|
||||
tx := avm.Tx{UnsignedTx: &genesisTx.CreateAssetTx}
|
||||
txBytes, err := c.Marshal(&tx)
|
||||
if err != nil {
|
||||
return ids.ID{}, err
|
||||
}
|
||||
tx.Initialize(txBytes)
|
||||
|
||||
return tx.ID(), nil
|
||||
}
|
||||
|
|
|
@ -6,8 +6,8 @@ package genesis
|
|||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/ava-labs/gecko/ids"
|
||||
"github.com/ava-labs/gecko/vms/avm"
|
||||
"github.com/ava-labs/gecko/vms/evm"
|
||||
"github.com/ava-labs/gecko/vms/platformvm"
|
||||
"github.com/ava-labs/gecko/vms/spchainvm"
|
||||
"github.com/ava-labs/gecko/vms/spdagvm"
|
||||
|
@ -17,11 +17,14 @@ func TestNetworkName(t *testing.T) {
|
|||
if name := NetworkName(MainnetID); name != MainnetName {
|
||||
t.Fatalf("NetworkID was incorrectly named. Result: %s ; Expected: %s", name, MainnetName)
|
||||
}
|
||||
if name := NetworkName(TestnetID); name != BorealisName {
|
||||
t.Fatalf("NetworkID was incorrectly named. Result: %s ; Expected: %s", name, BorealisName)
|
||||
if name := NetworkName(CascadeID); name != CascadeName {
|
||||
t.Fatalf("NetworkID was incorrectly named. Result: %s ; Expected: %s", name, CascadeName)
|
||||
}
|
||||
if name := NetworkName(BorealisID); name != BorealisName {
|
||||
t.Fatalf("NetworkID was incorrectly named. Result: %s ; Expected: %s", name, BorealisName)
|
||||
if name := NetworkName(DenaliID); name != DenaliName {
|
||||
t.Fatalf("NetworkID was incorrectly named. Result: %s ; Expected: %s", name, DenaliName)
|
||||
}
|
||||
if name := NetworkName(TestnetID); name != DenaliName {
|
||||
t.Fatalf("NetworkID was incorrectly named. Result: %s ; Expected: %s", name, DenaliName)
|
||||
}
|
||||
if name := NetworkName(4294967295); name != "network-4294967295" {
|
||||
t.Fatalf("NetworkID was incorrectly named. Result: %s ; Expected: %s", name, "network-4294967295")
|
||||
|
@ -37,6 +40,38 @@ func TestNetworkID(t *testing.T) {
|
|||
t.Fatalf("Returned wrong network. Expected: %d ; Returned %d", MainnetID, id)
|
||||
}
|
||||
|
||||
id, err = NetworkID(CascadeName)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if id != CascadeID {
|
||||
t.Fatalf("Returned wrong network. Expected: %d ; Returned %d", CascadeID, id)
|
||||
}
|
||||
|
||||
id, err = NetworkID("cAsCaDe")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if id != CascadeID {
|
||||
t.Fatalf("Returned wrong network. Expected: %d ; Returned %d", CascadeID, id)
|
||||
}
|
||||
|
||||
id, err = NetworkID(DenaliName)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if id != DenaliID {
|
||||
t.Fatalf("Returned wrong network. Expected: %d ; Returned %d", DenaliID, id)
|
||||
}
|
||||
|
||||
id, err = NetworkID("dEnAlI")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if id != DenaliID {
|
||||
t.Fatalf("Returned wrong network. Expected: %d ; Returned %d", DenaliID, id)
|
||||
}
|
||||
|
||||
id, err = NetworkID(TestnetName)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
|
@ -45,22 +80,6 @@ func TestNetworkID(t *testing.T) {
|
|||
t.Fatalf("Returned wrong network. Expected: %d ; Returned %d", TestnetID, id)
|
||||
}
|
||||
|
||||
id, err = NetworkID(BorealisName)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if id != TestnetID {
|
||||
t.Fatalf("Returned wrong network. Expected: %d ; Returned %d", TestnetID, id)
|
||||
}
|
||||
|
||||
id, err = NetworkID("bOrEaLiS")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if id != TestnetID {
|
||||
t.Fatalf("Returned wrong network. Expected: %d ; Returned %d", TestnetID, id)
|
||||
}
|
||||
|
||||
id, err = NetworkID("network-4294967295")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
|
@ -91,12 +110,12 @@ func TestNetworkID(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestAliases(t *testing.T) {
|
||||
generalAliases, _, _ := Aliases(LocalID)
|
||||
generalAliases, _, _, _ := Aliases(LocalID)
|
||||
if _, exists := generalAliases["vm/"+platformvm.ID.String()]; !exists {
|
||||
t.Fatalf("Should have a custom alias from the vm")
|
||||
} else if _, exists := generalAliases["vm/"+avm.ID.String()]; !exists {
|
||||
t.Fatalf("Should have a custom alias from the vm")
|
||||
} else if _, exists := generalAliases["vm/"+evm.ID.String()]; !exists {
|
||||
} else if _, exists := generalAliases["vm/"+EVMID.String()]; !exists {
|
||||
t.Fatalf("Should have a custom alias from the vm")
|
||||
} else if _, exists := generalAliases["vm/"+spdagvm.ID.String()]; !exists {
|
||||
t.Fatalf("Should have a custom alias from the vm")
|
||||
|
@ -106,9 +125,84 @@ func TestAliases(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestGenesis(t *testing.T) {
|
||||
genesisBytes := Genesis(LocalID)
|
||||
genesisBytes, err := Genesis(LocalID)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
genesis := platformvm.Genesis{}
|
||||
if err := platformvm.Codec.Unmarshal(genesisBytes, &genesis); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestVMGenesis(t *testing.T) {
|
||||
tests := []struct {
|
||||
networkID uint32
|
||||
vmID ids.ID
|
||||
expectedID string
|
||||
}{
|
||||
{
|
||||
networkID: CascadeID,
|
||||
vmID: avm.ID,
|
||||
expectedID: "4ktRjsAKxgMr2aEzv9SWmrU7Xk5FniHUrVCX4P1TZSfTLZWFM",
|
||||
},
|
||||
{
|
||||
networkID: LocalID,
|
||||
vmID: avm.ID,
|
||||
expectedID: "4R5p2RXDGLqaifZE4hHWH9owe34pfoBULn1DrQTWivjg8o4aH",
|
||||
},
|
||||
{
|
||||
networkID: CascadeID,
|
||||
vmID: EVMID,
|
||||
expectedID: "2mUYSXfLrDtigwbzj1LxKVsHwELghc5sisoXrzJwLqAAQHF4i",
|
||||
},
|
||||
{
|
||||
networkID: LocalID,
|
||||
vmID: EVMID,
|
||||
expectedID: "tZGm6RCkeGpVETUTp11DW3UYFZmm69zfqxchpHrSF7wgy8rmw",
|
||||
},
|
||||
}
|
||||
|
||||
for _, test := range tests {
|
||||
genesisTx, err := VMGenesis(test.networkID, test.vmID)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if result := genesisTx.ID().String(); test.expectedID != result {
|
||||
t.Fatalf("%s genesisID with networkID %d was expected to be %s but was %s",
|
||||
test.vmID,
|
||||
test.networkID,
|
||||
test.expectedID,
|
||||
result)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestAVAAssetID(t *testing.T) {
|
||||
tests := []struct {
|
||||
networkID uint32
|
||||
expectedID string
|
||||
}{
|
||||
{
|
||||
networkID: CascadeID,
|
||||
expectedID: "21d7KVtPrubc5fHr6CGNcgbUb4seUjmZKr35ZX7BZb5iP8pXWA",
|
||||
},
|
||||
{
|
||||
networkID: LocalID,
|
||||
expectedID: "n8XH5JY1EX5VYqDeAhB4Zd4GKxi9UNQy6oPpMsCAj1Q6xkiiL",
|
||||
},
|
||||
}
|
||||
|
||||
for _, test := range tests {
|
||||
avaID, err := AVAAssetID(test.networkID)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if result := avaID.String(); test.expectedID != result {
|
||||
t.Fatalf("AVA assetID with networkID %d was expected to be %s but was %s",
|
||||
test.networkID,
|
||||
test.expectedID,
|
||||
result)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,81 @@
|
|||
// (c) 2019-2020, Ava Labs, Inc. All rights reserved.
|
||||
// See the file LICENSE for licensing terms.
|
||||
|
||||
package genesis
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"math"
|
||||
"regexp"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// Hardcoded network IDs
|
||||
var (
|
||||
MainnetID uint32 = 1
|
||||
CascadeID uint32 = 2
|
||||
DenaliID uint32 = 3
|
||||
|
||||
TestnetID uint32 = 3
|
||||
LocalID uint32 = 12345
|
||||
|
||||
MainnetName = "mainnet"
|
||||
CascadeName = "cascade"
|
||||
DenaliName = "denali"
|
||||
|
||||
TestnetName = "testnet"
|
||||
LocalName = "local"
|
||||
|
||||
NetworkIDToNetworkName = map[uint32]string{
|
||||
MainnetID: MainnetName,
|
||||
CascadeID: CascadeName,
|
||||
DenaliID: DenaliName,
|
||||
|
||||
LocalID: LocalName,
|
||||
}
|
||||
NetworkNameToNetworkID = map[string]uint32{
|
||||
MainnetName: MainnetID,
|
||||
CascadeName: CascadeID,
|
||||
DenaliName: DenaliID,
|
||||
|
||||
TestnetName: TestnetID,
|
||||
LocalName: LocalID,
|
||||
}
|
||||
|
||||
validNetworkName = regexp.MustCompile(`network-[0-9]+`)
|
||||
)
|
||||
|
||||
// NetworkName returns a human readable name for the network with
|
||||
// ID [networkID]
|
||||
func NetworkName(networkID uint32) string {
|
||||
if name, exists := NetworkIDToNetworkName[networkID]; exists {
|
||||
return name
|
||||
}
|
||||
return fmt.Sprintf("network-%d", networkID)
|
||||
}
|
||||
|
||||
// NetworkID returns the ID of the network with name [networkName]
|
||||
func NetworkID(networkName string) (uint32, error) {
|
||||
networkName = strings.ToLower(networkName)
|
||||
if id, exists := NetworkNameToNetworkID[networkName]; exists {
|
||||
return id, nil
|
||||
}
|
||||
|
||||
if id, err := strconv.ParseUint(networkName, 10, 0); err == nil {
|
||||
if id > math.MaxUint32 {
|
||||
return 0, fmt.Errorf("NetworkID %s not in [0, 2^32)", networkName)
|
||||
}
|
||||
return uint32(id), nil
|
||||
}
|
||||
if validNetworkName.MatchString(networkName) {
|
||||
if id, err := strconv.Atoi(networkName[8:]); err == nil {
|
||||
if id > math.MaxUint32 {
|
||||
return 0, fmt.Errorf("NetworkID %s not in [0, 2^32)", networkName)
|
||||
}
|
||||
return uint32(id), nil
|
||||
}
|
||||
}
|
||||
|
||||
return 0, fmt.Errorf("Failed to parse %s as a network name", networkName)
|
||||
}
|
|
@ -0,0 +1,52 @@
|
|||
module github.com/ava-labs/gecko
|
||||
|
||||
go 1.14
|
||||
|
||||
require (
|
||||
github.com/AppsFlyer/go-sundheit v0.2.0
|
||||
github.com/allegro/bigcache v1.2.1 // indirect
|
||||
github.com/aristanetworks/goarista v0.0.0-20200520141224-0f14e646773f // indirect
|
||||
github.com/ava-labs/coreth v0.2.4 // Added manually; don't delete
|
||||
github.com/ava-labs/go-ethereum v1.9.3 // indirect
|
||||
github.com/deckarep/golang-set v1.7.1 // indirect
|
||||
github.com/decred/dcrd/dcrec/secp256k1 v1.0.3
|
||||
github.com/decred/dcrd/dcrec/secp256k1/v3 v3.0.0-20200526030155-0c6c7ca85d3b
|
||||
github.com/edsrzf/mmap-go v1.0.0 // indirect
|
||||
github.com/elastic/gosigar v0.10.5 // indirect
|
||||
github.com/fjl/memsize v0.0.0-20190710130421-bcb5799ab5e5 // indirect
|
||||
github.com/gballet/go-libpcsclite v0.0.0-20191108122812-4678299bea08 // indirect
|
||||
github.com/golang/protobuf v1.4.2
|
||||
github.com/gorilla/handlers v1.4.2
|
||||
github.com/gorilla/mux v1.7.4
|
||||
github.com/gorilla/rpc v1.2.0
|
||||
github.com/gorilla/websocket v1.4.2
|
||||
github.com/hashicorp/go-plugin v1.3.0
|
||||
github.com/hashicorp/golang-lru v0.5.4 // indirect
|
||||
github.com/huin/goupnp v1.0.0
|
||||
github.com/jackpal/gateway v1.0.6
|
||||
github.com/jackpal/go-nat-pmp v1.0.2
|
||||
github.com/karalabe/usb v0.0.0-20191104083709-911d15fe12a9 // indirect
|
||||
github.com/mattn/go-colorable v0.1.6 // indirect
|
||||
github.com/mitchellh/go-homedir v1.1.0
|
||||
github.com/mr-tron/base58 v1.1.3
|
||||
github.com/nbutton23/zxcvbn-go v0.0.0-20180912185939-ae427f1e4c1d
|
||||
github.com/olekukonko/tablewriter v0.0.4 // indirect
|
||||
github.com/pborman/uuid v1.2.0 // indirect
|
||||
github.com/prometheus/client_golang v1.6.0
|
||||
github.com/prometheus/tsdb v0.10.0 // indirect
|
||||
github.com/rjeczalik/notify v0.9.2 // indirect
|
||||
github.com/rs/cors v1.7.0
|
||||
github.com/status-im/keycard-go v0.0.0-20200402102358-957c09536969 // indirect
|
||||
github.com/steakknife/bloomfilter v0.0.0-20180922174646-6819c0d2a570 // indirect
|
||||
github.com/steakknife/hamming v0.0.0-20180906055917-c99c65617cd3 // indirect
|
||||
github.com/stretchr/testify v1.4.0
|
||||
github.com/syndtr/goleveldb v1.0.0
|
||||
github.com/tyler-smith/go-bip39 v1.0.2 // indirect
|
||||
github.com/wsddn/go-ecdh v0.0.0-20161211032359-48726bab9208 // indirect
|
||||
golang.org/x/crypto v0.0.0-20200510223506-06a226fb4e37
|
||||
golang.org/x/net v0.0.0-20200520182314-0ba52f642ac2
|
||||
google.golang.org/grpc v1.29.1
|
||||
gopkg.in/olebedev/go-duktape.v3 v3.0.0-20200316214253-d7b0ff38cac9 // indirect
|
||||
gopkg.in/urfave/cli.v1 v1.20.0 // indirect
|
||||
nanomsg.org/go/mangos/v2 v2.0.8
|
||||
)
|
|
@ -0,0 +1,366 @@
|
|||
cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
|
||||
github.com/AppsFlyer/go-sundheit v0.2.0 h1:FArqX+HbqZ6U32RC3giEAWRUpkggqxHj91KIvxNgwjU=
|
||||
github.com/AppsFlyer/go-sundheit v0.2.0/go.mod h1:rCRkVTMQo7/krF7xQ9X0XEF1an68viFR6/Gy02q+4ds=
|
||||
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
||||
github.com/Microsoft/go-winio v0.4.11/go.mod h1:VhR8bwka0BXejwEJY73c50VrPtXAaKcyvVC4A4RozmA=
|
||||
github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU=
|
||||
github.com/Shopify/sarama v1.26.1/go.mod h1:NbSGBSSndYaIhRcBtY9V0U7AyH+x71bG668AuWys/yU=
|
||||
github.com/Shopify/toxiproxy v2.1.4+incompatible/go.mod h1:OXgGpZ6Cli1/URJOF1DMxUHB2q5Ap20/P/eIdh4G0pI=
|
||||
github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
|
||||
github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
|
||||
github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
|
||||
github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
|
||||
github.com/allegro/bigcache v1.2.1 h1:hg1sY1raCwic3Vnsvje6TT7/pnZba83LeFck5NrFKSc=
|
||||
github.com/allegro/bigcache v1.2.1/go.mod h1:Cb/ax3seSYIx7SuZdm2G2xzfwmv3TPSk2ucNfQESPXM=
|
||||
github.com/aristanetworks/fsnotify v1.4.2/go.mod h1:D/rtu7LpjYM8tRJphJ0hUBYpjai8SfX+aSNsWDTq/Ks=
|
||||
github.com/aristanetworks/glog v0.0.0-20191112221043-67e8567f59f3/go.mod h1:KASm+qXFKs/xjSoWn30NrWBBvdTTQq+UjkhjEJHfSFA=
|
||||
github.com/aristanetworks/goarista v0.0.0-20200520141224-0f14e646773f h1:uM6lu1fpmCwf54zb6Ckkvphioq8MLlyFb/TlTgPpCKc=
|
||||
github.com/aristanetworks/goarista v0.0.0-20200520141224-0f14e646773f/go.mod h1:QZe5Yh80Hp1b6JxQdpfSEEe8X7hTyTEZSosSrFf/oJE=
|
||||
github.com/aristanetworks/splunk-hec-go v0.3.3/go.mod h1:1VHO9r17b0K7WmOlLb9nTk/2YanvOEnLMUgsFrxBROc=
|
||||
github.com/ava-labs/coreth v0.2.4 h1:MhnbuRyMcij7WU4+frayp40quc44AMPc4IrxXhmucWw=
|
||||
github.com/ava-labs/coreth v0.2.4/go.mod h1:pGolKipwq5vGIY2IBBcBkMYrqniXMsS5SBn+BBi4+Js=
|
||||
github.com/ava-labs/go-ethereum v1.9.3 h1:GmnMZ/dlvVAPFmWBzEpRJX49pUAymPfoASLNRJqR0AY=
|
||||
github.com/ava-labs/go-ethereum v1.9.3/go.mod h1:a+agc6fXfZFsPZCylA3ry4Y8CLCqLKg3Rc23NXZ9aw8=
|
||||
github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
|
||||
github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8=
|
||||
github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
|
||||
github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
|
||||
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
|
||||
github.com/cespare/xxhash v1.1.0 h1:a6HrQnmkObjyL+Gs60czilIUGqrzKutQD6XZog3p+ko=
|
||||
github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc=
|
||||
github.com/cespare/xxhash/v2 v2.1.1 h1:6MnRN8NT7+YBpUIWxHtefFZOKTAPgGjpQSxqLNn0+qY=
|
||||
github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
|
||||
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
|
||||
github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=
|
||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/deckarep/golang-set v1.7.1 h1:SCQV0S6gTtp6itiFrTqI+pfmJ4LN85S1YzhDf9rTHJQ=
|
||||
github.com/deckarep/golang-set v1.7.1/go.mod h1:93vsz/8Wt4joVM7c2AVqh+YRMiUSc14yDtF28KmMOgQ=
|
||||
github.com/decred/dcrd v1.3.0 h1:EEXm7BdiROfazDtuFsOu9mfotnyy00bgCuVwUqaszFo=
|
||||
github.com/decred/dcrd/chaincfg/chainhash v1.0.2/go.mod h1:BpbrGgrPTr3YJYRN3Bm+D9NuaFd+zGyNeIKgrhCXK60=
|
||||
github.com/decred/dcrd/crypto/blake256 v1.0.0/go.mod h1:sQl2p6Y26YV+ZOcSTP6thNdn47hh8kt6rqSlvmrXFAc=
|
||||
github.com/decred/dcrd/dcrec v1.0.0 h1:W+z6Es+Rai3MXYVoPAxYr5U1DGis0Co33scJ6uH2J6o=
|
||||
github.com/decred/dcrd/dcrec/secp256k1 v1.0.3 h1:u4XpHqlscRolxPxt2YHrFBDVZYY1AK+KMV02H1r+HmU=
|
||||
github.com/decred/dcrd/dcrec/secp256k1 v1.0.3/go.mod h1:eCL8H4MYYjRvsw2TuANvEOcVMFbmi9rt/6hJUWU5wlU=
|
||||
github.com/decred/dcrd/dcrec/secp256k1/v2 v2.0.0 h1:3GIJYXQDAKpLEFriGFN8SbSffak10UXHGdIcFaMPykY=
|
||||
github.com/decred/dcrd/dcrec/secp256k1/v2 v2.0.0/go.mod h1:3s92l0paYkZoIHuj4X93Teg/HB7eGM9x/zokGw+u4mY=
|
||||
github.com/decred/dcrd/dcrec/secp256k1/v3 v3.0.0-20200526030155-0c6c7ca85d3b h1:TSqdwcjNCJ2SXwoVMkgn9oZeuR1Lh2akLzZh58hPjzQ=
|
||||
github.com/decred/dcrd/dcrec/secp256k1/v3 v3.0.0-20200526030155-0c6c7ca85d3b/go.mod h1:J70FGZSbzsjecRTiTzER+3f1KZLNaXkuv+yeFTKoxM8=
|
||||
github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no=
|
||||
github.com/eapache/go-resiliency v1.2.0/go.mod h1:kFI+JgMyC7bLPUVY133qvEBtVayf5mFgVsvEsIPBvNs=
|
||||
github.com/eapache/go-xerial-snappy v0.0.0-20180814174437-776d5712da21/go.mod h1:+020luEh2TKB4/GOp8oxxtq0Daoen/Cii55CzbTV6DU=
|
||||
github.com/eapache/queue v1.1.0/go.mod h1:6eCeP0CKFpHLu8blIFXhExK/dRa7WDZfr6jVFPTqq+I=
|
||||
github.com/edsrzf/mmap-go v1.0.0 h1:CEBF7HpRnUCSJgGUb5h1Gm7e3VkmVDrR8lvWVLtrOFw=
|
||||
github.com/edsrzf/mmap-go v1.0.0/go.mod h1:YO35OhQPt3KJa3ryjFM5Bs14WD66h8eGKpfaBNrHW5M=
|
||||
github.com/elastic/gosigar v0.10.5 h1:GzPQ+78RaAb4J63unidA/JavQRKrB6s8IOzN6Ib59jo=
|
||||
github.com/elastic/gosigar v0.10.5/go.mod h1:cdorVVzy1fhmEqmtgqkoE3bYtCfSCkVyjTyCIo22xvs=
|
||||
github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
|
||||
github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
|
||||
github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98=
|
||||
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
|
||||
github.com/fjl/memsize v0.0.0-20190710130421-bcb5799ab5e5 h1:FtmdgXiUlNeRsoNMFlKLDt+S+6hbjVMEW6RGQ7aUf7c=
|
||||
github.com/fjl/memsize v0.0.0-20190710130421-bcb5799ab5e5/go.mod h1:VvhXpOYNQvB+uIk2RvXzuaQtkQJzzIx6lSBe1xv7hi0=
|
||||
github.com/fortytw2/leaktest v1.3.0/go.mod h1:jDsjWgpAGjm2CA7WthBh/CdZYEPF31XHquHwclZch5g=
|
||||
github.com/frankban/quicktest v1.7.2/go.mod h1:jaStnuzAqU1AJdCO0l53JDCJrVDKcS03DbaAcR7Ks/o=
|
||||
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
|
||||
github.com/garyburd/redigo v1.6.0/go.mod h1:NR3MbYisc3/PwhQ00EMzDiPmrwpPxAn5GI05/YaO1SY=
|
||||
github.com/gballet/go-libpcsclite v0.0.0-20191108122812-4678299bea08 h1:f6D9Hr8xV8uYKlyuj8XIruxlh9WjVjdh1gIicAS7ays=
|
||||
github.com/gballet/go-libpcsclite v0.0.0-20191108122812-4678299bea08/go.mod h1:x7DCsMOv1taUwEWCzT4cmDeAkigA5/QCwUodaVOe8Ww=
|
||||
github.com/gdamore/optopia v0.2.0/go.mod h1:YKYEwo5C1Pa617H7NlPcmQXl+vG6YnSSNB44n8dNL0Q=
|
||||
github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
|
||||
github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
|
||||
github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE=
|
||||
github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk=
|
||||
github.com/go-stack/stack v1.8.0 h1:5SgMzNM5HxrEjV0ww2lTmX6E2Izsfxas4+YHWRs3Lsk=
|
||||
github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
|
||||
github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
|
||||
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
|
||||
github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
||||
github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
|
||||
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||
github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||
github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||
github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw=
|
||||
github.com/golang/protobuf v1.3.4/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw=
|
||||
github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8=
|
||||
github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA=
|
||||
github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs=
|
||||
github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w=
|
||||
github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0=
|
||||
github.com/golang/protobuf v1.4.2 h1:+Z5KGCizgyZCbGh1KZqA0fcLLkwbsjIzS4aV2v7wJX0=
|
||||
github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
|
||||
github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db h1:woRePGFeVFfLKN/pOkfl+p/TAqKOfFu+7KPlMVpok/w=
|
||||
github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
|
||||
github.com/golang/snappy v0.0.1 h1:Qgr9rKW7uDUkrbSmQeiDsGa8SjGyCOGtuasMWwvp2P4=
|
||||
github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
|
||||
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
|
||||
github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
|
||||
github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
|
||||
github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
||||
github.com/google/uuid v1.0.0 h1:b4Gk+7WdP/d3HZH8EJsZpvV7EtDOgaZLtnaNGIu1adA=
|
||||
github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/gorilla/handlers v1.4.2 h1:0QniY0USkHQ1RGCLfKxeNHK9bkDHGRYGNDFBCS+YARg=
|
||||
github.com/gorilla/handlers v1.4.2/go.mod h1:Qkdc/uu4tH4g6mTK6auzZ766c4CA0Ng8+o/OAirnOIQ=
|
||||
github.com/gorilla/mux v1.7.4 h1:VuZ8uybHlWmqV03+zRzdwKL4tUnIp1MAQtp1mIFE1bc=
|
||||
github.com/gorilla/mux v1.7.4/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So=
|
||||
github.com/gorilla/rpc v1.2.0 h1:WvvdC2lNeT1SP32zrIce5l0ECBfbAlmrmSBsuc57wfk=
|
||||
github.com/gorilla/rpc v1.2.0/go.mod h1:V4h9r+4sF5HnzqbwIez0fKSpANP0zlYd3qR7p36jkTQ=
|
||||
github.com/gorilla/websocket v1.4.1/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
|
||||
github.com/gorilla/websocket v1.4.2 h1:+/TMaTYc4QFitKJxsQ7Yye35DkWvkdLcvGKqM+x0Ufc=
|
||||
github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
|
||||
github.com/hashicorp/go-hclog v0.0.0-20180709165350-ff2cf002a8dd h1:rNuUHR+CvK1IS89MMtcF0EpcVMZtjKfPRp4MEmt/aTs=
|
||||
github.com/hashicorp/go-hclog v0.0.0-20180709165350-ff2cf002a8dd/go.mod h1:9bjs9uLqI8l75knNv3lV1kA55veR+WUPSiKIWcQHudI=
|
||||
github.com/hashicorp/go-plugin v1.3.0 h1:4d/wJojzvHV1I4i/rrjVaeuyxWrLzDE1mDCyDy8fXS8=
|
||||
github.com/hashicorp/go-plugin v1.3.0/go.mod h1:F9eH4LrE/ZsRdbwhfjs9k9HoDUwAHnYtXdgmf1AVNs0=
|
||||
github.com/hashicorp/go-uuid v1.0.2/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=
|
||||
github.com/hashicorp/golang-lru v0.5.4 h1:YDjusn29QI/Das2iO9M0BHnIbxPeyuCHsjMW+lJfyTc=
|
||||
github.com/hashicorp/golang-lru v0.5.4/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4=
|
||||
github.com/hashicorp/yamux v0.0.0-20180604194846-3520598351bb h1:b5rjCoWHc7eqmAS4/qyk21ZsHyb6Mxv/jykxvNTkU4M=
|
||||
github.com/hashicorp/yamux v0.0.0-20180604194846-3520598351bb/go.mod h1:+NfK9FKeTrX5uv1uIXGdwYDTeHna2qgaIlx54MXqjAM=
|
||||
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
|
||||
github.com/huin/goupnp v1.0.0 h1:wg75sLpL6DZqwHQN6E1Cfk6mtfzS45z8OV+ic+DtHRo=
|
||||
github.com/huin/goupnp v1.0.0/go.mod h1:n9v9KO1tAxYH82qOn+UTIFQDmx5n1Zxd/ClZDMX7Bnc=
|
||||
github.com/huin/goutil v0.0.0-20170803182201-1ca381bf3150/go.mod h1:PpLOETDnJ0o3iZrZfqZzyLl6l7F3c6L1oWn7OICBi6o=
|
||||
github.com/influxdata/influxdb1-client v0.0.0-20191209144304-8bf82d3c094d/go.mod h1:qj24IKcXYK6Iy9ceXlo3Tc+vtHo9lIhSX5JddghvEPo=
|
||||
github.com/jackpal/gateway v1.0.6 h1:/MJORKvJEwNVldtGVJC2p2cwCnsSoLn3hl3zxmZT7tk=
|
||||
github.com/jackpal/gateway v1.0.6/go.mod h1:lTpwd4ACLXmpyiCTRtfiNyVnUmqT9RivzCDQetPfnjA=
|
||||
github.com/jackpal/go-nat-pmp v1.0.2 h1:KzKSgb7qkJvOUTqYl9/Hg/me3pWgBmERKrTGD7BdWus=
|
||||
github.com/jackpal/go-nat-pmp v1.0.2/go.mod h1:QPH045xvCAeXUZOxsnwmrtiCoxIr9eob+4orBN1SBKc=
|
||||
github.com/jcmturner/gofork v1.0.0/go.mod h1:MK8+TM0La+2rjBD4jE12Kj1pCCxK7d2LK/UM3ncEo0o=
|
||||
github.com/jhump/protoreflect v1.6.0/go.mod h1:eaTn3RZAmMBcV0fifFvlm6VHNz3wSkYyXYWUh7ymB74=
|
||||
github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
|
||||
github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
|
||||
github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w=
|
||||
github.com/karalabe/usb v0.0.0-20191104083709-911d15fe12a9 h1:ZHuwnjpP8LsVsUYqTqeVAI+GfDfJ6UNPrExZF+vX/DQ=
|
||||
github.com/karalabe/usb v0.0.0-20191104083709-911d15fe12a9/go.mod h1:Od972xHfMJowv7NGVDiWVxk2zxnWgjLlJzE+F4F7AGU=
|
||||
github.com/klauspost/compress v1.9.8/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A=
|
||||
github.com/klauspost/compress v1.10.1/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs=
|
||||
github.com/klauspost/cpuid v1.2.3/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek=
|
||||
github.com/klauspost/reedsolomon v1.9.3/go.mod h1:CwCi+NUr9pqSVktrkN+Ondf06rkhYZ/pcNv7fu+8Un4=
|
||||
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
|
||||
github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc=
|
||||
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
|
||||
github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
|
||||
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
||||
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
||||
github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw=
|
||||
github.com/mattn/go-colorable v0.1.6 h1:6Su7aK7lXmJ/U79bYtBjLNaha4Fs1Rg9plHpcH+vvnE=
|
||||
github.com/mattn/go-colorable v0.1.6/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc=
|
||||
github.com/mattn/go-isatty v0.0.12 h1:wuysRhFDzyxgEmMf5xjvJ2M9dZoWAXNNr5LSBS7uHXY=
|
||||
github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU=
|
||||
github.com/mattn/go-runewidth v0.0.7 h1:Ei8KR0497xHyKJPAv59M1dkC+rOZCMBJ+t3fZ+twI54=
|
||||
github.com/mattn/go-runewidth v0.0.7/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI=
|
||||
github.com/matttproud/golang_protobuf_extensions v1.0.1 h1:4hp9jkHxhMHkqkrB3Ix0jegS5sx/RkqARlsWZ6pIwiU=
|
||||
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
|
||||
github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y=
|
||||
github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
|
||||
github.com/mitchellh/go-testing-interface v0.0.0-20171004221916-a61a99592b77 h1:7GoSOOW2jpsfkntVKaS2rAr1TJqfcxotyaUcuxoZSzg=
|
||||
github.com/mitchellh/go-testing-interface v0.0.0-20171004221916-a61a99592b77/go.mod h1:kRemZodwjscx+RGhAo8eIhFbs2+BFgRtFPeD/KE+zxI=
|
||||
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
||||
github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
|
||||
github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
|
||||
github.com/mr-tron/base58 v1.1.3 h1:v+sk57XuaCKGXpWtVBX8YJzO7hMGx4Aajh4TQbdEFdc=
|
||||
github.com/mr-tron/base58 v1.1.3/go.mod h1:BinMc/sQntlIE1frQmRFPUoPA1Zkr8VRgBdjWI2mNwc=
|
||||
github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
|
||||
github.com/nbutton23/zxcvbn-go v0.0.0-20180912185939-ae427f1e4c1d h1:AREM5mwr4u1ORQBMvzfzBgpsctsbQikCVpvC+tX285E=
|
||||
github.com/nbutton23/zxcvbn-go v0.0.0-20180912185939-ae427f1e4c1d/go.mod h1:o96djdrsSGy3AWPyBgZMAGfxZNfgntdJG+11KU4QvbU=
|
||||
github.com/oklog/run v1.0.0 h1:Ru7dDtJNOyC66gQ5dQmaCa0qIsAUFY3sFpK1Xk8igrw=
|
||||
github.com/oklog/run v1.0.0/go.mod h1:dlhp/R75TPv97u0XWUtDeV/lRKWPKSdTuV0TZvrmrQA=
|
||||
github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U=
|
||||
github.com/olekukonko/tablewriter v0.0.4 h1:vHD/YYe1Wolo78koG299f7V/VAS08c6IpCLn+Ejf/w8=
|
||||
github.com/olekukonko/tablewriter v0.0.4/go.mod h1:zq6QwlOf5SlnkVbMSr5EoBv3636FWnp+qbPhuoO21uA=
|
||||
github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
||||
github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
||||
github.com/onsi/ginkgo v1.10.1/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
||||
github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
|
||||
github.com/onsi/gomega v1.7.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
|
||||
github.com/openconfig/gnmi v0.0.0-20190823184014-89b2bf29312c/go.mod h1:t+O9It+LKzfOAhKTT5O0ehDix+MTqbtT0T9t+7zzOvc=
|
||||
github.com/openconfig/reference v0.0.0-20190727015836-8dfd928c9696/go.mod h1:ym2A+zigScwkSEb/cVQB0/ZMpU3rqiH6X7WRRsxgOGw=
|
||||
github.com/pborman/uuid v1.2.0 h1:J7Q5mO4ysT1dv8hyrUGHb9+ooztCXu1D8MY8DZYsu3g=
|
||||
github.com/pborman/uuid v1.2.0/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtPdI/k=
|
||||
github.com/pierrec/lz4 v2.4.1+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY=
|
||||
github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I=
|
||||
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
|
||||
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=
|
||||
github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo=
|
||||
github.com/prometheus/client_golang v1.4.1/go.mod h1:e9GMxYsXl05ICDXkRhurwBS4Q3OK1iX/F2sw+iXX5zU=
|
||||
github.com/prometheus/client_golang v1.6.0 h1:YVPodQOcK15POxhgARIvnDRVpLcuK8mglnMrWfyrw6A=
|
||||
github.com/prometheus/client_golang v1.6.0/go.mod h1:ZLOG9ck3JLRdB5MgO8f+lLTe83AXG6ro35rLTxvnIl4=
|
||||
github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
|
||||
github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
|
||||
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
|
||||
github.com/prometheus/client_model v0.2.0 h1:uq5h0d+GuxiXLJLNABMgp2qUWDPiLvgCzz2dUR+/W/M=
|
||||
github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
|
||||
github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
|
||||
github.com/prometheus/common v0.9.1 h1:KOMtN28tlbam3/7ZKEYKHhKoJZYYj3gMH4uc62x7X7U=
|
||||
github.com/prometheus/common v0.9.1/go.mod h1:yhUN8i9wzaXS3w1O07YhxHEBxD+W35wd8bs7vj7HSQ4=
|
||||
github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
|
||||
github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
|
||||
github.com/prometheus/procfs v0.0.8/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+GxbHq6oeK9A=
|
||||
github.com/prometheus/procfs v0.0.10/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+GxbHq6oeK9A=
|
||||
github.com/prometheus/procfs v0.0.11 h1:DhHlBtkHWPYi8O2y31JkK0TF+DGM+51OopZjH/Ia5qI=
|
||||
github.com/prometheus/procfs v0.0.11/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU=
|
||||
github.com/prometheus/tsdb v0.10.0 h1:If5rVCMTp6W2SiRAQFlbpJNgVlgMEd+U2GZckwK38ic=
|
||||
github.com/prometheus/tsdb v0.10.0/go.mod h1:oi49uRhEe9dPUTlS3JRZOwJuVi6tmh10QSgwXEyGCt4=
|
||||
github.com/rcrowley/go-metrics v0.0.0-20190826022208-cac0b30c2563/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4=
|
||||
github.com/rjeczalik/notify v0.9.2 h1:MiTWrPj55mNDHEiIX5YUSKefw/+lCQVoAFmD6oQm5w8=
|
||||
github.com/rjeczalik/notify v0.9.2/go.mod h1:aErll2f0sUX9PXZnVNyeiObbmTlk5jnMoCa4QEjJeqM=
|
||||
github.com/rs/cors v1.7.0 h1:+88SsELBHx5r+hZ8TCkggzSstaWNbDvThkVK8H6f9ik=
|
||||
github.com/rs/cors v1.7.0/go.mod h1:gFx+x8UowdsKA9AchylcLynDq+nNFfI8FkUZdN/jGCU=
|
||||
github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0=
|
||||
github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
|
||||
github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
|
||||
github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA=
|
||||
github.com/status-im/keycard-go v0.0.0-20200402102358-957c09536969 h1:Oo2KZNP70KE0+IUJSidPj/BFS/RXNHmKIJOdckzml2E=
|
||||
github.com/status-im/keycard-go v0.0.0-20200402102358-957c09536969/go.mod h1:RZLeN1LMWmRsyYjvAu+I6Dm9QmlDaIIt+Y+4Kd7Tp+Q=
|
||||
github.com/steakknife/bloomfilter v0.0.0-20180922174646-6819c0d2a570 h1:gIlAHnH1vJb5vwEjIp5kBj/eu99p/bl0Ay2goiPe5xE=
|
||||
github.com/steakknife/bloomfilter v0.0.0-20180922174646-6819c0d2a570/go.mod h1:8OR4w3TdeIHIh1g6EMY5p0gVNOovcWC+1vpc7naMuAw=
|
||||
github.com/steakknife/hamming v0.0.0-20180906055917-c99c65617cd3 h1:njlZPzLwU639dk2kqnCPPv+wNjq7Xb6EfUxe/oX0/NM=
|
||||
github.com/steakknife/hamming v0.0.0-20180906055917-c99c65617cd3/go.mod h1:hpGUWaI9xL8pRQCTXQgocU38Qw1g0Us7n5PxxTwTCYU=
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
||||
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
||||
github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk=
|
||||
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
|
||||
github.com/syndtr/goleveldb v1.0.0 h1:fBdIW9lB4Iz0n9khmH8w27SJ3QEJ7+IgjPEwGSZiFdE=
|
||||
github.com/syndtr/goleveldb v1.0.0/go.mod h1:ZVVdQEZoIme9iO1Ch2Jdy24qqXrMMOU6lpPAyBWyWuQ=
|
||||
github.com/templexxx/cpufeat v0.0.0-20180724012125-cef66df7f161/go.mod h1:wM7WEvslTq+iOEAMDLSzhVuOt5BRZ05WirO+b09GHQU=
|
||||
github.com/templexxx/xor v0.0.0-20191217153810-f85b25db303b/go.mod h1:5XA7W9S6mni3h5uvOC75dA3m9CCCaS83lltmc0ukdi4=
|
||||
github.com/tjfoc/gmsm v1.3.0/go.mod h1:HaUcFuY0auTiaHB9MHFGCPx5IaLhTUd2atbCFBQXn9w=
|
||||
github.com/tyler-smith/go-bip39 v1.0.2 h1:+t3w+KwLXO6154GNJY+qUtIxLTmFjfUmpguQT1OlOT8=
|
||||
github.com/tyler-smith/go-bip39 v1.0.2/go.mod h1:sJ5fKU0s6JVwZjjcUEX2zFOnvq0ASQ2K9Zr6cf67kNs=
|
||||
github.com/wsddn/go-ecdh v0.0.0-20161211032359-48726bab9208 h1:1cngl9mPEoITZG8s8cVcUy5CeIBYhEESkOB7m6Gmkrk=
|
||||
github.com/wsddn/go-ecdh v0.0.0-20161211032359-48726bab9208/go.mod h1:IotVbo4F+mw0EzQ08zFqg7pK3FebNXpaMsRy2RT+Ees=
|
||||
github.com/xdg/scram v0.0.0-20180814205039-7eeb5667e42c/go.mod h1:lB8K/P019DLNhemzwFU4jHLhdvlE6uDZjXFejJXr49I=
|
||||
github.com/xdg/stringprep v1.0.0/go.mod h1:Jhud4/sHMO4oL310DaZAKk9ZaJ08SJfe+sJh0HrGL1Y=
|
||||
github.com/xtaci/kcp-go v5.4.20+incompatible/go.mod h1:bN6vIwHQbfHaHtFpEssmWsN45a+AZwO7eyRCmEIbtvE=
|
||||
github.com/xtaci/lossyconn v0.0.0-20190602105132-8df528c0c9ae/go.mod h1:gXtu8J62kEgmN++bm9BVICuT/e8yiLI2KFobd/TRFsE=
|
||||
go.opencensus.io v0.22.1 h1:8dP3SGL7MPB94crU3bEPplMPe83FI4EouesJUeFHv50=
|
||||
go.opencensus.io v0.22.1/go.mod h1:Ap50jQcDJrx6rB6VgeeFPtuPIf3wMRvRfrfYDO6+BmA=
|
||||
golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20191219195013-becbf705a915/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.0.0-20200204104054-c9f3fb736b72/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.0.0-20200221231518-2aa609cf4a9d/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.0.0-20200510223506-06a226fb4e37 h1:cg5LA/zNPRzIXIWSCxQW10Rvpy94aQh3LT/ShoCpkHw=
|
||||
golang.org/x/crypto v0.0.0-20200510223506-06a226fb4e37/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
|
||||
golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
|
||||
golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
|
||||
golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
|
||||
golang.org/x/net v0.0.0-20180530234432-1e491301e022/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20181011144130-49bb7cea24b1/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20200222125558-5a598a2470a0/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20200520182314-0ba52f642ac2 h1:eDrdRpKgkcCqKZQwyZRyeFZgfqt37SL7Kv3tok06cKE=
|
||||
golang.org/x/net v0.0.0-20200520182314-0ba52f642ac2/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
|
||||
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20180926160741-c2ed4eda69e7/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20181128092732-4ed8d59d0b35/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200106162015-b016eb3dc98e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200219091948-cb0a6d8edb6c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200420163511-1957bb5e6d1f h1:gWF768j/LaZugp8dyS4UwsslYCYz9XgFxvlgsn0n9H8=
|
||||
golang.org/x/sys v0.0.0-20200420163511-1957bb5e6d1f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs=
|
||||
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
|
||||
golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
|
||||
golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
||||
golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
|
||||
golang.org/x/tools v0.0.0-20200221224223-e1da425f72fd/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
|
||||
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
||||
google.golang.org/genproto v0.0.0-20170818010345-ee236bd376b0/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
|
||||
google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
|
||||
google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
|
||||
google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55 h1:gSJIx1SDwno+2ElGhA4+qG2zF97qiUzTM+rQ0klBOcE=
|
||||
google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
|
||||
google.golang.org/genproto v0.0.0-20200218151345-dad8c97a84f5 h1:jB9+PJSvu5tBfmJHy/OVapFdjDF3WvpkqRhxqrmzoEU=
|
||||
google.golang.org/genproto v0.0.0-20200218151345-dad8c97a84f5/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
|
||||
google.golang.org/grpc v1.8.0/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw=
|
||||
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
|
||||
google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38=
|
||||
google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
|
||||
google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY=
|
||||
google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
|
||||
google.golang.org/grpc v1.27.1/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
|
||||
google.golang.org/grpc v1.29.1 h1:EC2SB8S04d2r73uptxphDSUG+kTKVgjRPF+N3xpxRB4=
|
||||
google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk=
|
||||
google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
|
||||
google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
|
||||
google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM=
|
||||
google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE=
|
||||
google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo=
|
||||
google.golang.org/protobuf v1.23.0 h1:4MY060fB1DLGMB/7MBTLnwQUY6+F09GEiz6SsrNqyzM=
|
||||
google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
|
||||
gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
|
||||
gopkg.in/bsm/ratelimit.v1 v1.0.0-20160220154919-db14e161995a/go.mod h1:KF9sEfUPAXdG8Oev9e99iLGnl2uJMjc5B+4y3O7x610=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
|
||||
gopkg.in/jcmturner/aescts.v1 v1.0.1/go.mod h1:nsR8qBOg+OucoIW+WMhB3GspUQXq9XorLnQb9XtvcOo=
|
||||
gopkg.in/jcmturner/dnsutils.v1 v1.0.1/go.mod h1:m3v+5svpVOhtFAP/wSz+yzh4Mc0Fg7eRhxkJMWSIz9Q=
|
||||
gopkg.in/jcmturner/goidentity.v3 v3.0.0/go.mod h1:oG2kH0IvSYNIu80dVAyu/yoefjq1mNfM5bm88whjWx4=
|
||||
gopkg.in/jcmturner/gokrb5.v7 v7.5.0/go.mod h1:l8VISx+WGYp+Fp7KRbsiUuXTTOnxIc3Tuvyavf11/WM=
|
||||
gopkg.in/jcmturner/rpc.v1 v1.1.0/go.mod h1:YIdkC4XfD6GXbzje11McwsDuOlZQSb9W4vfLvuNnlv8=
|
||||
gopkg.in/olebedev/go-duktape.v3 v3.0.0-20200316214253-d7b0ff38cac9 h1:ITeyKbRetrVzqR3U1eY+ywgp7IBspGd1U/bkwd1gWu4=
|
||||
gopkg.in/olebedev/go-duktape.v3 v3.0.0-20200316214253-d7b0ff38cac9/go.mod h1:uAJfkITjFhyEEuUfm7bsmCZRbW5WRq8s9EY8HZ6hCns=
|
||||
gopkg.in/redis.v4 v4.2.4/go.mod h1:8KREHdypkCEojGKQcjMqAODMICIVwZAONWq8RowTITA=
|
||||
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
|
||||
gopkg.in/urfave/cli.v1 v1.20.0 h1:NdAVW6RYxDif9DhDHaAortIu956m2c0v+09AZBPTbE0=
|
||||
gopkg.in/urfave/cli.v1 v1.20.0/go.mod h1:vuBzUtMdQeixQj8LVd+/98pzhxNGQoyuPBlsXHOQNO0=
|
||||
gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.2.5 h1:ymVxjfMaHvXD8RqPRmzHHsB3VvucivSkIAvJFDI5O3c=
|
||||
gopkg.in/yaml.v2 v2.2.5/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.2.8 h1:obN1ZagJSUGI0Ek/LBmuj4SNLPfIny3KsKFopxRdj10=
|
||||
gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||
honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||
nanomsg.org/go/mangos v2.0.0+incompatible h1:LE83iAKZmIY8CP0gI9ETWgGL9X2m0d4WH0oyIRuAJ7o=
|
||||
nanomsg.org/go/mangos/v2 v2.0.8 h1:Nnc5gCNPd8sSyxgfMTdlKK020p4nxLAxcQrhLVnjGQ8=
|
||||
nanomsg.org/go/mangos/v2 v2.0.8/go.mod h1:gngxudWUZkxqHN+8n/2y9gWZPcwmSbliFYJsYG8mbKs=
|
|
@ -0,0 +1,113 @@
|
|||
// (c) 2020, Alex Willmer. All rights reserved.
|
||||
// See the file LICENSE for licensing terms.
|
||||
|
||||
package ids
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestAliaserLookupError(t *testing.T) {
|
||||
emptyAliaser := Aliaser{}
|
||||
emptyAliaser.Initialize()
|
||||
tests := []struct {
|
||||
label string
|
||||
aliaser Aliaser
|
||||
alias string
|
||||
res ID
|
||||
}{
|
||||
{"Unitialized", Aliaser{}, "Batwoman", ID{}},
|
||||
{"Empty", emptyAliaser, "Batman", ID{}},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.label, func(t *testing.T) {
|
||||
res, err := tt.aliaser.Lookup(tt.alias)
|
||||
if !tt.res.Equals(res) {
|
||||
t.Errorf("Got %v, expected %v", res, tt.res)
|
||||
}
|
||||
if err == nil {
|
||||
t.Error("Expected an error due to missing alias")
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestAliaserLookup(t *testing.T) {
|
||||
id := NewID([32]byte{'K', 'a', 't', 'e', ' ', 'K', 'a', 'n', 'e'})
|
||||
aliaser := Aliaser{}
|
||||
aliaser.Initialize()
|
||||
aliaser.Alias(id, "Batwoman")
|
||||
|
||||
res, err := aliaser.Lookup("Batwoman")
|
||||
if err != nil {
|
||||
t.Fatalf("Unexpected error %q", err)
|
||||
}
|
||||
if !id.Equals(res) {
|
||||
t.Fatalf("Got %v, expected %v", res, id)
|
||||
}
|
||||
}
|
||||
|
||||
func TestAliaserAliasesEmpty(t *testing.T) {
|
||||
id := NewID([32]byte{'J', 'a', 'm', 'e', 's', ' ', 'G', 'o', 'r', 'd', 'o', 'n'})
|
||||
aliaser := Aliaser{}
|
||||
aliaser.Initialize()
|
||||
|
||||
aliases := aliaser.Aliases(id)
|
||||
if len(aliases) != 0 {
|
||||
t.Fatalf("Unexpected aliases %#v", aliases)
|
||||
}
|
||||
}
|
||||
|
||||
func TestAliaserAliases(t *testing.T) {
|
||||
id := NewID([32]byte{'B', 'r', 'u', 'c', 'e', ' ', 'W', 'a', 'y', 'n', 'e'})
|
||||
aliaser := Aliaser{}
|
||||
aliaser.Initialize()
|
||||
aliaser.Alias(id, "Batman")
|
||||
aliaser.Alias(id, "Dark Knight")
|
||||
|
||||
aliases := aliaser.Aliases(id)
|
||||
expected := []string{"Batman", "Dark Knight"}
|
||||
if !reflect.DeepEqual(aliases, expected) {
|
||||
t.Fatalf("Got %v, expected %v", aliases, expected)
|
||||
}
|
||||
}
|
||||
|
||||
func TestAliaserPrimaryAlias(t *testing.T) {
|
||||
id1 := NewID([32]byte{'J', 'a', 'm', 'e', 's', ' ', 'G', 'o', 'r', 'd', 'o', 'n'})
|
||||
id2 := NewID([32]byte{'B', 'r', 'u', 'c', 'e', ' ', 'W', 'a', 'y', 'n', 'e'})
|
||||
aliaser := Aliaser{}
|
||||
aliaser.Initialize()
|
||||
aliaser.Alias(id2, "Batman")
|
||||
aliaser.Alias(id2, "Dark Knight")
|
||||
|
||||
res, err := aliaser.PrimaryAlias(id1)
|
||||
if res != "" {
|
||||
t.Fatalf("Unexpected alias for %v", id1)
|
||||
}
|
||||
if err == nil {
|
||||
t.Fatal("Expected an error given an id with no aliases")
|
||||
}
|
||||
|
||||
res, err = aliaser.PrimaryAlias(id2)
|
||||
expected := "Batman"
|
||||
if res != expected {
|
||||
t.Fatalf("Got %v, expected %v", res, expected)
|
||||
}
|
||||
if err != nil {
|
||||
t.Fatalf("Unexpected error %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestAliaserAliasClash(t *testing.T) {
|
||||
id1 := NewID([32]byte{'B', 'r', 'u', 'c', 'e', ' ', 'W', 'a', 'y', 'n', 'e'})
|
||||
id2 := NewID([32]byte{'D', 'i', 'c', 'k', ' ', 'G', 'r', 'a', 'y', 's', 'o', 'n'})
|
||||
aliaser := Aliaser{}
|
||||
aliaser.Initialize()
|
||||
aliaser.Alias(id1, "Batman")
|
||||
|
||||
err := aliaser.Alias(id2, "Batman")
|
||||
if err == nil {
|
||||
t.Fatalf("Expected an error, due to an existing alias")
|
||||
}
|
||||
}
|
15
ids/bag.go
15
ids/bag.go
|
@ -86,6 +86,19 @@ func (b *Bag) List() []ID {
|
|||
return idList
|
||||
}
|
||||
|
||||
// Equals returns true if the bags contain the same elements
|
||||
func (b *Bag) Equals(oIDs Bag) bool {
|
||||
if b.Len() != oIDs.Len() {
|
||||
return false
|
||||
}
|
||||
for key, value := range b.counts {
|
||||
if value != oIDs.counts[key] {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
// Mode returns the id that has been seen the most and the number of times it
|
||||
// has been seen. Ties are broken by the first id to be seen the reported number
|
||||
// of times.
|
||||
|
@ -95,7 +108,7 @@ func (b *Bag) Mode() (ID, int) { return b.mode, b.modeFreq }
|
|||
func (b *Bag) Threshold() Set { return b.metThreshold }
|
||||
|
||||
// Filter returns the bag of ids with the same counts as this bag, except all
|
||||
// the ids in the returned bag must have the same bits in the range [start, end]
|
||||
// the ids in the returned bag must have the same bits in the range [start, end)
|
||||
// as id.
|
||||
func (b *Bag) Filter(start, end int, id ID) Bag {
|
||||
newBag := Bag{}
|
||||
|
|
145
ids/id_test.go
145
ids/id_test.go
|
@ -5,6 +5,7 @@ package ids
|
|||
|
||||
import (
|
||||
"bytes"
|
||||
"reflect"
|
||||
"testing"
|
||||
)
|
||||
|
||||
|
@ -29,10 +30,6 @@ func TestID(t *testing.T) {
|
|||
if b := id.Bytes(); !bytes.Equal(hash[:], b) {
|
||||
t.Fatalf("ID.Bytes returned wrong bytes")
|
||||
}
|
||||
|
||||
if str := id.String(); str != "Ba3mm8Ra8JYYebeZ9p7zw1ayorDbeD1euwxhgzSLsncKqGoNt" {
|
||||
t.Fatalf("ID.String returned wrong string: %s", str)
|
||||
}
|
||||
}
|
||||
|
||||
func TestIDBit(t *testing.T) {
|
||||
|
@ -79,3 +76,143 @@ func TestFromString(t *testing.T) {
|
|||
t.Fatal("Expected FromString to be inverse of String but it wasn't")
|
||||
}
|
||||
}
|
||||
|
||||
func TestIDFromStringError(t *testing.T) {
|
||||
tests := []struct {
|
||||
in string
|
||||
}{
|
||||
{""},
|
||||
{"foo"},
|
||||
{"foobar"},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.in, func(t *testing.T) {
|
||||
_, err := FromString(tt.in)
|
||||
if err == nil {
|
||||
t.Error("Unexpected success")
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestIDMarshalJSON(t *testing.T) {
|
||||
tests := []struct {
|
||||
label string
|
||||
in ID
|
||||
out []byte
|
||||
err error
|
||||
}{
|
||||
{"ID{}", ID{}, []byte("null"), nil},
|
||||
{"ID(\"ava labs\")",
|
||||
NewID([32]byte{'a', 'v', 'a', ' ', 'l', 'a', 'b', 's'}),
|
||||
[]byte("\"jvYi6Tn9idMi7BaymUVi9zWjg5tpmW7trfKG1AYJLKZJ2fsU7\""),
|
||||
nil,
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.label, func(t *testing.T) {
|
||||
out, err := tt.in.MarshalJSON()
|
||||
if err != tt.err {
|
||||
t.Errorf("Expected err %s, got error %v", tt.err, err)
|
||||
} else if !bytes.Equal(out, tt.out) {
|
||||
t.Errorf("got %q, expected %q", out, tt.out)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestIDUnmarshalJSON(t *testing.T) {
|
||||
tests := []struct {
|
||||
label string
|
||||
in []byte
|
||||
out ID
|
||||
err error
|
||||
}{
|
||||
{"ID{}", []byte("null"), ID{}, nil},
|
||||
{"ID(\"ava labs\")",
|
||||
[]byte("\"jvYi6Tn9idMi7BaymUVi9zWjg5tpmW7trfKG1AYJLKZJ2fsU7\""),
|
||||
NewID([32]byte{'a', 'v', 'a', ' ', 'l', 'a', 'b', 's'}),
|
||||
nil,
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.label, func(t *testing.T) {
|
||||
foo := ID{}
|
||||
err := foo.UnmarshalJSON(tt.in)
|
||||
if err != tt.err {
|
||||
t.Errorf("Expected err %s, got error %v", tt.err, err)
|
||||
} else if foo.ID != nil && foo.Key() != tt.out.Key() {
|
||||
t.Errorf("got %q, expected %q", foo.Key(), tt.out.Key())
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestIDHex(t *testing.T) {
|
||||
id := NewID([32]byte{'a', 'v', 'a', ' ', 'l', 'a', 'b', 's'})
|
||||
expected := "617661206c616273000000000000000000000000000000000000000000000000"
|
||||
actual := id.Hex()
|
||||
if actual != expected {
|
||||
t.Fatalf("got %s, expected %s", actual, expected)
|
||||
}
|
||||
}
|
||||
|
||||
func TestIDString(t *testing.T) {
|
||||
tests := []struct {
|
||||
label string
|
||||
id ID
|
||||
expected string
|
||||
}{
|
||||
{"ID{}", ID{}, "nil"},
|
||||
{"ID{[32]byte{24}}", NewID([32]byte{24}), "Ba3mm8Ra8JYYebeZ9p7zw1ayorDbeD1euwxhgzSLsncKqGoNt"},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.label, func(t *testing.T) {
|
||||
result := tt.id.String()
|
||||
if result != tt.expected {
|
||||
t.Errorf("got %q, expected %q", result, tt.expected)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestSortIDs(t *testing.T) {
|
||||
ids := []ID{
|
||||
NewID([32]byte{'e', 'v', 'a', ' ', 'l', 'a', 'b', 's'}),
|
||||
NewID([32]byte{'W', 'a', 'l', 'l', 'e', ' ', 'l', 'a', 'b', 's'}),
|
||||
NewID([32]byte{'a', 'v', 'a', ' ', 'l', 'a', 'b', 's'}),
|
||||
}
|
||||
SortIDs(ids)
|
||||
expected := []ID{
|
||||
NewID([32]byte{'W', 'a', 'l', 'l', 'e', ' ', 'l', 'a', 'b', 's'}),
|
||||
NewID([32]byte{'a', 'v', 'a', ' ', 'l', 'a', 'b', 's'}),
|
||||
NewID([32]byte{'e', 'v', 'a', ' ', 'l', 'a', 'b', 's'}),
|
||||
}
|
||||
if !reflect.DeepEqual(ids, expected) {
|
||||
t.Fatal("[]ID was not sorted lexographically")
|
||||
}
|
||||
}
|
||||
|
||||
func TestIsSortedAndUnique(t *testing.T) {
|
||||
unsorted := []ID{
|
||||
NewID([32]byte{'e', 'v', 'a', ' ', 'l', 'a', 'b', 's'}),
|
||||
NewID([32]byte{'a', 'v', 'a', ' ', 'l', 'a', 'b', 's'}),
|
||||
}
|
||||
if IsSortedAndUniqueIDs(unsorted) {
|
||||
t.Fatal("Wrongly accepted unsorted IDs")
|
||||
}
|
||||
duplicated := []ID{
|
||||
NewID([32]byte{'a', 'v', 'a', ' ', 'l', 'a', 'b', 's'}),
|
||||
NewID([32]byte{'a', 'v', 'a', ' ', 'l', 'a', 'b', 's'}),
|
||||
}
|
||||
if IsSortedAndUniqueIDs(duplicated) {
|
||||
t.Fatal("Wrongly accepted duplicated IDs")
|
||||
}
|
||||
sorted := []ID{
|
||||
NewID([32]byte{'a', 'v', 'a', ' ', 'l', 'a', 'b', 's'}),
|
||||
NewID([32]byte{'e', 'v', 'a', ' ', 'l', 'a', 'b', 's'}),
|
||||
}
|
||||
if !IsSortedAndUniqueIDs(sorted) {
|
||||
t.Fatal("Wrongly rejected sorted, unique IDs")
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,70 @@
|
|||
package ids
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestQueueSetinit(t *testing.T) {
|
||||
qs := QueueSet{}
|
||||
qs.init()
|
||||
if qs.idList == nil {
|
||||
t.Fatal("Failed to initialize")
|
||||
}
|
||||
list := qs.idList
|
||||
qs.init()
|
||||
if list != qs.idList {
|
||||
t.Fatal("Mutated an already intialized queue")
|
||||
}
|
||||
}
|
||||
|
||||
func TestQueueSetSetHead(t *testing.T) {
|
||||
qs := QueueSet{}
|
||||
id := NewID([32]byte{'a', 'v', 'a', ' ', 'l', 'a', 'b', 's'})
|
||||
qs.SetHead(id)
|
||||
if qs.idList == nil || id != qs.idList.Front().Value.(ID) {
|
||||
t.Fatal("Failed to set head of unintilised queue")
|
||||
}
|
||||
|
||||
qs.SetHead(id)
|
||||
if qs.idList.Len() != 1 || id != qs.idList.Front().Value.(ID) {
|
||||
t.Fatal("Mutated a queue which already had the desired head")
|
||||
}
|
||||
|
||||
id2 := NewID([32]byte{'e', 'v', 'a', ' ', 'l', 'a', 'b', 's'})
|
||||
qs.SetHead(id2)
|
||||
if qs.idList.Len() != 1 || id2 != qs.idList.Front().Value.(ID) {
|
||||
t.Fatal("Didn't replace the existing head")
|
||||
}
|
||||
}
|
||||
|
||||
func TestQueueSetAppend(t *testing.T) {
|
||||
qs := QueueSet{}
|
||||
id := NewID([32]byte{'a', 'v', 'a', ' ', 'l', 'a', 'b', 's'})
|
||||
qs.Append(id)
|
||||
if qs.idList == nil || id != qs.idList.Front().Value.(ID) {
|
||||
t.Fatal("Failed to append to an uninitialised queue")
|
||||
}
|
||||
|
||||
id2 := NewID([32]byte{'e', 'v', 'a', ' ', 'l', 'a', 'b', 's'})
|
||||
qs.Append(id2)
|
||||
if qs.idList.Len() != 2 || id2 != qs.idList.Back().Value.(ID) {
|
||||
t.Fatal("Failed to append to the back of the queue")
|
||||
}
|
||||
}
|
||||
|
||||
func TestQueueGetTail(t *testing.T) {
|
||||
qs := QueueSet{}
|
||||
tail := qs.GetTail()
|
||||
if !reflect.DeepEqual(tail, ID{}) {
|
||||
t.Fatalf("Empty queue returned %v, expected empty ID %v", tail, Empty)
|
||||
}
|
||||
|
||||
qs.Append(NewID([32]byte{'a', 'v', 'a', ' ', 'l', 'a', 'b', 's'}))
|
||||
id2 := NewID([32]byte{'e', 'v', 'a', ' ', 'l', 'a', 'b', 's'})
|
||||
qs.Append(id2)
|
||||
tail = qs.GetTail()
|
||||
if tail != id2 {
|
||||
t.Fatalf("Populated queue returned %v, expected %v", tail, id2)
|
||||
}
|
||||
}
|
|
@ -0,0 +1,33 @@
|
|||
// (c) 2019-2020, Ava Labs, Inc. All rights reserved.
|
||||
// See the file LICENSE for licensing terms.
|
||||
|
||||
package ids
|
||||
|
||||
// Equals returns true if the arrays are equal
|
||||
func Equals(a, b []ID) bool {
|
||||
if len(a) != len(b) {
|
||||
return false
|
||||
}
|
||||
|
||||
for i, aID := range a {
|
||||
if !aID.Equals(b[i]) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
// UnsortedEquals returns true if the have the same number of each ID
|
||||
func UnsortedEquals(a, b []ID) bool {
|
||||
if len(a) != len(b) {
|
||||
return false
|
||||
}
|
||||
|
||||
aBag := Bag{}
|
||||
aBag.Add(a...)
|
||||
|
||||
bBag := Bag{}
|
||||
bBag.Add(b...)
|
||||
|
||||
return aBag.Equals(bBag)
|
||||
}
|
|
@ -62,6 +62,9 @@ func (b *UniqueBag) Difference(diff *UniqueBag) {
|
|||
// GetSet ...
|
||||
func (b *UniqueBag) GetSet(id ID) BitSet { return (*b)[*id.ID] }
|
||||
|
||||
// RemoveSet ...
|
||||
func (b *UniqueBag) RemoveSet(id ID) { delete(*b, id.Key()) }
|
||||
|
||||
// List ...
|
||||
func (b *UniqueBag) List() []ID {
|
||||
idList := []ID(nil)
|
||||
|
|
|
@ -1,5 +0,0 @@
|
|||
#!/bin/sh
|
||||
set -ex
|
||||
|
||||
openssl genrsa -out `dirname "$0"`/rootCA.key 4096
|
||||
openssl req -x509 -new -nodes -key `dirname "$0"`/rootCA.key -sha256 -days 365250 -out `dirname "$0"`/rootCA.crt
|
|
@ -1,6 +0,0 @@
|
|||
#!/bin/sh
|
||||
set -ex
|
||||
|
||||
openssl genrsa -out `dirname "$0"`/staker.key 4096
|
||||
openssl req -new -sha256 -key `dirname "$0"`/staker.key -subj "/C=US/ST=NY/O=Avalabs/CN=ava" -out `dirname "$0"`/staker.csr
|
||||
openssl x509 -req -in `dirname "$0"`/staker.csr -CA `dirname "$0"`/rootCA.crt -CAkey `dirname "$0"`/rootCA.key -CAcreateserial -out `dirname "$0"`/staker.crt -days 365250 -sha256
|
|
@ -1,34 +0,0 @@
|
|||
-----BEGIN CERTIFICATE-----
|
||||
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
|
||||
DB8IRfWqBx2nWw==
|
||||
-----END CERTIFICATE-----
|
|
@ -1,51 +0,0 @@
|
|||
-----BEGIN RSA PRIVATE KEY-----
|
||||
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
|
||||
-----END RSA PRIVATE KEY-----
|
|
@ -1 +0,0 @@
|
|||
BAF3B5C5C6D0D14A
|
|
@ -1,27 +0,0 @@
|
|||
-----BEGIN CERTIFICATE REQUEST-----
|
||||
MIIEfzCCAmcCAQAwOjELMAkGA1UEBhMCVVMxCzAJBgNVBAgMAk5ZMRAwDgYDVQQK
|
||||
DAdBdmFsYWJzMQwwCgYDVQQDDANhdmEwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAw
|
||||
ggIKAoICAQDKYSRw/W0YpYH/MTQhiFrR0m89l6yTuzLpDtjudr/5RnhIPvtqk7YI
|
||||
Gm/m9l29xwR4J5r7SZGs+70yBetkbS+h7PwJ2rmWDwbrdyJKvVBhqf8kSn+VU2Le
|
||||
PSIcJj193LDyWhV1H4lqNkUkcAR76Fh9qjMvA2p0vJ66+eDLXlph/RYapQx9HgOj
|
||||
/0BmAKMrYCyo5BhRih+Ougg8aK4G9PQTIA5G2wTWW2QkHxM/QppFjZd/XwQeJ2H6
|
||||
ubWMFc5fttf6AzpJvFIDBu/JDCKWiCu5m8t4GL8w2OrIx8Js19lF4YYE2eojCreq
|
||||
gPi64S3ocqwKsDoySTw6/5iKQ5BUYwUXX3z7EXOqD8SMHefUKeczj4WvAaZLzR27
|
||||
qXm55EgRYQAIX4fhmY7NfSop3Wh0Eo62+JHoM/1g+UgOXlbnWpY95Mgd7/fwDSWL
|
||||
u4IxE0/uq8VufIbfC4yrY8qlTVfAffI1ldRdvJjPJBPiQ0CNrOl60LVptpkGc9sh
|
||||
H7wZ2bP0bEnYKTgLAfOzD8Ut71O2AOIa80A1GNFl4Yle/MSNJOcQOSpgtWdREzIU
|
||||
oenAjfuzM4OeTr4cRg4+VYTAo9KHKriN1DuewNzGd8WjKAVHmcIMjqISLTlzMhds
|
||||
dm+OmfQ6OvyX7v0GTOBbhP09NGcww5A0gCzXN18FS5oxnxe6OG9D0wIDAQABoAAw
|
||||
DQYJKoZIhvcNAQELBQADggIBAE7VplAZTEGHpYwXZvhlVg0qDsb/7IQj77eNteSU
|
||||
33Dq6u7QLgS+Ea04Xv5BHnhnBoWRtrNR8WLTw64cuj6p/sqXiQsSNDgxNDPuPG+g
|
||||
1FFi6wjgtoIJnx/QrITuUyO/MRy1awKLHlGfbY6yXSdLCC9bqLSIRm0tx+E+jo5C
|
||||
0r5+ZOcLK8ZXWq9uHjmekX0hoN4qzsbQ0J5IeMh9ag+698aqzBSEDljLHg614yiK
|
||||
FxtpD+23O0XfAdgqFgXRLLg3tt8AkVuys7r/uwHoz9du+nwW2U5nsMIYBXLV2mq3
|
||||
1KbpXDTlVwaSoA2LP8dpmvbyTgNbXsjPdS91Rrzd7fcsammcSV0aWPiXmIbTLtn8
|
||||
61ZRR0uj+jB68cRjSvegnheifsGyq6alr8OSUMdeWVyiPy2O7N6fUVj+Fmyzl5Ph
|
||||
fl9UPZTmt/zOZrcSBoWjtZfmQVfw29SfMYwlNKALN4eOT6XwBLDK4uu4UXSoXwi+
|
||||
V8evUUfBWcrcXHMTIFhoZbW/b7gjhnv148XWYI0ta8pjt/akzlPLtf4ETPqfECNN
|
||||
4+p2w9+R5ktzCLeceXQc8eN+ZwjIt31zG48J7Sl1wJB13VR0jPy6zDsyUIswIVfe
|
||||
7gp7GHg8R0lzDpEYCvU+R7RUWK6xcpjt7+mTHM70csnnOg7uPqnXqOdtVplr0y+R
|
||||
pmqJ
|
||||
-----END CERTIFICATE REQUEST-----
|
|
@ -1,5 +0,0 @@
|
|||
#!/bin/sh
|
||||
set -ex
|
||||
|
||||
openssl genrsa -out `dirname "$0"`/rootCA.key 4096
|
||||
openssl req -x509 -new -nodes -key `dirname "$0"`/rootCA.key -sha256 -days 365250 -out `dirname "$0"`/rootCA.crt
|
|
@ -1,6 +0,0 @@
|
|||
#!/bin/sh
|
||||
set -ex
|
||||
|
||||
openssl genrsa -out `dirname "$0"`/staker.key 4096
|
||||
openssl req -new -sha256 -key `dirname "$0"`/staker.key -subj "/C=US/ST=NY/O=Avalabs/CN=ava" -out `dirname "$0"`/staker.csr
|
||||
openssl x509 -req -in `dirname "$0"`/staker.csr -CA `dirname "$0"`/rootCA.crt -CAkey `dirname "$0"`/rootCA.key -CAcreateserial -out `dirname "$0"`/staker.crt -days 365250 -sha256
|
|
@ -1,34 +0,0 @@
|
|||
-----BEGIN CERTIFICATE-----
|
||||
MIIF1jCCA76gAwIBAgIJALI1DF9cpwfEMA0GCSqGSIb3DQEBCwUAMH8xCzAJBgNV
|
||||
BAYTAlVTMQswCQYDVQQIDAJOWTEPMA0GA1UEBwwGSXRoYWNhMRAwDgYDVQQKDAdB
|
||||
dmFsYWJzMQ4wDAYDVQQLDAVHZWNrbzEMMAoGA1UEAwwDYXZhMSIwIAYJKoZIhvcN
|
||||
AQkBFhNzdGVwaGVuQGF2YWxhYnMub3JnMCAXDTE5MDIyODIwNTkyNFoYDzMwMTkw
|
||||
MzA4MjA1OTI0WjB/MQswCQYDVQQGEwJVUzELMAkGA1UECAwCTlkxDzANBgNVBAcM
|
||||
Bkl0aGFjYTEQMA4GA1UECgwHQXZhbGFiczEOMAwGA1UECwwFR2Vja28xDDAKBgNV
|
||||
BAMMA2F2YTEiMCAGCSqGSIb3DQEJARYTc3RlcGhlbkBhdmFsYWJzLm9yZzCCAiIw
|
||||
DQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAJ45ScWV8tsCNO+NTIBuUYsPkhcg
|
||||
jrp0HEyCHY3XEkxsLuDqtesNyv39YA0xQ3M3FP1e29tjFeHWJzyzV8O1H+6yco93
|
||||
QAtzh9xELYD301Yq+x55yZrSjZxNIC5Tmz1ewTfD315lNR04M6JmqjrStIuLsWFU
|
||||
m6P4OgXs4daqnyq9au4PYSrejcbexW59rKxLryK6Acv+E9Ax04oS33g9KqPmlRx0
|
||||
lfu3x4nkIKIl+VaK1wC5CwJDYZ91KpEbC8Z2YvTeVDH+/hz/MvKl1CEaqK/4G5FB
|
||||
KGEyd/bGRxMVQF41G7liJLaXzPLyZnKO2n21ZuJhkA9MZelt1U0LuQU505qU7IzW
|
||||
cmKFEIb1MOrclaF19Is7HQlJWKyDo2/hfjSCZO8zH7eR9EGzKyQwZhwkYCycJD44
|
||||
RKEHq6s/Z2dHUlpLIgRJ7k171TNkL9+xLntu8v1lzTkhemSNeO9asqJ7VcvpnMHH
|
||||
bQXpDxJpi8jTnV8In8EolSqaKeN6/nzwbbSJ7gHehgpDhC1DlXPRzTt/ktQKlNGW
|
||||
T5bdNdvYFyYTd9fu78aJZSbJo8jS2fykWuBgOgnlV8VmwpDa7iHM3EECByhf5GKB
|
||||
J1jBlXO1ZyfJ7sNTbuVM7Uc2JkB4ASKdm3GZ3sFv95HjSTJAUORjE4pQ1es4kfDU
|
||||
KqzDHH+bEHaGIGJTAgMBAAGjUzBRMB0GA1UdDgQWBBQr2T0duSMkvGXe3bSdWcei
|
||||
73QtwzAfBgNVHSMEGDAWgBQr2T0duSMkvGXe3bSdWcei73QtwzAPBgNVHRMBAf8E
|
||||
BTADAQH/MA0GCSqGSIb3DQEBCwUAA4ICAQBpP18zCdzvnSdPigg9wx+a8Znr4aJj
|
||||
FxZYwBY6/BmKb56ke9g+zKKCw2dYYkRYDcTOEfuBgBvNeCSJv4R5rmkukkL8RCIG
|
||||
XV/WfSn2d3Mnz5KTgGQS6Q9s5qx+8ydkiGZthi+8a8ltXczyYrvWgd47U0NWTcOY
|
||||
omjgF6XF+hVLWLgiwmA468pd7wyCsuJJkyxxeyDPXQ422I1AJW/7c5JQQa+lDNsv
|
||||
Vna6420mZ/DiQd3stFkdjhRjmBZvGQ09g6l3zo6TgI1TWr5TMYPrempBVCWPNilC
|
||||
XaMysU77+tPutI+7kMBuGvLuZtPrH/2uTYdXWPodyORm5i2ABF6In3VISPD9YNc0
|
||||
gWx3PYGi2BfdnZepCojsffUMlhT3SsiAKMYv5FhW8LQBNMRR4721U1Vf5f8fzNQn
|
||||
3E55TthV5HXZQ6HcLhkmOvH8CMqtWGETTbBtYSA2AVMjoqs7QDGkfsCH9UuwGd1N
|
||||
W12JOf53XyOQT2XwWerSQC2kv7elsTh6Bk7PhvrCi0OwCVSGny5IQY/aXM1n6Z6s
|
||||
scJlZmq6P3AJZ3tRtBt9yDK7iIW7mzNLTb/kAjsNQh06oETJIJ0CIgL0Bn6CANYU
|
||||
kNqB4oTxmAhdOPKNgqaIwdZAL1VDIVaQEcvGeZRduo7yZvA/MhuQD8IIKSeOBFaD
|
||||
DB8IRfWqBx2nWw==
|
||||
-----END CERTIFICATE-----
|
|
@ -1,51 +0,0 @@
|
|||
-----BEGIN RSA PRIVATE KEY-----
|
||||
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
|
||||
-----END RSA PRIVATE KEY-----
|
|
@ -1 +0,0 @@
|
|||
BAF3B5C5C6D0D14A
|
|
@ -1,27 +0,0 @@
|
|||
-----BEGIN CERTIFICATE REQUEST-----
|
||||
MIIEfzCCAmcCAQAwOjELMAkGA1UEBhMCVVMxCzAJBgNVBAgMAk5ZMRAwDgYDVQQK
|
||||
DAdBdmFsYWJzMQwwCgYDVQQDDANhdmEwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAw
|
||||
ggIKAoICAQDdToR60na6NuR9iSAUMyzPXJNMWVQbLyT5/iZCiJ3BB4YWMBhfxpJW
|
||||
JiWXcM+znDgpJuyCEeh5Dp6ZY3Fe7k6Hht6FmFpDjwnjpQmdkEKUg00G+ElPTp/U
|
||||
smsPL+JAswPqBZWpMBS3dsXQNunMMtMGlrf5S0l6XX4y7kc/GTxYgveWZ9JtR/m2
|
||||
KNer+wjgBHqJ4rPqnHB30sDYPZg91Cz1Ak8Bb2w2I108zQVgKK6eIqNKXJJ/4piz
|
||||
SZdU4920wMxYBpnfDAchnxei9U/v3QbT7eKUI2fGr+hOWTIWU80+VeOBt8a6P4sS
|
||||
9AQh5/6G8qwmAqO3YQ9dxN82iu/H3+N+GGa/M0r5rEWrzwIuFhwKvyQcpPRBm2yQ
|
||||
nBnhL9G5kN6n4OBM0KsgZ3CYlHZSg4eWcNgBt1WCFsQc7vfUFaJnr8QP3pF4V/4B
|
||||
ok7wTO5HN0A1EYEVYuX53NGnrKVe+Fg9+xMOgXPWkUNqdvpI9ZbV3Z0S5866qF3/
|
||||
vBZrhgCrKc5E/vMexBRe8Ki4wKqONVhi9WGUcRHvFEikc+7VrPj0YaG6zVLd+uOA
|
||||
JN81fKOPYo4X4sZrMyPYl3OjGtMhfV4KvCaLEr1duOklqO6cCvGQ8iAlLVy3VJyW
|
||||
5GJ0D0KyiAir4VNdAJKo1ZgiGivJLWulTfjUifCN9o115AiqJxiqwwIDAQABoAAw
|
||||
DQYJKoZIhvcNAQELBQADggIBAM2IHKsQsebxTD50QQXtSNbyRzG/GpMZuZXn/QYO
|
||||
QGW0ThJwtcmx6cqQvuyBovH5WhB9QUBFjiKkR7Qef7HUsgxU1cJA75gBfb2GMUru
|
||||
Q+T37xOxtr6S2TcKOq/LvdJaTYmAHmW9V7vwEcrMRa9lWVTEmJIKTuxiUubpXtup
|
||||
8OB8WLIvDikVtKtegvl6VCaTApCkUfuLhf7DERQ6sGLXWz6dVQcfvbfcXK2fn1Ik
|
||||
Koxqy1SSz/rPb4u9NEk1yqvJQdpgnbTM3drTPHiIHCA7F6SjMu5tekHtVQkFOd6c
|
||||
B0geEwyxY97zqnFv5YXiukXEaAnCRAlOuIZXRqtK6GFthTWo33YpB2KaRUtJ7IuP
|
||||
og4Q/zjDs8DEc/qbbUbhyulExz6uoyRKO4j/gG3ESC6j09j7Eungt1LDhyt8p3wD
|
||||
pytIIPkTseykO0CcEpEcGbES6d3u4PrFJ75XWxMkNZVK8mC3faxx2kJLfS1+4Fg8
|
||||
A0zbcN6qwm1ezGq2vGQcyVKyFVWJQAEAFuSO8sjW6dk3ClfE+MNGUvxTQMe96V14
|
||||
jGRICCp9aJrJXA3u0iQaUX0cXmlhegAYk7Ho/Ef3k/PcP8DzZ8Ck839oRHBw4pPv
|
||||
tKbyiKnOcet7AFGwsiM2t5VLrj4jovhRLEiaXrCaxNe6j4xs63TEb+8uTCzKyktC
|
||||
4BFq
|
||||
-----END CERTIFICATE REQUEST-----
|
|
@ -1,5 +0,0 @@
|
|||
#!/bin/sh
|
||||
set -ex
|
||||
|
||||
openssl genrsa -out `dirname "$0"`/rootCA.key 4096
|
||||
openssl req -x509 -new -nodes -key `dirname "$0"`/rootCA.key -sha256 -days 365250 -out `dirname "$0"`/rootCA.crt
|
|
@ -1,6 +0,0 @@
|
|||
#!/bin/sh
|
||||
set -ex
|
||||
|
||||
openssl genrsa -out `dirname "$0"`/staker.key 4096
|
||||
openssl req -new -sha256 -key `dirname "$0"`/staker.key -subj "/C=US/ST=NY/O=Avalabs/CN=ava" -out `dirname "$0"`/staker.csr
|
||||
openssl x509 -req -in `dirname "$0"`/staker.csr -CA `dirname "$0"`/rootCA.crt -CAkey `dirname "$0"`/rootCA.key -CAcreateserial -out `dirname "$0"`/staker.crt -days 365250 -sha256
|
|
@ -1,34 +0,0 @@
|
|||
-----BEGIN CERTIFICATE-----
|
||||
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
|
||||
DB8IRfWqBx2nWw==
|
||||
-----END CERTIFICATE-----
|
|
@ -1,51 +0,0 @@
|
|||
-----BEGIN RSA PRIVATE KEY-----
|
||||
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
|
||||
-----END RSA PRIVATE KEY-----
|
|
@ -1 +0,0 @@
|
|||
BAF3B5C5C6D0D14A
|
|
@ -1,27 +0,0 @@
|
|||
-----BEGIN CERTIFICATE REQUEST-----
|
||||
MIIEfzCCAmcCAQAwOjELMAkGA1UEBhMCVVMxCzAJBgNVBAgMAk5ZMRAwDgYDVQQK
|
||||
DAdBdmFsYWJzMQwwCgYDVQQDDANhdmEwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAw
|
||||
ggIKAoICAQC8mVDToHbkUF2gRdVfpydZLNKeQ38d6HZFkUM3U1dWLZFSZNvagN8h
|
||||
lQvY/tQu3A40p19WgKbzWZre3tg1Akw8Jztdz9gl4RMn142IIO3CiwIptkE0Jopb
|
||||
ZhmG5fAC2n/MXQtfieI3hzeR04LW4JgLKzf3Nn8xZdlBgJfBmL5qUUnE7O7IbJGG
|
||||
ma6gSD3ewetE6KQZtNtf0xRIv08doZKYwTl6ItkdGK76ufqq098GVwWvA1wSune4
|
||||
+MFgs9N4eFJj6Jyt85fiK/cwPx7KRdgYgBzrZQ4EPshRnwWrBTieOOaJvAA2RMxM
|
||||
EYzKRrJAAsYI1zxtNyqIUaBTcxmaz+NXUGW+wHwITic0Gp/XQm2Lwr/lxIV6OnAl
|
||||
L3CgbSXirSnoG+eHQ+vDzBAcRDkTAgv/GUIzlfqT2StTK02uIBgJYzvFTG4plHit
|
||||
ccRfy8wxsh5Z8xG99lmPQQtLsnlQAV+Li06Cb8CH4hUVoiWiVs5QAahqWmv5fpoX
|
||||
0Es26RyUHXGbjE202pyMMA7jUerUVKMijOoGZtcH6zB4p/dJ0TtToRwOgrA7NCI9
|
||||
AYVtqVXrXG/udj8ur2r1bTVwIbHsOeTEP3gY0mHRWm2E/bLjt9vbYIRUxR8xWnLk
|
||||
beBziNTwg+36jdDF+6gu3cUz/nbSn8YY+Y1jjXuM3lqF8iMaAobhuwIDAQABoAAw
|
||||
DQYJKoZIhvcNAQELBQADggIBAEWU13T1alCni4R36J65TrGfIljW8LGhmWRo5xoV
|
||||
YW7HxxZ/WTAFSwAv0yHCGq+H/tebRZhvua+c+jP16YBDoAp5neGWW57gLDg+35H5
|
||||
guLo73p/qM6hyaUGSfyO9D1nS1QX8R0r70TQYbIrVB4uQeTM2pEYR6NYO7bjPEWr
|
||||
WwC6RnbtnsNGTeoH+LwiM+uY//VB/tUe1u2y6U8HkIXJo7j4+NqUL1xXmYmC6Rph
|
||||
PNI3MAZUL40z1VX7fn/Vp7+rc0CBUsFMOLfLmSgL8jsQeKuyVAQKA4xzWQ2qeuGV
|
||||
Bv24rHbnSxYSu8tMs31LZPn+fsvNWB9iU7MEiTUr+8nAPEAANNaBwaD1EUkzC1WC
|
||||
OcCUpMgkhVuzfHq+eXWnw3cGVvEZ8A4DzOyl1ZFofxBX7IOOv0lmpDQSeEQlmKPF
|
||||
LdWI2JJM76BjeXI7l5HbOmRJv1kYFwBq/biDxCSmmNX8uHvAj1EgDNXvr/pRw7rT
|
||||
6yKOLtk1GSCCrrYQijCXRx2u276+j8MtC5i6FVcUoaSYD+nx2+ApOnZlYR7xsJYw
|
||||
5ECaeDagjHP472FY/fuhy/UwAIFm5gCcVFs3A2M/Iyn+vsAW5WEdh+fwGiWxfw49
|
||||
Y5KRT8u7BD0R5T5UYxYwzYekEzxsoD3bvQGx/4tboSUxkOd7pVymbuGzIsQ18heI
|
||||
78pG
|
||||
-----END CERTIFICATE REQUEST-----
|
|
@ -1,5 +0,0 @@
|
|||
#!/bin/sh
|
||||
set -ex
|
||||
|
||||
openssl genrsa -out `dirname "$0"`/rootCA.key 4096
|
||||
openssl req -x509 -new -nodes -key `dirname "$0"`/rootCA.key -sha256 -days 365250 -out `dirname "$0"`/rootCA.crt
|
|
@ -1,6 +0,0 @@
|
|||
#!/bin/sh
|
||||
set -ex
|
||||
|
||||
openssl genrsa -out `dirname "$0"`/staker.key 4096
|
||||
openssl req -new -sha256 -key `dirname "$0"`/staker.key -subj "/C=US/ST=NY/O=Avalabs/CN=ava" -out `dirname "$0"`/staker.csr
|
||||
openssl x509 -req -in `dirname "$0"`/staker.csr -CA `dirname "$0"`/rootCA.crt -CAkey `dirname "$0"`/rootCA.key -CAcreateserial -out `dirname "$0"`/staker.crt -days 365250 -sha256
|
|
@ -1,34 +0,0 @@
|
|||
-----BEGIN CERTIFICATE-----
|
||||
MIIF1jCCA76gAwIBAgIJALI1DF9cpwfEMA0GCSqGSIb3DQEBCwUAMH8xCzAJBgNV
|
||||
BAYTAlVTMQswCQYDVQQIDAJOWTEPMA0GA1UEBwwGSXRoYWNhMRAwDgYDVQQKDAdB
|
||||
dmFsYWJzMQ4wDAYDVQQLDAVHZWNrbzEMMAoGA1UEAwwDYXZhMSIwIAYJKoZIhvcN
|
||||
AQkBFhNzdGVwaGVuQGF2YWxhYnMub3JnMCAXDTE5MDIyODIwNTkyNFoYDzMwMTkw
|
||||
MzA4MjA1OTI0WjB/MQswCQYDVQQGEwJVUzELMAkGA1UECAwCTlkxDzANBgNVBAcM
|
||||
Bkl0aGFjYTEQMA4GA1UECgwHQXZhbGFiczEOMAwGA1UECwwFR2Vja28xDDAKBgNV
|
||||
BAMMA2F2YTEiMCAGCSqGSIb3DQEJARYTc3RlcGhlbkBhdmFsYWJzLm9yZzCCAiIw
|
||||
DQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAJ45ScWV8tsCNO+NTIBuUYsPkhcg
|
||||
jrp0HEyCHY3XEkxsLuDqtesNyv39YA0xQ3M3FP1e29tjFeHWJzyzV8O1H+6yco93
|
||||
QAtzh9xELYD301Yq+x55yZrSjZxNIC5Tmz1ewTfD315lNR04M6JmqjrStIuLsWFU
|
||||
m6P4OgXs4daqnyq9au4PYSrejcbexW59rKxLryK6Acv+E9Ax04oS33g9KqPmlRx0
|
||||
lfu3x4nkIKIl+VaK1wC5CwJDYZ91KpEbC8Z2YvTeVDH+/hz/MvKl1CEaqK/4G5FB
|
||||
KGEyd/bGRxMVQF41G7liJLaXzPLyZnKO2n21ZuJhkA9MZelt1U0LuQU505qU7IzW
|
||||
cmKFEIb1MOrclaF19Is7HQlJWKyDo2/hfjSCZO8zH7eR9EGzKyQwZhwkYCycJD44
|
||||
RKEHq6s/Z2dHUlpLIgRJ7k171TNkL9+xLntu8v1lzTkhemSNeO9asqJ7VcvpnMHH
|
||||
bQXpDxJpi8jTnV8In8EolSqaKeN6/nzwbbSJ7gHehgpDhC1DlXPRzTt/ktQKlNGW
|
||||
T5bdNdvYFyYTd9fu78aJZSbJo8jS2fykWuBgOgnlV8VmwpDa7iHM3EECByhf5GKB
|
||||
J1jBlXO1ZyfJ7sNTbuVM7Uc2JkB4ASKdm3GZ3sFv95HjSTJAUORjE4pQ1es4kfDU
|
||||
KqzDHH+bEHaGIGJTAgMBAAGjUzBRMB0GA1UdDgQWBBQr2T0duSMkvGXe3bSdWcei
|
||||
73QtwzAfBgNVHSMEGDAWgBQr2T0duSMkvGXe3bSdWcei73QtwzAPBgNVHRMBAf8E
|
||||
BTADAQH/MA0GCSqGSIb3DQEBCwUAA4ICAQBpP18zCdzvnSdPigg9wx+a8Znr4aJj
|
||||
FxZYwBY6/BmKb56ke9g+zKKCw2dYYkRYDcTOEfuBgBvNeCSJv4R5rmkukkL8RCIG
|
||||
XV/WfSn2d3Mnz5KTgGQS6Q9s5qx+8ydkiGZthi+8a8ltXczyYrvWgd47U0NWTcOY
|
||||
omjgF6XF+hVLWLgiwmA468pd7wyCsuJJkyxxeyDPXQ422I1AJW/7c5JQQa+lDNsv
|
||||
Vna6420mZ/DiQd3stFkdjhRjmBZvGQ09g6l3zo6TgI1TWr5TMYPrempBVCWPNilC
|
||||
XaMysU77+tPutI+7kMBuGvLuZtPrH/2uTYdXWPodyORm5i2ABF6In3VISPD9YNc0
|
||||
gWx3PYGi2BfdnZepCojsffUMlhT3SsiAKMYv5FhW8LQBNMRR4721U1Vf5f8fzNQn
|
||||
3E55TthV5HXZQ6HcLhkmOvH8CMqtWGETTbBtYSA2AVMjoqs7QDGkfsCH9UuwGd1N
|
||||
W12JOf53XyOQT2XwWerSQC2kv7elsTh6Bk7PhvrCi0OwCVSGny5IQY/aXM1n6Z6s
|
||||
scJlZmq6P3AJZ3tRtBt9yDK7iIW7mzNLTb/kAjsNQh06oETJIJ0CIgL0Bn6CANYU
|
||||
kNqB4oTxmAhdOPKNgqaIwdZAL1VDIVaQEcvGeZRduo7yZvA/MhuQD8IIKSeOBFaD
|
||||
DB8IRfWqBx2nWw==
|
||||
-----END CERTIFICATE-----
|
|
@ -1,51 +0,0 @@
|
|||
-----BEGIN RSA PRIVATE KEY-----
|
||||
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
|
||||
-----END RSA PRIVATE KEY-----
|
|
@ -1 +0,0 @@
|
|||
BAF3B5C5C6D0D14A
|
|
@ -1,27 +0,0 @@
|
|||
-----BEGIN CERTIFICATE REQUEST-----
|
||||
MIIEfzCCAmcCAQAwOjELMAkGA1UEBhMCVVMxCzAJBgNVBAgMAk5ZMRAwDgYDVQQK
|
||||
DAdBdmFsYWJzMQwwCgYDVQQDDANhdmEwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAw
|
||||
ggIKAoICAQDZnDoDHE2nj82xDjH0Tb7OXMqQDHz+zbLidt6MSI1XB3vOAIEiPqrt
|
||||
enGnqRbVFcm5GZxvxh4YQD8CjKSk1qgZJczs0DPSiGQ8Efl4PGO4xnEbllgL3PUR
|
||||
PWp7mEV3oh6fxICgQKTBlT671EnFzB5lyJWpumRzvA1vyhBMsY8aO+xdq5LUFltY
|
||||
zBdvpgLXVaDwHZQ2PQEWtF0d0JO2N0WFFDGNmx6n8pKSeIAVDsTwZCZK+FCeeEyo
|
||||
GfXsINsc0yCMQslawkfOMqA9yBV3Ji6QmFYKyGYt65MWGNqPA4XrIyliKwCCXwz9
|
||||
mjaWyN7rAyw9cWlLMODNmDORWzGRZ5290MEAEIZsqjYHVitRTM/RnNIadToZGO0y
|
||||
5uAkM14cmTvnsK1CP92qtfSisq75W/I91drThoEtTK78UGOl/5Q1YBR08F+tSUWZ
|
||||
WyHeI6UOBUCGC2bCtmzKMl7vU25lG6mbCR1JuQi6RYpnfMjXH36lV4S7fTvSwwuR
|
||||
03h2F3H1eFkWNG2lbFrW0dzDCPg3lXwmFQ65hUcQhctznoBz5C1lF2eW03wuVgxi
|
||||
nnuVlJHjy/GrqmWsASn1PDuVs4k7k6DJfwyHAiA0uxXrGfxYvp7H8j4+2YOmWiWl
|
||||
5xYgrEDjur5n8Zx46PHQer2Avq3sbEGEe1MCtXJlj3drd5Him3m+NQIDAQABoAAw
|
||||
DQYJKoZIhvcNAQELBQADggIBAMdZKzx/Qz07D/ISgEe10+XofO5It86g12YJBgGN
|
||||
4UEnKNk1quJIs0PAwcDNp7G4BpEMuP5xjyf4q976gzAkTg2kcB+LK85eGGSxkxAt
|
||||
uFQPlFvk85qn4k7wLSx2zkqs47ItvqK5Ev8lLCZ/HfIy+7y57BKqDTvzhXarE3lq
|
||||
bEZketwQvDcQPN7Ho9gxDMMQDeE2NeDyYhQtCMlX8PnmBRhWZ4CExODMdm8TrTJJ
|
||||
5HDoj+fXCaSSbXPN25LKYSKOEM4wtzHa91hQK7JGoeHuSS0zFxDwXNKi3sLLtKTH
|
||||
jsYL/E9bH2NxKPRoHwCJMS0N2jUqnHFyhQUp8VtJlxN0IsPLZGXFapVo4fk2hDpF
|
||||
OapX0kysLV37KEklVHucQclU5SeTpzoS7gYXqvOJ3Q/IFR6CFAkCHaDggWpB/sVm
|
||||
OPG6Pt6XXbGNCav9+Am+0q4UD5O1Sbobx+0XJu3VtnuZdn4Mt0uBSL1DZdG9ceig
|
||||
mGz4bx1kvnzhL1LOAPmxOYqrLCwqJRkRCa+25uRNqBAqWcU48pwoxC3RLyWvy2UN
|
||||
8Or+TsBzPUldq8yWn3s0/zE8yui6pxzpGUD2TfbUT78O0HJKn5nQjrjVdQZhaA4t
|
||||
KnrZCz7lIrHRXf2Hbsg/9QgHhcpkknc98z0trNQHncp/kxUvrBJyJGrUh1DEkOSe
|
||||
f9p0
|
||||
-----END CERTIFICATE REQUEST-----
|
|
@ -1,5 +0,0 @@
|
|||
#!/bin/sh
|
||||
set -ex
|
||||
|
||||
openssl genrsa -out `dirname "$0"`/rootCA.key 4096
|
||||
openssl req -x509 -new -nodes -key `dirname "$0"`/rootCA.key -sha256 -days 365250 -out `dirname "$0"`/rootCA.crt
|
|
@ -1,6 +0,0 @@
|
|||
#!/bin/sh
|
||||
set -ex
|
||||
|
||||
openssl genrsa -out `dirname "$0"`/staker.key 4096
|
||||
openssl req -new -sha256 -key `dirname "$0"`/staker.key -subj "/C=US/ST=NY/O=Avalabs/CN=ava" -out `dirname "$0"`/staker.csr
|
||||
openssl x509 -req -in `dirname "$0"`/staker.csr -CA `dirname "$0"`/rootCA.crt -CAkey `dirname "$0"`/rootCA.key -CAcreateserial -out `dirname "$0"`/staker.crt -days 365250 -sha256
|
|
@ -1,34 +0,0 @@
|
|||
-----BEGIN CERTIFICATE-----
|
||||
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
|
||||
DB8IRfWqBx2nWw==
|
||||
-----END CERTIFICATE-----
|
|
@ -1,51 +0,0 @@
|
|||
-----BEGIN RSA PRIVATE KEY-----
|
||||
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
|
||||
-----END RSA PRIVATE KEY-----
|
|
@ -1 +0,0 @@
|
|||
BAF3B5C5C6D0D14A
|
|
@ -1,27 +0,0 @@
|
|||
-----BEGIN CERTIFICATE REQUEST-----
|
||||
MIIEfzCCAmcCAQAwOjELMAkGA1UEBhMCVVMxCzAJBgNVBAgMAk5ZMRAwDgYDVQQK
|
||||
DAdBdmFsYWJzMQwwCgYDVQQDDANhdmEwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAw
|
||||
ggIKAoICAQDgK5r5vdHtJFEgw7hGE/lzKaHcvwzr32armq0k9tYchJXfT3k1j1lX
|
||||
tBAdcUN3gSRKjgzH/vjbn0ea3AiDCUd2Mck/n0KcJZ43S5I7ZjP7rbav296bKCZ1
|
||||
Hr7r5gXYFhk+3aUsVfDUqAPBwyP8KeV31ARVA/s+WPeWqs69QXTdyJuBYE5pr40v
|
||||
1Sf+ebUInZ37uGY3kiO0Ex/JgcoQsGJzrWD/ztbRCFIvrdNJZd0pGvMlmTKp7XsM
|
||||
R3cpvqk770//MLCdyGW/1IArTSuD1vd7mBX1JyVXKycYN0vIOtbgxPOFutUyqDOe
|
||||
P7o51q4iPS3dCRgfmn/hWLwy+CtJe0BGKsb4tk0tKxo0se8v9JA8mUtnmzmMt4Y9
|
||||
jijOrCOB7XwWKmJYEm8N5Ubcy6cp2oL8vQVtzz3PXrkFt+3cFt1jrjdpQYgH4jyk
|
||||
kWDeOjEfy1FCwzsNRudLTvLhfLn86/ZT4cLZ9JI7/WW0IPC8Fc7lhznJ+bIQUeEn
|
||||
daGdgVkxuEg0MxdrMr0jU0IFoXySRXNRzcDWZShEjBTv7tnFxLmoNU+uJb/KpMH6
|
||||
sRYi3zs85ecaMKNyG+LDmBahUlHx5hKAH49O8855+AMhsg91ONZJldjQX0oZrIKz
|
||||
K5BpsqeTl4c2Yt/fALiZaeFk1pBEsvVeMOBCIuWE+b4UIEaLAOhxfwIDAQABoAAw
|
||||
DQYJKoZIhvcNAQELBQADggIBAMWzSdk6C53ijuLYOt77BAYpxnxRvKA1tsxJd9K5
|
||||
+R+ZGiuTLXWArgClhhwx65OTeqrwkVlh2CZoVTBeEMzvxn6zHO4S20KcWJ1lWU76
|
||||
OIrBZrAecBVXB5LmttUkvlMgVlWLQuVpVJiEn1jW6KeABqWKCLz7Au8TzHfr1HQ4
|
||||
1ukndu3SsKVwSIy0ZHFpQaXvzA8f0V93ap9R2RVw9BXqCJDe+BtQPvlCwOrvQ7d3
|
||||
gg+3aymbqUx3hrscEvd1ETad7LyFw3QfPcr1j1FwPH+K1/UDrWxIzxmO+HM5Lh8f
|
||||
269aYceysgv/xa/KpANTxVAM7j1SE1CjjI5e5CQJVZ+gtAqTIv3lLkk0dWQksObN
|
||||
Z1tTtJkFAUNbGsMadtVeTmx2eBcRi4LEv0DIPyyWUQTWwTYtaMFi8I0bYPk1T/fV
|
||||
9umR6jqZ0l1qdiuLYOSYUx4iI5SAmCrA/kEINOj0u2gqqkxdOgUVsuKqer4w9Iyt
|
||||
qOhhOHwctRo+cIhpVwcF2ouJeNrFqoBzOgHKQxBvcDWJM8ra5GCNIvD3MP4Q63hy
|
||||
b4fkBcYwb1B2ETH9nSDtfW+JLjt70rvf6IxAiXRRiOv4fPzaUlK49NRVgjzx5Iu+
|
||||
8Zq4+I+S6qZOROWsOVSpJu44VvNZd5bMB9dEHnkoGxkPjo8pkC/o0uZbxsnZScSL
|
||||
WGxS
|
||||
-----END CERTIFICATE REQUEST-----
|
|
@ -1,5 +0,0 @@
|
|||
#!/bin/sh
|
||||
set -ex
|
||||
|
||||
openssl genrsa -out `dirname "$0"`/rootCA.key 4096
|
||||
openssl req -x509 -new -nodes -key `dirname "$0"`/rootCA.key -sha256 -days 365250 -out `dirname "$0"`/rootCA.crt
|
|
@ -1,13 +0,0 @@
|
|||
#!/bin/sh
|
||||
set -ex
|
||||
|
||||
keypath=$GOPATH/src/github.com/ava-labs/gecko/keys/mykey
|
||||
|
||||
if test -f "$keypath/staker.key" || test -f "$keypath/staker.crt"; then
|
||||
echo "staker.key or staker.crt already exists. Not generating new key/certificiate."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
openssl genrsa -out `dirname "$0"`/staker.key 4096
|
||||
openssl req -new -sha256 -key `dirname "$0"`/staker.key -subj "/C=US/ST=NY/O=Avalabs/CN=ava" -out `dirname "$0"`/staker.csr
|
||||
openssl x509 -req -in `dirname "$0"`/staker.csr -CA `dirname "$0"`/rootCA.crt -CAkey `dirname "$0"`/rootCA.key -CAcreateserial -out `dirname "$0"`/staker.crt -days 365250 -sha256
|
|
@ -1,34 +0,0 @@
|
|||
-----BEGIN CERTIFICATE-----
|
||||
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
|
||||
DB8IRfWqBx2nWw==
|
||||
-----END CERTIFICATE-----
|
|
@ -1,51 +0,0 @@
|
|||
-----BEGIN RSA PRIVATE KEY-----
|
||||
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
|
||||
-----END RSA PRIVATE KEY-----
|
|
@ -1 +0,0 @@
|
|||
BAF3B5C5C6D0D164
|
|
@ -4,10 +4,11 @@
|
|||
package main
|
||||
|
||||
const (
|
||||
gecko = " ___ ________ __ ___\n" +
|
||||
" / _ \\_/\\ / _____/ ____ ____ | | ______ / _ \\_/\\\n" +
|
||||
" \\/ \\___/ / \\ ____/ __ \\_/ ___\\| |/ / _ \\ \\/ \\___/\n" +
|
||||
" \\ \\_\\ \\ ___/\\ \\___| < <_> )\n" +
|
||||
" \\______ /\\___ >\\___ >__|_ \\____/\n" +
|
||||
" \\/ \\/ \\/ \\/"
|
||||
gecko = "" +
|
||||
` ___ ________ __ ___` + "\n" +
|
||||
` / _ \_/\ / _____/ ____ ____ | | ______ / _ \_/\` + "\n" +
|
||||
` \/ \___/ / \ ____/ __ \_/ ___\| |/ / _ \ \/ \___/` + "\n" +
|
||||
` \ \_\ \ ___/\ \___| < <_> )` + "\n" +
|
||||
` \______ /\___ >\___ >__|_ \____/` + "\n" +
|
||||
` \/ \/ \/ \/`
|
||||
)
|
||||
|
|
52
main/main.go
52
main/main.go
|
@ -7,10 +7,10 @@ import (
|
|||
"fmt"
|
||||
"path"
|
||||
|
||||
"github.com/ava-labs/gecko/nat"
|
||||
"github.com/ava-labs/gecko/node"
|
||||
"github.com/ava-labs/gecko/utils/crypto"
|
||||
"github.com/ava-labs/gecko/utils/logging"
|
||||
"github.com/ava-labs/go-ethereum/p2p/nat"
|
||||
)
|
||||
|
||||
// main is the primary entry point to Ava. This can either create a CLI to an
|
||||
|
@ -40,8 +40,15 @@ func main() {
|
|||
defer log.StopOnPanic()
|
||||
defer Config.DB.Close()
|
||||
|
||||
if Config.StakingIP.IsZero() {
|
||||
log.Warn("NAT traversal has failed. It will be able to connect to less nodes.")
|
||||
}
|
||||
|
||||
// Track if sybil control is enforced
|
||||
if !Config.EnableStaking {
|
||||
if !Config.EnableStaking && Config.EnableP2PTLS {
|
||||
log.Warn("Staking is disabled. Sybil control is not enforced.")
|
||||
}
|
||||
if !Config.EnableStaking && !Config.EnableP2PTLS {
|
||||
log.Warn("Staking and p2p encryption are disabled. Packet spoofing is possible.")
|
||||
}
|
||||
|
||||
|
@ -58,45 +65,26 @@ func main() {
|
|||
|
||||
// Track if assertions should be executed
|
||||
if Config.LoggingConfig.Assertions {
|
||||
log.Warn("assertions are enabled. This may slow down execution")
|
||||
log.Debug("assertions are enabled. This may slow down execution")
|
||||
}
|
||||
|
||||
natChan := make(chan struct{})
|
||||
defer close(natChan)
|
||||
mapper := nat.NewDefaultMapper(log, Config.Nat, nat.TCP, "gecko")
|
||||
defer mapper.UnmapAllPorts()
|
||||
|
||||
go nat.Map(
|
||||
/*nat=*/ Config.Nat,
|
||||
/*closeChannel=*/ natChan,
|
||||
/*protocol=*/ "TCP",
|
||||
/*internetPort=*/ int(Config.StakingIP.Port),
|
||||
/*localPort=*/ int(Config.StakingIP.Port),
|
||||
/*name=*/ "Gecko Staking Server",
|
||||
)
|
||||
mapper.MapPort(Config.StakingIP.Port, Config.StakingIP.Port)
|
||||
mapper.MapPort(Config.HTTPPort, Config.HTTPPort)
|
||||
|
||||
go nat.Map(
|
||||
/*nat=*/ Config.Nat,
|
||||
/*closeChannel=*/ natChan,
|
||||
/*protocol=*/ "TCP",
|
||||
/*internetPort=*/ int(Config.HTTPPort),
|
||||
/*localPort=*/ int(Config.HTTPPort),
|
||||
/*name=*/ "Gecko HTTP Server",
|
||||
)
|
||||
node := node.Node{}
|
||||
|
||||
log.Debug("initializing node state")
|
||||
// MainNode is a global variable in the node.go file
|
||||
if err := node.MainNode.Initialize(&Config, log, factory); err != nil {
|
||||
if err := node.Initialize(&Config, log, factory); err != nil {
|
||||
log.Fatal("error initializing node state: %s", err)
|
||||
return
|
||||
}
|
||||
|
||||
log.Debug("Starting servers")
|
||||
if err := node.MainNode.StartConsensusServer(); err != nil {
|
||||
log.Fatal("problem starting servers: %s", err)
|
||||
return
|
||||
}
|
||||
defer node.Shutdown()
|
||||
|
||||
defer node.MainNode.Shutdown()
|
||||
|
||||
log.Debug("Dispatching node handlers")
|
||||
node.MainNode.Dispatch()
|
||||
log.Debug("dispatching node handlers")
|
||||
err = node.Dispatch()
|
||||
log.Debug("node dispatching returned with %s", err)
|
||||
}
|
||||
|
|
347
main/params.go
347
main/params.go
|
@ -8,169 +8,360 @@ import (
|
|||
"flag"
|
||||
"fmt"
|
||||
"net"
|
||||
"os"
|
||||
"path"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
"github.com/ava-labs/go-ethereum/p2p/nat"
|
||||
|
||||
"github.com/ava-labs/gecko/database/leveldb"
|
||||
"github.com/ava-labs/gecko/database/memdb"
|
||||
"github.com/ava-labs/gecko/genesis"
|
||||
"github.com/ava-labs/gecko/ids"
|
||||
"github.com/ava-labs/gecko/nat"
|
||||
"github.com/ava-labs/gecko/node"
|
||||
"github.com/ava-labs/gecko/snow/networking/router"
|
||||
"github.com/ava-labs/gecko/staking"
|
||||
"github.com/ava-labs/gecko/utils"
|
||||
"github.com/ava-labs/gecko/utils/formatting"
|
||||
"github.com/ava-labs/gecko/utils/hashing"
|
||||
"github.com/ava-labs/gecko/utils/logging"
|
||||
"github.com/ava-labs/gecko/utils/random"
|
||||
"github.com/ava-labs/gecko/utils/wrappers"
|
||||
)
|
||||
|
||||
const (
|
||||
dbVersion = "v0.5.0"
|
||||
)
|
||||
|
||||
// Results of parsing the CLI
|
||||
var (
|
||||
Config = node.Config{}
|
||||
Err error
|
||||
Config = node.Config{}
|
||||
Err error
|
||||
defaultNetworkName = genesis.TestnetName
|
||||
defaultDbDir = os.ExpandEnv(filepath.Join("$HOME", ".gecko", "db"))
|
||||
defaultStakingKeyPath = os.ExpandEnv(filepath.Join("$HOME", ".gecko", "staking", "staker.key"))
|
||||
defaultStakingCertPath = os.ExpandEnv(filepath.Join("$HOME", ".gecko", "staking", "staker.crt"))
|
||||
|
||||
defaultPluginDirs = []string{
|
||||
"./build/plugins",
|
||||
"./plugins",
|
||||
os.ExpandEnv(filepath.Join("$HOME", ".gecko", "plugins")),
|
||||
}
|
||||
)
|
||||
|
||||
var (
|
||||
errBootstrapMismatch = errors.New("more bootstrap IDs provided than bootstrap IPs")
|
||||
errBootstrapMismatch = errors.New("more bootstrap IDs provided than bootstrap IPs")
|
||||
errStakingRequiresTLS = errors.New("if staking is enabled, network TLS must also be enabled")
|
||||
)
|
||||
|
||||
// GetIPs returns the default IPs for each network
|
||||
func GetIPs(networkID uint32) []string {
|
||||
switch networkID {
|
||||
case genesis.DenaliID:
|
||||
return []string{
|
||||
"18.188.121.35:21001",
|
||||
"3.133.83.66:21001",
|
||||
"3.15.206.239:21001",
|
||||
"18.224.140.156:21001",
|
||||
"3.133.131.39:21001",
|
||||
"18.191.29.54:21001",
|
||||
"18.224.172.110:21001",
|
||||
"18.223.211.203:21001",
|
||||
"18.216.130.143:21001",
|
||||
"18.223.184.147:21001",
|
||||
"52.15.48.84:21001",
|
||||
"18.189.194.220:21001",
|
||||
"18.223.119.104:21001",
|
||||
"3.133.155.41:21001",
|
||||
"13.58.170.174:21001",
|
||||
"3.21.245.246:21001",
|
||||
"52.15.190.149:21001",
|
||||
"18.188.95.241:21001",
|
||||
"3.12.197.248:21001",
|
||||
"3.17.39.236:21001",
|
||||
}
|
||||
case genesis.CascadeID:
|
||||
return []string{
|
||||
"3.227.207.132:21001",
|
||||
"34.207.133.167:21001",
|
||||
"54.162.71.9:21001",
|
||||
"54.197.215.186:21001",
|
||||
"18.234.153.22:21001",
|
||||
}
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// GetIDs returns the default IDs for each network
|
||||
func GetIDs(networkID uint32) []string {
|
||||
switch networkID {
|
||||
case genesis.DenaliID:
|
||||
return []string{
|
||||
"NpagUxt6KQiwPch9Sd4osv8kD1TZnkjdk",
|
||||
"2m38qc95mhHXtrhjyGbe7r2NhniqHHJRB",
|
||||
"LQwRLm4cbJ7T2kxcxp4uXCU5XD8DFrE1C",
|
||||
"hArafGhY2HFTbwaaVh1CSCUCUCiJ2Vfb",
|
||||
"4QBwET5o8kUhvt9xArhir4d3R25CtmZho",
|
||||
"HGZ8ae74J3odT8ESreAdCtdnvWG1J4X5n",
|
||||
"4KXitMCoE9p2BHA6VzXtaTxLoEjNDo2Pt",
|
||||
"JyE4P8f4cTryNV8DCz2M81bMtGhFFHexG",
|
||||
"EzGaipqomyK9UKx9DBHV6Ky3y68hoknrF",
|
||||
"CYKruAjwH1BmV3m37sXNuprbr7dGQuJwG",
|
||||
"LegbVf6qaMKcsXPnLStkdc1JVktmmiDxy",
|
||||
"FesGqwKq7z5nPFHa5iwZctHE5EZV9Lpdq",
|
||||
"BFa1padLXBj7VHa2JYvYGzcTBPQGjPhUy",
|
||||
"4B4rc5vdD1758JSBYL1xyvE5NHGzz6xzH",
|
||||
"EDESh4DfZFC15i613pMtWniQ9arbBZRnL",
|
||||
"CZmZ9xpCzkWqjAyS7L4htzh5Lg6kf1k18",
|
||||
"CTtkcXvVdhpNp6f97LEUXPwsRD3A2ZHqP",
|
||||
"84KbQHSDnojroCVY7vQ7u9Tx7pUonPaS",
|
||||
"JjvzhxnLHLUQ5HjVRkvG827ivbLXPwA9u",
|
||||
"4CWTbdvgXHY1CLXqQNAp22nJDo5nAmts6",
|
||||
}
|
||||
case genesis.CascadeID:
|
||||
return []string{
|
||||
"NX4zVkuiRJZYe6Nzzav7GXN3TakUet3Co",
|
||||
"CMsa8cMw4eib1Hb8GG4xiUKAq5eE1BwUX",
|
||||
"DsMP6jLhi1MkDVc3qx9xx9AAZWx8e87Jd",
|
||||
"N86eodVZja3GEyZJTo3DFUPGpxEEvjGHs",
|
||||
"EkKeGSLUbHrrtuayBtbwgWDRUiAziC3ao",
|
||||
}
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// GetDefaultBootstraps returns the default bootstraps this node should connect
|
||||
// to
|
||||
func GetDefaultBootstraps(networkID uint32, count int) ([]string, []string) {
|
||||
ips := GetIPs(networkID)
|
||||
ids := GetIDs(networkID)
|
||||
|
||||
if numIPs := len(ips); numIPs < count {
|
||||
count = numIPs
|
||||
}
|
||||
|
||||
sampledIPs := make([]string, 0, count)
|
||||
sampledIDs := make([]string, 0, count)
|
||||
|
||||
sampler := random.Uniform{N: len(ips)}
|
||||
for i := 0; i < count; i++ {
|
||||
i := sampler.Sample()
|
||||
sampledIPs = append(sampledIPs, ips[i])
|
||||
sampledIDs = append(sampledIDs, ids[i])
|
||||
}
|
||||
|
||||
return sampledIPs, sampledIDs
|
||||
}
|
||||
|
||||
// Parse the CLI arguments
|
||||
func init() {
|
||||
errs := &wrappers.Errs{}
|
||||
defer func() { Err = errs.Err }()
|
||||
|
||||
loggingConfig, err := logging.DefaultConfig()
|
||||
errs.Add(err)
|
||||
if errs.Add(err); errs.Errored() {
|
||||
return
|
||||
}
|
||||
|
||||
fs := flag.NewFlagSet("gecko", flag.ContinueOnError)
|
||||
|
||||
// If this is true, print the version and quit.
|
||||
version := fs.Bool("version", false, "If true, print version and quit")
|
||||
|
||||
// NetworkID:
|
||||
networkName := flag.String("network-id", genesis.LocalName, "Network ID this node will connect to")
|
||||
networkName := fs.String("network-id", defaultNetworkName, "Network ID this node will connect to")
|
||||
|
||||
// Ava fees:
|
||||
flag.Uint64Var(&Config.AvaTxFee, "ava-tx-fee", 0, "Ava transaction fee, in $nAva")
|
||||
fs.Uint64Var(&Config.AvaTxFee, "ava-tx-fee", 0, "Ava transaction fee, in $nAva")
|
||||
|
||||
// Assertions:
|
||||
flag.BoolVar(&loggingConfig.Assertions, "assertions-enabled", true, "Turn on assertion execution")
|
||||
fs.BoolVar(&loggingConfig.Assertions, "assertions-enabled", true, "Turn on assertion execution")
|
||||
|
||||
// Crypto:
|
||||
flag.BoolVar(&Config.EnableCrypto, "signature-verification-enabled", true, "Turn on signature verification")
|
||||
fs.BoolVar(&Config.EnableCrypto, "signature-verification-enabled", true, "Turn on signature verification")
|
||||
|
||||
// Database:
|
||||
db := flag.Bool("db-enabled", true, "Turn on persistent storage")
|
||||
dbDir := flag.String("db-dir", "db", "Database directory for Ava state")
|
||||
db := fs.Bool("db-enabled", true, "Turn on persistent storage")
|
||||
dbDir := fs.String("db-dir", defaultDbDir, "Database directory for Ava state")
|
||||
|
||||
// IP:
|
||||
consensusIP := flag.String("public-ip", "", "Public IP of this node")
|
||||
consensusIP := fs.String("public-ip", "", "Public IP of this node")
|
||||
|
||||
// HTTP Server:
|
||||
httpPort := flag.Uint("http-port", 9650, "Port of the HTTP server")
|
||||
flag.BoolVar(&Config.EnableHTTPS, "http-tls-enabled", false, "Upgrade the HTTP server to HTTPs")
|
||||
flag.StringVar(&Config.HTTPSKeyFile, "http-tls-key-file", "", "TLS private key file for the HTTPs server")
|
||||
flag.StringVar(&Config.HTTPSCertFile, "http-tls-cert-file", "", "TLS certificate file for the HTTPs server")
|
||||
httpHost := fs.String("http-host", "", "Address of the HTTP server")
|
||||
httpPort := fs.Uint("http-port", 9650, "Port of the HTTP server")
|
||||
fs.BoolVar(&Config.EnableHTTPS, "http-tls-enabled", false, "Upgrade the HTTP server to HTTPs")
|
||||
fs.StringVar(&Config.HTTPSKeyFile, "http-tls-key-file", "", "TLS private key file for the HTTPs server")
|
||||
fs.StringVar(&Config.HTTPSCertFile, "http-tls-cert-file", "", "TLS certificate file for the HTTPs server")
|
||||
|
||||
// Bootstrapping:
|
||||
bootstrapIPs := flag.String("bootstrap-ips", "", "Comma separated list of bootstrap peer ips to connect to. Example: 127.0.0.1:9630,127.0.0.1:9631")
|
||||
bootstrapIDs := flag.String("bootstrap-ids", "", "Comma separated list of bootstrap peer ids to connect to. Example: JR4dVmy6ffUGAKCBDkyCbeZbyHQBeDsET,8CrVPQZ4VSqgL8zTdvL14G8HqAfrBr4z")
|
||||
bootstrapIPs := fs.String("bootstrap-ips", "default", "Comma separated list of bootstrap peer ips to connect to. Example: 127.0.0.1:9630,127.0.0.1:9631")
|
||||
bootstrapIDs := fs.String("bootstrap-ids", "default", "Comma separated list of bootstrap peer ids to connect to. Example: JR4dVmy6ffUGAKCBDkyCbeZbyHQBeDsET,8CrVPQZ4VSqgL8zTdvL14G8HqAfrBr4z")
|
||||
|
||||
// Staking:
|
||||
consensusPort := flag.Uint("staking-port", 9651, "Port of the consensus server")
|
||||
flag.BoolVar(&Config.EnableStaking, "staking-tls-enabled", true, "Require TLS to authenticate staking connections")
|
||||
flag.StringVar(&Config.StakingKeyFile, "staking-tls-key-file", "", "TLS private key file for staking connections")
|
||||
flag.StringVar(&Config.StakingCertFile, "staking-tls-cert-file", "", "TLS certificate file for staking connections")
|
||||
consensusPort := fs.Uint("staking-port", 9651, "Port of the consensus server")
|
||||
// TODO - keeping same flag for backwards compatibility, should be changed to "staking-enabled"
|
||||
fs.BoolVar(&Config.EnableStaking, "staking-tls-enabled", true, "Enable staking. If enabled, Network TLS is required.")
|
||||
fs.BoolVar(&Config.EnableP2PTLS, "p2p-tls-enabled", true, "Require TLS to authenticate network communication")
|
||||
fs.StringVar(&Config.StakingKeyFile, "staking-tls-key-file", defaultStakingKeyPath, "TLS private key for staking")
|
||||
fs.StringVar(&Config.StakingCertFile, "staking-tls-cert-file", defaultStakingCertPath, "TLS certificate for staking")
|
||||
|
||||
// Plugins:
|
||||
fs.StringVar(&Config.PluginDir, "plugin-dir", defaultPluginDirs[0], "Plugin directory for Ava VMs")
|
||||
|
||||
// Logging:
|
||||
logsDir := flag.String("log-dir", "", "Logging directory for Ava")
|
||||
logLevel := flag.String("log-level", "info", "The log level. Should be one of {verbo, debug, info, warn, error, fatal, off}")
|
||||
logDisplayLevel := flag.String("log-display-level", "", "The log display level. If left blank, will inherit the value of log-level. Otherwise, should be one of {verbo, debug, info, warn, error, fatal, off}")
|
||||
logsDir := fs.String("log-dir", "", "Logging directory for Ava")
|
||||
logLevel := fs.String("log-level", "info", "The log level. Should be one of {verbo, debug, info, warn, error, fatal, off}")
|
||||
logDisplayLevel := fs.String("log-display-level", "", "The log display level. If left blank, will inherit the value of log-level. Otherwise, should be one of {verbo, debug, info, warn, error, fatal, off}")
|
||||
|
||||
flag.IntVar(&Config.ConsensusParams.K, "snow-sample-size", 20, "Number of nodes to query for each network poll")
|
||||
flag.IntVar(&Config.ConsensusParams.Alpha, "snow-quorum-size", 18, "Alpha value to use for required number positive results")
|
||||
flag.IntVar(&Config.ConsensusParams.BetaVirtuous, "snow-virtuous-commit-threshold", 20, "Beta value to use for virtuous transactions")
|
||||
flag.IntVar(&Config.ConsensusParams.BetaRogue, "snow-rogue-commit-threshold", 30, "Beta value to use for rogue transactions")
|
||||
flag.IntVar(&Config.ConsensusParams.Parents, "snow-avalanche-num-parents", 5, "Number of vertexes for reference from each new vertex")
|
||||
flag.IntVar(&Config.ConsensusParams.BatchSize, "snow-avalanche-batch-size", 30, "Number of operations to batch in each new vertex")
|
||||
fs.IntVar(&Config.ConsensusParams.K, "snow-sample-size", 5, "Number of nodes to query for each network poll")
|
||||
fs.IntVar(&Config.ConsensusParams.Alpha, "snow-quorum-size", 4, "Alpha value to use for required number positive results")
|
||||
fs.IntVar(&Config.ConsensusParams.BetaVirtuous, "snow-virtuous-commit-threshold", 20, "Beta value to use for virtuous transactions")
|
||||
fs.IntVar(&Config.ConsensusParams.BetaRogue, "snow-rogue-commit-threshold", 30, "Beta value to use for rogue transactions")
|
||||
fs.IntVar(&Config.ConsensusParams.Parents, "snow-avalanche-num-parents", 5, "Number of vertexes for reference from each new vertex")
|
||||
fs.IntVar(&Config.ConsensusParams.BatchSize, "snow-avalanche-batch-size", 30, "Number of operations to batch in each new vertex")
|
||||
fs.IntVar(&Config.ConsensusParams.ConcurrentRepolls, "snow-concurrent-repolls", 1, "Minimum number of concurrent polls for finalizing consensus")
|
||||
|
||||
// Enable/Disable APIs:
|
||||
flag.BoolVar(&Config.AdminAPIEnabled, "api-admin-enabled", true, "If true, this node exposes the Admin API")
|
||||
flag.BoolVar(&Config.KeystoreAPIEnabled, "api-keystore-enabled", true, "If true, this node exposes the Keystore API")
|
||||
flag.BoolVar(&Config.MetricsAPIEnabled, "api-metrics-enabled", true, "If true, this node exposes the Metrics API")
|
||||
flag.BoolVar(&Config.IPCEnabled, "api-ipcs-enabled", false, "If true, IPCs can be opened")
|
||||
fs.BoolVar(&Config.AdminAPIEnabled, "api-admin-enabled", true, "If true, this node exposes the Admin API")
|
||||
fs.BoolVar(&Config.KeystoreAPIEnabled, "api-keystore-enabled", true, "If true, this node exposes the Keystore API")
|
||||
fs.BoolVar(&Config.MetricsAPIEnabled, "api-metrics-enabled", true, "If true, this node exposes the Metrics API")
|
||||
fs.BoolVar(&Config.HealthAPIEnabled, "api-health-enabled", true, "If true, this node exposes the Health API")
|
||||
fs.BoolVar(&Config.IPCEnabled, "api-ipcs-enabled", false, "If true, IPCs can be opened")
|
||||
|
||||
// Throughput Server
|
||||
throughputPort := flag.Uint("xput-server-port", 9652, "Port of the deprecated throughput test server")
|
||||
flag.BoolVar(&Config.ThroughputServerEnabled, "xput-server-enabled", false, "If true, throughput test server is created")
|
||||
throughputPort := fs.Uint("xput-server-port", 9652, "Port of the deprecated throughput test server")
|
||||
fs.BoolVar(&Config.ThroughputServerEnabled, "xput-server-enabled", false, "If true, throughput test server is created")
|
||||
|
||||
flag.Parse()
|
||||
ferr := fs.Parse(os.Args[1:])
|
||||
|
||||
if *version { // If --version used, print version and exit
|
||||
networkID, err := genesis.NetworkID(defaultNetworkName)
|
||||
if errs.Add(err); err != nil {
|
||||
return
|
||||
}
|
||||
networkGeneration := genesis.NetworkName(networkID)
|
||||
fmt.Printf(
|
||||
"%s [database=%s, network=%s/%s]\n",
|
||||
node.Version, dbVersion, defaultNetworkName, networkGeneration,
|
||||
)
|
||||
os.Exit(0)
|
||||
}
|
||||
|
||||
if ferr == flag.ErrHelp {
|
||||
// display usage/help text and exit successfully
|
||||
os.Exit(0)
|
||||
}
|
||||
|
||||
if ferr != nil {
|
||||
// other type of error occurred when parsing args
|
||||
os.Exit(2)
|
||||
}
|
||||
|
||||
networkID, err := genesis.NetworkID(*networkName)
|
||||
errs.Add(err)
|
||||
|
||||
if networkID != genesis.LocalID {
|
||||
errs.Add(fmt.Errorf("the only supported networkID is: %s", genesis.LocalName))
|
||||
if errs.Add(err); err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
Config.NetworkID = networkID
|
||||
|
||||
// DB:
|
||||
if *db && err == nil {
|
||||
// TODO: Add better params here
|
||||
dbPath := path.Join(*dbDir, genesis.NetworkName(Config.NetworkID))
|
||||
if *db {
|
||||
*dbDir = os.ExpandEnv(*dbDir) // parse any env variables
|
||||
dbPath := path.Join(*dbDir, genesis.NetworkName(Config.NetworkID), dbVersion)
|
||||
db, err := leveldb.New(dbPath, 0, 0, 0)
|
||||
if err != nil {
|
||||
errs.Add(fmt.Errorf("couldn't create db at %s: %w", dbPath, err))
|
||||
return
|
||||
}
|
||||
Config.DB = db
|
||||
errs.Add(err)
|
||||
} else {
|
||||
Config.DB = memdb.New()
|
||||
}
|
||||
|
||||
Config.Nat = nat.Any()
|
||||
Config.Nat = nat.NewRouter()
|
||||
|
||||
var ip net.IP
|
||||
// If public IP is not specified, get it using shell command dig
|
||||
if *consensusIP == "" {
|
||||
ip, err = Config.Nat.ExternalIP()
|
||||
errs.Add(fmt.Errorf("%s\nIf you are trying to create a local network, try adding --public-ip=127.0.0.1", err))
|
||||
ip, err = Config.Nat.IP()
|
||||
if err != nil {
|
||||
ip = net.IPv4zero // Couldn't get my IP...set to 0.0.0.0
|
||||
}
|
||||
} else {
|
||||
ip = net.ParseIP(*consensusIP)
|
||||
}
|
||||
|
||||
if ip == nil {
|
||||
errs.Add(fmt.Errorf("Invalid IP Address %s", *consensusIP))
|
||||
return
|
||||
}
|
||||
|
||||
Config.StakingIP = utils.IPDesc{
|
||||
IP: ip,
|
||||
Port: uint16(*consensusPort),
|
||||
}
|
||||
|
||||
defaultBootstrapIPs, defaultBootstrapIDs := GetDefaultBootstraps(networkID, 5)
|
||||
|
||||
// Bootstrapping:
|
||||
if *bootstrapIPs == "default" {
|
||||
*bootstrapIPs = strings.Join(defaultBootstrapIPs, ",")
|
||||
}
|
||||
for _, ip := range strings.Split(*bootstrapIPs, ",") {
|
||||
if ip != "" {
|
||||
addr, err := utils.ToIPDesc(ip)
|
||||
errs.Add(err)
|
||||
if err != nil {
|
||||
errs.Add(fmt.Errorf("couldn't parse ip: %w", err))
|
||||
return
|
||||
}
|
||||
Config.BootstrapPeers = append(Config.BootstrapPeers, &node.Peer{
|
||||
IP: addr,
|
||||
})
|
||||
}
|
||||
}
|
||||
if Config.EnableStaking {
|
||||
|
||||
if *bootstrapIDs == "default" {
|
||||
if *bootstrapIPs == "" {
|
||||
*bootstrapIDs = ""
|
||||
} else {
|
||||
*bootstrapIDs = strings.Join(defaultBootstrapIDs, ",")
|
||||
}
|
||||
}
|
||||
|
||||
if Config.EnableStaking && !Config.EnableP2PTLS {
|
||||
errs.Add(errStakingRequiresTLS)
|
||||
return
|
||||
}
|
||||
|
||||
if Config.EnableP2PTLS {
|
||||
i := 0
|
||||
cb58 := formatting.CB58{}
|
||||
for _, id := range strings.Split(*bootstrapIDs, ",") {
|
||||
if id != "" {
|
||||
errs.Add(cb58.FromString(id))
|
||||
cert, err := ids.ToShortID(cb58.Bytes)
|
||||
errs.Add(err)
|
||||
|
||||
err = cb58.FromString(id)
|
||||
if err != nil {
|
||||
errs.Add(fmt.Errorf("couldn't parse bootstrap peer id to bytes: %w", err))
|
||||
return
|
||||
}
|
||||
peerID, err := ids.ToShortID(cb58.Bytes)
|
||||
if err != nil {
|
||||
errs.Add(fmt.Errorf("couldn't parse bootstrap peer id: %w", err))
|
||||
return
|
||||
}
|
||||
if len(Config.BootstrapPeers) <= i {
|
||||
errs.Add(errBootstrapMismatch)
|
||||
continue
|
||||
return
|
||||
}
|
||||
Config.BootstrapPeers[i].ID = cert
|
||||
Config.BootstrapPeers[i].ID = peerID
|
||||
i++
|
||||
}
|
||||
}
|
||||
if len(Config.BootstrapPeers) != i {
|
||||
errs.Add(fmt.Errorf("More bootstrap IPs, %d, provided than bootstrap IDs, %d", len(Config.BootstrapPeers), i))
|
||||
return
|
||||
}
|
||||
} else {
|
||||
for _, peer := range Config.BootstrapPeers {
|
||||
|
@ -178,7 +369,39 @@ func init() {
|
|||
}
|
||||
}
|
||||
|
||||
// Plugins
|
||||
if _, err := os.Stat(Config.PluginDir); os.IsNotExist(err) {
|
||||
for _, dir := range defaultPluginDirs {
|
||||
if _, err := os.Stat(dir); !os.IsNotExist(err) {
|
||||
Config.PluginDir = dir
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Staking
|
||||
Config.StakingCertFile = os.ExpandEnv(Config.StakingCertFile) // parse any env variable
|
||||
Config.StakingKeyFile = os.ExpandEnv(Config.StakingKeyFile)
|
||||
switch {
|
||||
// If staking key/cert locations are specified but not found, error
|
||||
case Config.StakingKeyFile != defaultStakingKeyPath || Config.StakingCertFile != defaultStakingCertPath:
|
||||
if _, err := os.Stat(Config.StakingKeyFile); os.IsNotExist(err) {
|
||||
errs.Add(fmt.Errorf("couldn't find staking key at %s", Config.StakingKeyFile))
|
||||
return
|
||||
} else if _, err := os.Stat(Config.StakingCertFile); os.IsNotExist(err) {
|
||||
errs.Add(fmt.Errorf("couldn't find staking certificate at %s", Config.StakingCertFile))
|
||||
return
|
||||
}
|
||||
default:
|
||||
// Only creates staking key/cert if [stakingKeyPath] doesn't exist
|
||||
if err := staking.GenerateStakingKeyCert(Config.StakingKeyFile, Config.StakingCertFile); err != nil {
|
||||
errs.Add(fmt.Errorf("couldn't generate staking key/cert: %w", err))
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
// HTTP:
|
||||
Config.HTTPHost = *httpHost
|
||||
Config.HTTPPort = uint16(*httpPort)
|
||||
|
||||
// Logging:
|
||||
|
@ -186,14 +409,18 @@ func init() {
|
|||
loggingConfig.Directory = *logsDir
|
||||
}
|
||||
logFileLevel, err := logging.ToLevel(*logLevel)
|
||||
errs.Add(err)
|
||||
if errs.Add(err); err != nil {
|
||||
return
|
||||
}
|
||||
loggingConfig.LogLevel = logFileLevel
|
||||
|
||||
if *logDisplayLevel == "" {
|
||||
*logDisplayLevel = *logLevel
|
||||
}
|
||||
displayLevel, err := logging.ToLevel(*logDisplayLevel)
|
||||
errs.Add(err)
|
||||
if errs.Add(err); err != nil {
|
||||
return
|
||||
}
|
||||
loggingConfig.DisplayLevel = displayLevel
|
||||
|
||||
Config.LoggingConfig = loggingConfig
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue