Merge branch 'master' into remove-install-warning

This commit is contained in:
StephenButtolph 2020-04-17 03:02:45 -04:00
commit 98ad6dab99
372 changed files with 25077 additions and 8081 deletions

11
.gitignore vendored
View File

@ -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/

View File

@ -6,10 +6,6 @@ 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

View File

@ -51,7 +51,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.)

View File

@ -11,6 +11,7 @@ import (
"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/prefixdb"
@ -21,10 +22,30 @@ 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
// 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,7 +135,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)
ks.log.Verbo("CreateUser called with %.*s", maxUserPassLen, args.Username)
if len(args.Username) > maxUserPassLen || len(args.Password) > maxUserPassLen {
return errUserPassMaxLength
}
if args.Username == "" {
return errEmptyUsername
@ -123,6 +148,10 @@ func (ks *Keystore) CreateUser(_ *http.Request, args *CreateUserArgs, reply *Cre
return fmt.Errorf("user already exists: %s", args.Username)
}
if zxcvbn.PasswordStrength(args.Password, nil).Score < requiredPassScore {
return errWeakPassword
}
usr := &User{}
if err := usr.Initialize(args.Password); err != nil {
return err
@ -174,7 +203,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
@ -214,16 +243,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
@ -242,13 +270,8 @@ func (ks *Keystore) ImportUser(r *http.Request, args *ImportUserArgs, reply *Imp
return fmt.Errorf("user already exists: %s", args.Username)
}
cb58 := formatting.CB58{}
if err := cb58.FromString(args.User); err != nil {
return err
}
userData := UserDB{}
if err := ks.codec.Unmarshal(cb58.Bytes, &userData); err != nil {
if err := ks.codec.Unmarshal(args.User.Bytes, &userData); err != nil {
return err
}
@ -257,22 +280,25 @@ 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
}
// NewBlockchainKeyStore ...

View File

@ -5,6 +5,8 @@ package keystore
import (
"bytes"
"fmt"
"math/rand"
"testing"
"github.com/ava-labs/gecko/database/memdb"
@ -12,6 +14,12 @@ import (
"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())
@ -33,7 +41,7 @@ func TestServiceCreateUser(t *testing.T) {
reply := CreateUserReply{}
if err := ks.CreateUser(nil, &CreateUserArgs{
Username: "bob",
Password: "launch",
Password: strongPassword,
}, &reply); err != nil {
t.Fatal(err)
}
@ -56,6 +64,78 @@ 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 := Keystore{}
ks.Initialize(logging.NoLog{}, memdb.New())
{
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 := Keystore{}
ks.Initialize(logging.NoLog{}, memdb.New())
{
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())
@ -64,7 +144,7 @@ func TestServiceCreateDuplicate(t *testing.T) {
reply := CreateUserReply{}
if err := ks.CreateUser(nil, &CreateUserArgs{
Username: "bob",
Password: "launch",
Password: strongPassword,
}, &reply); err != nil {
t.Fatal(err)
}
@ -77,7 +157,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")
}
@ -90,7 +170,7 @@ func TestServiceCreateUserNoName(t *testing.T) {
reply := CreateUserReply{}
if err := ks.CreateUser(nil, &CreateUserArgs{
Password: "launch",
Password: strongPassword,
}, &reply); err == nil {
t.Fatalf("Shouldn't have allowed empty username")
}
@ -104,7 +184,7 @@ func TestServiceUseBlockchainDB(t *testing.T) {
reply := CreateUserReply{}
if err := ks.CreateUser(nil, &CreateUserArgs{
Username: "bob",
Password: "launch",
Password: strongPassword,
}, &reply); err != nil {
t.Fatal(err)
}
@ -114,7 +194,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 +204,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)
}
@ -144,7 +224,7 @@ func TestServiceExportImport(t *testing.T) {
reply := CreateUserReply{}
if err := ks.CreateUser(nil, &CreateUserArgs{
Username: "bob",
Password: "launch",
Password: strongPassword,
}, &reply); err != nil {
t.Fatal(err)
}
@ -154,7 +234,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,7 +246,7 @@ 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)
}
@ -178,7 +258,7 @@ func TestServiceExportImport(t *testing.T) {
reply := ImportUserReply{}
if err := newKS.ImportUser(nil, &ImportUserArgs{
Username: "bob",
Password: "launch",
Password: strongPassword,
User: exportReply.User,
}, &reply); err != nil {
t.Fatal(err)
@ -189,7 +269,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)
}

View File

@ -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)
}

View File

@ -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)
}

105
chains/atomic/memory.go Normal file
View File

@ -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))
}

View File

@ -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)
}

21
chains/atomic/writer.go Normal file
View File

@ -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()
}

View File

@ -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})
}
}

View File

@ -9,6 +9,7 @@ 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"
@ -26,6 +27,7 @@ import (
"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"
@ -92,6 +94,7 @@ 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
@ -109,6 +112,7 @@ type manager struct {
awaiter Awaiter // Waits for required connections before running bootstrapping
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,
@ -135,6 +140,7 @@ func New(
awaiter Awaiter,
server *api.Server,
keystore *keystore.Keystore,
sharedMemory *atomic.SharedMemory,
) Manager {
timeoutManager := timeout.Manager{}
timeoutManager.Initialize(requestTimeout)
@ -143,6 +149,7 @@ func New(
router.Initialize(log, &timeoutManager)
m := &manager{
stakingEnabled: stakingEnabled,
log: log,
logFactory: logFactory,
vmManager: vmManager,
@ -159,6 +166,7 @@ func New(
awaiter: awaiter,
server: server,
keystore: keystore,
sharedMemory: sharedMemory,
}
m.Initialize()
return m
@ -206,7 +214,12 @@ func (m *manager) ForceCreateChain(chain ChainParameters) {
}
// Create the chain
vm := vmFactory.New()
vm, err := vmFactory.New()
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,10 +236,16 @@ func (m *manager) ForceCreateChain(chain ChainParameters) {
return
}
fx, err := fxFactory.New()
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,
}
}
@ -246,6 +265,7 @@ func (m *manager) ForceCreateChain(chain ChainParameters) {
NodeID: m.nodeID,
HTTP: m.server,
Keystore: m.keystore.NewBlockchainKeyStore(chain.ID),
SharedMemory: m.sharedMemory.NewBlockchainSharedMemory(chain.ID),
BCLookup: m,
}
consensusParams := m.consensusParams
@ -256,7 +276,13 @@ func (m *manager) ForceCreateChain(chain ChainParameters) {
}
// 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
@ -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
@ -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,
@ -403,6 +438,8 @@ func (m *manager) createAvalancheChain(
go ctx.Log.RecoverAndPanic(handler.Dispatch)
awaiting := &networking.AwaitingConnections{
Requested: beacons,
WeightRequired: (3*bootstrapWeight + 3) / 4, // 75% must be connected to
Finish: func() {
ctx.Lock.Lock()
defer ctx.Lock.Unlock()
@ -410,10 +447,6 @@ func (m *manager) createAvalancheChain(
engine.Startup()
},
}
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
@ -454,6 +487,15 @@ func (m *manager) createSnowmanChain(
sender := sender.Sender{}
sender.Initialize(ctx, m.sender, 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{}
engine.Initialize(smeng.Config{
@ -462,7 +504,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,
@ -482,6 +524,8 @@ func (m *manager) createSnowmanChain(
go ctx.Log.RecoverAndPanic(handler.Dispatch)
awaiting := &networking.AwaitingConnections{
Requested: beacons,
WeightRequired: (3*bootstrapWeight + 3) / 4, // 75% must be connected to
Finish: func() {
ctx.Lock.Lock()
defer ctx.Lock.Unlock()
@ -489,10 +533,6 @@ func (m *manager) createSnowmanChain(
engine.Startup()
},
}
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
}

37
chains/mock_manager.go Normal file
View File

@ -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() {}

View File

@ -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.

View File

@ -184,6 +184,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

View File

@ -208,6 +208,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

View File

@ -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 }

268
database/rpcdb/db_client.go Normal file
View File

@ -0,0 +1,268 @@
// (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/proto"
)
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 proto.DatabaseClient }
// NewClient returns a database instance connected to a remote database instance
func NewClient(client proto.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(), &proto.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(), &proto.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(), &proto.PutRequest{
Key: key,
Value: value,
})
return updateError(err)
}
// Delete returns nil
func (db *DatabaseClient) Delete(key []byte) error {
_, err := db.client.Delete(context.Background(), &proto.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(), &proto.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(), &proto.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(), &proto.CompactRequest{
Start: start,
Limit: limit,
})
return updateError(err)
}
// Close returns nil
func (db *DatabaseClient) Close() error {
_, err := db.client.Close(context.Background(), &proto.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{copyBytes(key), 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.size++
return nil
}
func (b *batch) ValueSize() int { return b.size }
func (b *batch) Write() error {
request := &proto.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, &proto.DeleteRequest{
Key: kv.key,
})
} else {
request.Puts = append(request.Puts, &proto.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(), &proto.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(), &proto.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(), &proto.IteratorReleaseRequest{
Id: it.id,
})
}
func copyBytes(bytes []byte) []byte {
copiedBytes := make([]byte, len(bytes))
copy(copiedBytes, bytes)
return copiedBytes
}
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
}
}

143
database/rpcdb/db_server.go Normal file
View File

@ -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/proto"
)
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 *proto.HasRequest) (*proto.HasResponse, error) {
has, err := db.db.Has(req.Key)
if err != nil {
return nil, err
}
return &proto.HasResponse{Has: has}, nil
}
// Get ...
func (db *DatabaseServer) Get(_ context.Context, req *proto.GetRequest) (*proto.GetResponse, error) {
value, err := db.db.Get(req.Key)
if err != nil {
return nil, err
}
return &proto.GetResponse{Value: value}, nil
}
// Put ...
func (db *DatabaseServer) Put(_ context.Context, req *proto.PutRequest) (*proto.PutResponse, error) {
return &proto.PutResponse{}, db.db.Put(req.Key, req.Value)
}
// Delete ...
func (db *DatabaseServer) Delete(_ context.Context, req *proto.DeleteRequest) (*proto.DeleteResponse, error) {
return &proto.DeleteResponse{}, db.db.Delete(req.Key)
}
// Stat ...
func (db *DatabaseServer) Stat(_ context.Context, req *proto.StatRequest) (*proto.StatResponse, error) {
stat, err := db.db.Stat(req.Property)
if err != nil {
return nil, err
}
return &proto.StatResponse{Stat: stat}, nil
}
// Compact ...
func (db *DatabaseServer) Compact(_ context.Context, req *proto.CompactRequest) (*proto.CompactResponse, error) {
return &proto.CompactResponse{}, db.db.Compact(req.Start, req.Limit)
}
// Close ...
func (db *DatabaseServer) Close(_ context.Context, _ *proto.CloseRequest) (*proto.CloseResponse, error) {
return &proto.CloseResponse{}, db.db.Close()
}
// WriteBatch ...
func (db *DatabaseServer) WriteBatch(_ context.Context, req *proto.WriteBatchRequest) (*proto.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 &proto.WriteBatchResponse{}, db.batch.Write()
}
// NewIteratorWithStartAndPrefix ...
func (db *DatabaseServer) NewIteratorWithStartAndPrefix(_ context.Context, req *proto.NewIteratorWithStartAndPrefixRequest) (*proto.NewIteratorWithStartAndPrefixResponse, error) {
id := db.nextIteratorID
it := db.db.NewIteratorWithStartAndPrefix(req.Start, req.Prefix)
db.iterators[id] = it
db.nextIteratorID++
return &proto.NewIteratorWithStartAndPrefixResponse{Id: id}, nil
}
// IteratorNext ...
func (db *DatabaseServer) IteratorNext(_ context.Context, req *proto.IteratorNextRequest) (*proto.IteratorNextResponse, error) {
it, exists := db.iterators[req.Id]
if !exists {
return nil, errUnknownIterator
}
return &proto.IteratorNextResponse{
FoundNext: it.Next(),
Key: it.Key(),
Value: it.Value(),
}, nil
}
// IteratorError ...
func (db *DatabaseServer) IteratorError(_ context.Context, req *proto.IteratorErrorRequest) (*proto.IteratorErrorResponse, error) {
it, exists := db.iterators[req.Id]
if !exists {
return nil, errUnknownIterator
}
return &proto.IteratorErrorResponse{}, it.Error()
}
// IteratorRelease ...
func (db *DatabaseServer) IteratorRelease(_ context.Context, req *proto.IteratorReleaseRequest) (*proto.IteratorReleaseResponse, error) {
it, exists := db.iterators[req.Id]
if exists {
delete(db.iterators, req.Id)
it.Release()
}
return &proto.IteratorReleaseResponse{}, nil
}

51
database/rpcdb/db_test.go Normal file
View File

@ -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/proto"
)
const (
bufSize = 1 << 20
)
func TestInterface(t *testing.T) {
for _, test := range database.Tests {
listener := bufconn.Listen(bufSize)
server := grpc.NewServer()
proto.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(proto.NewDatabaseClient(conn))
test(t, db)
conn.Close()
}
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,108 @@
syntax = "proto3";
package proto;
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);
}

View File

@ -16,7 +16,10 @@ var (
TestBatchPut,
TestBatchDelete,
TestBatchReset,
TestBatchReuse,
TestBatchRewrite,
TestBatchReplay,
TestBatchInner,
TestIterator,
TestIteratorStart,
TestIteratorPrefix,
@ -235,6 +238,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 +401,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")

View File

@ -184,29 +184,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
@ -289,6 +315,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 {

View File

@ -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()

77
genesis/aliases.go Normal file
View File

@ -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
}

285
genesis/config.go Normal file
View File

@ -0,0 +1,285 @@
// (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 (
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 CascadeID:
return &CascadeConfig
default:
return &DefaultConfig
}
}

View File

@ -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
}

View File

@ -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,11 @@ 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(TestnetID); 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(CascadeID); name != CascadeName {
t.Fatalf("NetworkID was incorrectly named. Result: %s ; Expected: %s", name, CascadeName)
}
if name := NetworkName(4294967295); name != "network-4294967295" {
t.Fatalf("NetworkID was incorrectly named. Result: %s ; Expected: %s", name, "network-4294967295")
@ -45,7 +45,7 @@ func TestNetworkID(t *testing.T) {
t.Fatalf("Returned wrong network. Expected: %d ; Returned %d", TestnetID, id)
}
id, err = NetworkID(BorealisName)
id, err = NetworkID(CascadeName)
if err != nil {
t.Fatal(err)
}
@ -53,7 +53,7 @@ func TestNetworkID(t *testing.T) {
t.Fatalf("Returned wrong network. Expected: %d ; Returned %d", TestnetID, id)
}
id, err = NetworkID("bOrEaLiS")
id, err = NetworkID("cAsCaDe")
if err != nil {
t.Fatal(err)
}
@ -91,12 +91,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 +106,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)
}
}
}

73
genesis/network_id.go Normal file
View File

@ -0,0 +1,73 @@
// (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
TestnetID uint32 = 2
CascadeID uint32 = 2
LocalID uint32 = 12345
MainnetName = "mainnet"
TestnetName = "testnet"
CascadeName = "cascade"
LocalName = "local"
NetworkIDToNetworkName = map[uint32]string{
MainnetID: MainnetName,
TestnetID: CascadeName,
LocalID: LocalName,
}
NetworkNameToNetworkID = map[string]uint32{
MainnetName: MainnetID,
TestnetName: TestnetID,
CascadeName: CascadeID,
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)
}

113
ids/aliases_test.go Normal file
View File

@ -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")
}
}

View File

@ -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{}

View File

@ -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 := "617661206c61627300000000000000000000000000000000000000000000000000"
actual := id.Hex()
if actual != actual {
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")
}
}

70
ids/queue_test.go Normal file
View File

@ -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)
}
}

33
ids/slice.go Normal file
View File

@ -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)
}

View File

@ -1,7 +1,7 @@
#!/bin/sh
set -ex
keypath=$GOPATH/src/github.com/ava-labs/gecko/keys/mykey
keypath=$GOPATH/src/github.com/ava-labs/gecko/keys
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."

View File

@ -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

View File

@ -1 +0,0 @@
BAF3B5C5C6D0D14A

View File

@ -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-----

View File

@ -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

View File

@ -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

View File

@ -1,34 +0,0 @@
-----BEGIN CERTIFICATE-----
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
DB8IRfWqBx2nWw==
-----END CERTIFICATE-----

View File

@ -1,51 +0,0 @@
-----BEGIN RSA PRIVATE KEY-----
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
-----END RSA PRIVATE KEY-----

View File

@ -1 +0,0 @@
BAF3B5C5C6D0D14A

View File

@ -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-----

View File

@ -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

View File

@ -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

View File

@ -1,34 +0,0 @@
-----BEGIN CERTIFICATE-----
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
DB8IRfWqBx2nWw==
-----END CERTIFICATE-----

View File

@ -1,51 +0,0 @@
-----BEGIN RSA PRIVATE KEY-----
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
-----END RSA PRIVATE KEY-----

View File

@ -1 +0,0 @@
BAF3B5C5C6D0D14A

View File

@ -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-----

View File

@ -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

View File

@ -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

View File

@ -1,34 +0,0 @@
-----BEGIN CERTIFICATE-----
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
DB8IRfWqBx2nWw==
-----END CERTIFICATE-----

View File

@ -1,51 +0,0 @@
-----BEGIN RSA PRIVATE KEY-----
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
-----END RSA PRIVATE KEY-----

View File

@ -1 +0,0 @@
BAF3B5C5C6D0D14A

View File

@ -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-----

View File

@ -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

View File

@ -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

View File

@ -1,34 +0,0 @@
-----BEGIN CERTIFICATE-----
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
DB8IRfWqBx2nWw==
-----END CERTIFICATE-----

View File

@ -1,51 +0,0 @@
-----BEGIN RSA PRIVATE KEY-----
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
-----END RSA PRIVATE KEY-----

View File

@ -1 +0,0 @@
BAF3B5C5C6D0D14A

View File

@ -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-----

View File

@ -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

View File

@ -1,34 +0,0 @@
-----BEGIN CERTIFICATE-----
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
DB8IRfWqBx2nWw==
-----END CERTIFICATE-----

View File

@ -1,51 +0,0 @@
-----BEGIN RSA PRIVATE KEY-----
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
-----END RSA PRIVATE KEY-----

View File

@ -1 +0,0 @@
BAF3B5C5C6D0D164

1
keys/rootCA.srl Normal file
View File

@ -0,0 +1 @@
BAF3B5C5C6D0D166

View File

@ -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
@ -61,26 +61,11 @@ func main() {
log.Warn("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",
)
go nat.Map(
/*nat=*/ Config.Nat,
/*closeChannel=*/ natChan,
/*protocol=*/ "TCP",
/*internetPort=*/ int(Config.HTTPPort),
/*localPort=*/ int(Config.HTTPPort),
/*name=*/ "Gecko HTTP Server",
)
mapper.MapPort(Config.StakingIP.Port, Config.StakingIP.Port)
mapper.MapPort(Config.HTTPPort, Config.HTTPPort)
log.Debug("initializing node state")
// MainNode is a global variable in the node.go file

View File

@ -8,15 +8,15 @@ import (
"flag"
"fmt"
"net"
"os"
"path"
"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/utils"
@ -32,6 +32,14 @@ var (
Err error
)
// GetIPs returns the default IPs for each network
func GetIPs(networkID uint32) []string {
switch networkID {
default:
return nil
}
}
var (
errBootstrapMismatch = errors.New("more bootstrap IDs provided than bootstrap IPs")
)
@ -44,72 +52,84 @@ func init() {
loggingConfig, err := logging.DefaultConfig()
errs.Add(err)
fs := flag.NewFlagSet("gecko", flag.ContinueOnError)
// NetworkID:
networkName := flag.String("network-id", genesis.LocalName, "Network ID this node will connect to")
networkName := fs.String("network-id", genesis.LocalName, "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", "db", "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")
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")
fs.BoolVar(&Config.EnableStaking, "staking-tls-enabled", true, "Require TLS to authenticate staking connections")
fs.StringVar(&Config.StakingKeyFile, "staking-tls-key-file", "keys/staker.key", "TLS private key file for staking connections")
fs.StringVar(&Config.StakingCertFile, "staking-tls-cert-file", "keys/staker.crt", "TLS certificate file for staking connections")
// Plugins:
fs.StringVar(&Config.PluginDir, "plugin-dir", "./build/plugins", "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.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 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))
}
Config.NetworkID = networkID
// DB:
@ -123,13 +143,17 @@ func init() {
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()
errs.Add(fmt.Errorf(
"%s\n"+
"If you are trying to create a local network, try adding --public-ip=127.0.0.1\n"+
"If you are attempting to connect to a public network, you may need to manually report your IP and perform port forwarding",
err))
} else {
ip = net.ParseIP(*consensusIP)
}
@ -143,6 +167,9 @@ func init() {
}
// Bootstrapping:
if *bootstrapIPs == "default" {
*bootstrapIPs = strings.Join(GetIPs(networkID), ",")
}
for _, ip := range strings.Split(*bootstrapIPs, ",") {
if ip != "" {
addr, err := utils.ToIPDesc(ip)
@ -152,6 +179,14 @@ func init() {
})
}
}
if *bootstrapIDs == "default" {
if *bootstrapIPs == "" {
*bootstrapIDs = ""
} else {
*bootstrapIDs = strings.Join(genesis.GetConfig(networkID).StakerIDs, ",")
}
}
if Config.EnableStaking {
i := 0
cb58 := formatting.CB58{}

143
nat/mapper.go Normal file
View File

@ -0,0 +1,143 @@
// (c) 2019-2020, Ava Labs, Inc. All rights reserved.
// See the file LICENSE for licensing terms.
package nat
import (
"sync"
"time"
"github.com/ava-labs/gecko/utils/logging"
"github.com/ava-labs/gecko/utils/wrappers"
)
const (
defaultMappingTimeout = 30 * time.Minute
defaultMappingUpdateInterval = 3 * defaultMappingTimeout / 4
)
// Mapper maps port
type Mapper interface {
MapPort(newInternalPort, newExternalPort uint16) error
UnmapAllPorts() error
}
type mapper struct {
log logging.Logger
router Router
networkProtocol NetworkProtocol
mappingNames string
mappingTimeout time.Duration
mappingUpdateInterval time.Duration
closer chan struct{}
wg sync.WaitGroup
errLock sync.Mutex
errs wrappers.Errs
}
// NewMapper returns a new mapper that can map ports on a router
func NewMapper(
log logging.Logger,
router Router,
networkProtocol NetworkProtocol,
mappingNames string,
mappingTimeout time.Duration,
mappingUpdateInterval time.Duration,
) Mapper {
return &mapper{
log: log,
router: router,
networkProtocol: networkProtocol,
mappingNames: mappingNames,
mappingTimeout: mappingTimeout,
mappingUpdateInterval: mappingUpdateInterval,
closer: make(chan struct{}),
}
}
// NewDefaultMapper returns a new mapper that can map ports on a router with
// default settings
func NewDefaultMapper(
log logging.Logger,
router Router,
networkProtocol NetworkProtocol,
mappingNames string,
) Mapper {
return NewMapper(
log,
router,
networkProtocol,
mappingNames,
defaultMappingTimeout, // uses the default value
defaultMappingUpdateInterval, // uses the default value
)
}
// MapPort maps a local port to a port on the router until UnmapAllPorts is
// called.
func (m *mapper) MapPort(newInternalPort, newExternalPort uint16) error {
m.wg.Add(1)
go m.mapPort(newInternalPort, newExternalPort)
return nil
}
func (m *mapper) mapPort(newInternalPort, newExternalPort uint16) {
// duration is set to 0 here so that the select case will execute
// immediately
updateTimer := time.NewTimer(0)
defer func() {
updateTimer.Stop()
m.errLock.Lock()
m.errs.Add(m.router.UnmapPort(
m.networkProtocol,
newInternalPort,
newExternalPort))
m.errLock.Unlock()
m.log.Debug("Unmapped external port %d to internal port %d",
newExternalPort,
newInternalPort)
m.wg.Done()
}()
for {
select {
case <-updateTimer.C:
err := m.router.MapPort(
m.networkProtocol,
newInternalPort,
newExternalPort,
m.mappingNames,
m.mappingTimeout)
if err != nil {
m.errLock.Lock()
m.errs.Add(err)
m.errLock.Unlock()
m.log.Debug("Failed to add mapping from external port %d to internal port %d due to %s",
newExternalPort,
newInternalPort,
err)
} else {
m.log.Debug("Mapped external port %d to internal port %d",
newExternalPort,
newInternalPort)
}
// remap the port in m.mappingUpdateInterval
updateTimer.Reset(m.mappingUpdateInterval)
case _, _ = <-m.closer:
return // only return when all ports are unmapped
}
}
}
func (m *mapper) UnmapAllPorts() error {
close(m.closer)
m.wg.Wait()
return m.errs.Err
}

28
nat/no_router.go Normal file
View File

@ -0,0 +1,28 @@
// (c) 2019-2020, Ava Labs, Inc. All rights reserved.
// See the file LICENSE for licensing terms.
package nat
import (
"errors"
"net"
"time"
)
var (
errNoRouter = errors.New("no nat enabled router was discovered")
)
type noRouter struct{}
func (noRouter) MapPort(_ NetworkProtocol, _, _ uint16, _ string, _ time.Duration) error {
return errNoRouter
}
func (noRouter) UnmapPort(_ NetworkProtocol, _, _ uint16) error {
return errNoRouter
}
func (noRouter) IP() (net.IP, error) {
return nil, errNoRouter
}

71
nat/pmp.go Normal file
View File

@ -0,0 +1,71 @@
// (c) 2019-2020, Ava Labs, Inc. All rights reserved.
// See the file LICENSE for licensing terms.
package nat
import (
"net"
"time"
"github.com/jackpal/gateway"
"github.com/jackpal/go-nat-pmp"
)
var (
pmpClientTimeout = 500 * time.Millisecond
)
// natPMPClient adapts the NAT-PMP protocol implementation so it conforms to
// the common interface.
type pmpClient struct {
client *natpmp.Client
}
func (pmp *pmpClient) MapPort(
networkProtocol NetworkProtocol,
newInternalPort uint16,
newExternalPort uint16,
mappingName string,
mappingDuration time.Duration) error {
protocol := string(networkProtocol)
internalPort := int(newInternalPort)
externalPort := int(newExternalPort)
// go-nat-pmp uses seconds to denote their lifetime
lifetime := int(mappingDuration / time.Second)
_, err := pmp.client.AddPortMapping(protocol, internalPort, externalPort, lifetime)
return err
}
func (pmp *pmpClient) UnmapPort(
networkProtocol NetworkProtocol,
internalPort uint16,
_ uint16) error {
protocol := string(networkProtocol)
internalPortInt := int(internalPort)
_, err := pmp.client.AddPortMapping(protocol, internalPortInt, 0, 0)
return err
}
func (pmp *pmpClient) IP() (net.IP, error) {
response, err := pmp.client.GetExternalAddress()
if err != nil {
return nil, err
}
return response.ExternalIPAddress[:], nil
}
func getPMPRouter() Router {
gatewayIP, err := gateway.DiscoverGateway()
if err != nil {
return nil
}
pmp := &pmpClient{natpmp.NewClientWithTimeout(gatewayIP, pmpClientTimeout)}
if _, err := pmp.IP(); err != nil {
return nil
}
return pmp
}

65
nat/router.go Normal file
View File

@ -0,0 +1,65 @@
// (c) 2019-2020, Ava Labs, Inc. All rights reserved.
// See the file LICENSE for licensing terms.
// Package nat performs network address translation and provides helpers for
// routing ports.
package nat
import (
"net"
"time"
)
// NetworkProtocol is a protocol that will be used through a port
type NetworkProtocol string
// Available protocol
const (
TCP NetworkProtocol = "TCP"
UDP NetworkProtocol = "UDP"
)
// Router provides a standard NAT router functions. Specifically, allowing the
// fetching of public IPs and port forwarding to this computer.
type Router interface {
// mapPort creates a mapping between a port on the local computer to an
// external port on the router.
//
// The mappingName is something displayed on the router, so it is included
// for completeness.
MapPort(
networkProtocol NetworkProtocol,
newInternalPort uint16,
newExternalPort uint16,
mappingName string,
mappingDuration time.Duration) error
// UnmapPort clears a mapping that was previous made by a call to MapPort
UnmapPort(
networkProtocol NetworkProtocol,
internalPort uint16,
externalPort uint16) error
// Returns the routers IP address on the network the router considers
// external
IP() (net.IP, error)
}
// NewRouter returns a new router discovered on the local network
func NewRouter() Router {
routers := make(chan Router)
// Because getting a router can take a noticeable amount of time to error,
// we run these requests in parallel
go func() {
routers <- getUPnPRouter()
}()
go func() {
routers <- getPMPRouter()
}()
for i := 0; i < 2; i++ {
if router := <-routers; router != nil {
return router
}
}
return noRouter{}
}

253
nat/upnp.go Normal file
View File

@ -0,0 +1,253 @@
// (c) 2019-2020, Ava Labs, Inc. All rights reserved.
// See the file LICENSE for licensing terms.
package nat
import (
"errors"
"fmt"
"net"
"time"
"github.com/huin/goupnp"
"github.com/huin/goupnp/dcps/internetgateway1"
"github.com/huin/goupnp/dcps/internetgateway2"
)
const (
soapTimeout = time.Second
)
var (
errNoGateway = errors.New("Failed to connect to any avaliable gateways")
)
// upnpClient is the interface used by goupnp for their client implementations
type upnpClient interface {
// attempts to map connection using the provided protocol from the external
// port to the internal port for the lease duration.
AddPortMapping(
newRemoteHost string,
newExternalPort uint16,
newProtocol string,
newInternalPort uint16,
newInternalClient string,
newEnabled bool,
newPortMappingDescription string,
newLeaseDuration uint32) error
// attempt to remove any mapping from the external port.
DeletePortMapping(
newRemoteHost string,
newExternalPort uint16,
newProtocol string) error
// attempts to return the external IP address, formatted as a string.
GetExternalIPAddress() (ip string, err error)
// returns if there is rsip available, nat enabled, or an unexpected error.
GetNATRSIPStatus() (newRSIPAvailable bool, natEnabled bool, err error)
}
type upnpRouter struct {
root *goupnp.RootDevice
client upnpClient
}
func (n *upnpRouter) MapPort(
networkProtocol NetworkProtocol,
newInternalPort uint16,
newExternalPort uint16,
mappingName string,
mappingDuration time.Duration,
) error {
ip, err := n.localAddress()
if err != nil {
return err
}
protocol := string(networkProtocol)
// goupnp uses seconds to denote their lifetime
lifetime := uint32(mappingDuration / time.Second)
// UnmapPort's error is intentionally dropped, because the mapping may not
// exist.
n.UnmapPort(networkProtocol, newInternalPort, newExternalPort)
return n.client.AddPortMapping(
"", // newRemoteHost isn't used to limit the mapping to a host
newExternalPort,
protocol,
newInternalPort,
ip.String(), // newInternalClient is the client traffic should be sent to
true, // newEnabled enables port mappings
mappingName,
lifetime,
)
}
func (n *upnpRouter) UnmapPort(networkProtocol NetworkProtocol, _, externalPort uint16) error {
protocol := string(networkProtocol)
return n.client.DeletePortMapping(
"", // newRemoteHost isn't used to limit the mapping to a host
externalPort,
protocol)
}
func (n *upnpRouter) IP() (net.IP, error) {
ipStr, err := n.client.GetExternalIPAddress()
if err != nil {
return nil, err
}
ip := net.ParseIP(ipStr)
if ip == nil {
return nil, fmt.Errorf("invalid IP %s", ipStr)
}
return ip, nil
}
func (n *upnpRouter) localAddress() (net.IP, error) {
// attempt to get an address on the router
deviceAddr, err := net.ResolveUDPAddr("udp4", n.root.URLBase.Host)
if err != nil {
return nil, err
}
deviceIP := deviceAddr.IP
netInterfaces, err := net.Interfaces()
if err != nil {
return nil, err
}
// attempt to find one of my ips that the router would know about
for _, netInterface := range netInterfaces {
addrs, err := netInterface.Addrs()
if err != nil {
continue
}
for _, addr := range addrs {
// this is pretty janky, but it seems to be the best way to get the
// ip mask and properly check if the ip references the device we are
// connected to
ipNet, ok := addr.(*net.IPNet)
if !ok {
continue
}
if ipNet.Contains(deviceIP) {
return ipNet.IP, nil
}
}
}
return nil, fmt.Errorf("couldn't find the local address in the same network as %s", deviceIP)
}
// getUPnPRouter searches for all Gateway Devices that have avaliable
// connections in the goupnp library and returns the first connection it can
// find.
func getUPnPRouter() Router {
routers := make(chan *upnpRouter)
// Because DiscoverDevices takes a noticeable amount of time to error, we
// run these requests in parallel
go func() {
routers <- connectToGateway(internetgateway1.URN_WANConnectionDevice_1, gateway1)
}()
go func() {
routers <- connectToGateway(internetgateway2.URN_WANConnectionDevice_2, gateway2)
}()
for i := 0; i < 2; i++ {
if router := <-routers; router != nil {
return router
}
}
return nil
}
func gateway1(client goupnp.ServiceClient) upnpClient {
switch client.Service.ServiceType {
case internetgateway1.URN_WANIPConnection_1:
return &internetgateway1.WANIPConnection1{ServiceClient: client}
case internetgateway1.URN_WANPPPConnection_1:
return &internetgateway1.WANPPPConnection1{ServiceClient: client}
default:
return nil
}
}
func gateway2(client goupnp.ServiceClient) upnpClient {
switch client.Service.ServiceType {
case internetgateway2.URN_WANIPConnection_1:
return &internetgateway2.WANIPConnection1{ServiceClient: client}
case internetgateway2.URN_WANIPConnection_2:
return &internetgateway2.WANIPConnection2{ServiceClient: client}
case internetgateway2.URN_WANPPPConnection_1:
return &internetgateway2.WANPPPConnection1{ServiceClient: client}
default:
return nil
}
}
func connectToGateway(deviceType string, toClient func(goupnp.ServiceClient) upnpClient) *upnpRouter {
devs, err := goupnp.DiscoverDevices(deviceType)
if err != nil {
return nil
}
// we are iterating over all the network devices, acting a possible roots
for i := range devs {
dev := &devs[i]
if dev.Root == nil {
continue
}
// the root device may be a router, so attempt to connect to that
rootDevice := &dev.Root.Device
if upnp := getRouter(dev, rootDevice, toClient); upnp != nil {
return upnp
}
// attempt to connect to any sub devices
devices := rootDevice.Devices
for i := range devices {
if upnp := getRouter(dev, &devices[i], toClient); upnp != nil {
return upnp
}
}
}
return nil
}
func getRouter(rootDevice *goupnp.MaybeRootDevice, device *goupnp.Device, toClient func(goupnp.ServiceClient) upnpClient) *upnpRouter {
for i := range device.Services {
service := &device.Services[i]
soapClient := service.NewSOAPClient()
// make sure the client times out if needed
soapClient.HTTPClient.Timeout = soapTimeout
// attempt to create a client connection
serviceClient := goupnp.ServiceClient{
SOAPClient: soapClient,
RootDevice: rootDevice.Root,
Location: rootDevice.Location,
Service: service,
}
client := toClient(serviceClient)
if client == nil {
continue
}
// check whether port mapping is enabled
if _, nat, err := client.GetNATRSIPStatus(); err != nil || !nat {
continue
}
// we found a router!
return &upnpRouter{
root: rootDevice.Root,
client: client,
}
}
return nil
}

View File

@ -54,6 +54,13 @@ Periodically gossip peerlists.
stakers should be in the set).
*/
/*
Attempt reconnections
- If a non-staker disconnects, delete the connection
- If a staker disconnects, attempt to reconnect to the node for awhile. If the
node isn't connected to after awhile delete the connection.
*/
const (
// CurrentVersion this avalanche instance is executing.
CurrentVersion = "avalanche/0.0.1"
@ -70,6 +77,9 @@ const (
// GetVersionTimeout is the amount of time to wait before sending a
// getVersion message to a partially connected peer
GetVersionTimeout = 2 * time.Second
// ReconnectTimeout is the amount of time to wait to reconnect to a staker
// before giving up
ReconnectTimeout = 1 * time.Minute
)
// Manager is the struct that will be accessed on event calls
@ -100,6 +110,7 @@ type Handshake struct {
connections AddrCert // Connections that I think are connected
versionTimeout timer.TimeoutManager
reconnectTimeout timer.TimeoutManager
peerListGossiper *timer.Repeater
awaitingLock sync.Mutex
@ -143,6 +154,10 @@ func (nm *Handshake) Initialize(
nm.versionTimeout.Initialize(GetVersionTimeout)
go nm.log.RecoverAndPanic(nm.versionTimeout.Dispatch)
nm.reconnectTimeout.Initialize(ReconnectTimeout)
go nm.log.RecoverAndPanic(nm.reconnectTimeout.Dispatch)
nm.peerListGossiper = timer.NewRepeater(nm.gossipPeerList, PeerListGossipSpacing)
go nm.log.RecoverAndPanic(nm.peerListGossiper.Dispatch)
}
@ -290,6 +305,73 @@ func checkPeerCertificate(_ *C.struct_msgnetwork_conn_t, connected C.bool, _ uns
return connected
}
func (nm *Handshake) connectedToPeer(conn *C.struct_peernetwork_conn_t, addr salticidae.NetAddr) {
ip := toIPDesc(addr)
// If we're enforcing staking, use a peer's certificate to uniquely identify them
// Otherwise, use a hash of their ip to identify them
cert := ids.ShortID{}
ipCert := toShortID(ip)
if nm.enableStaking {
cert = getPeerCert(conn)
} else {
cert = ipCert
}
nm.log.Debug("Connected to %s", ip)
longCert := cert.LongID()
nm.reconnectTimeout.Remove(longCert)
nm.reconnectTimeout.Remove(ipCert.LongID())
nm.pending.Add(addr, cert)
handler := new(func())
*handler = func() {
if nm.pending.ContainsIP(addr) {
nm.SendGetVersion(addr)
nm.versionTimeout.Put(longCert, *handler)
}
}
(*handler)()
}
func (nm *Handshake) disconnectedFromPeer(addr salticidae.NetAddr) {
cert := ids.ShortID{}
if pendingCert, exists := nm.pending.GetID(addr); exists {
cert = pendingCert
} else if connectedCert, exists := nm.connections.GetID(addr); exists {
cert = connectedCert
} else {
return
}
nm.log.Info("Disconnected from %s", toIPDesc(addr))
longCert := cert.LongID()
if nm.vdrs.Contains(cert) {
nm.reconnectTimeout.Put(longCert, func() {
nm.net.DelPeer(addr)
})
} else {
nm.net.DelPeer(addr)
}
nm.versionTimeout.Remove(longCert)
if !nm.enableStaking {
nm.vdrs.Remove(cert)
}
nm.pending.RemoveIP(addr)
nm.connections.RemoveIP(addr)
nm.numPeers.Set(float64(nm.connections.Len()))
nm.awaitingLock.Lock()
defer nm.awaitingLock.Unlock()
for _, awaiting := range HandshakeNet.awaiting {
awaiting.Remove(cert)
}
}
// peerHandler notifies a change to the set of connected peers
// connected is true if a new peer is connected
// connected is false if a formerly connected peer has disconnected
@ -298,68 +380,30 @@ func peerHandler(_conn *C.struct_peernetwork_conn_t, connected C.bool, _ unsafe.
pConn := salticidae.PeerNetworkConnFromC(salticidae.CPeerNetworkConn(_conn))
addr := pConn.GetPeerAddr(true)
ip := toIPDesc(addr)
if !connected {
if !HandshakeNet.enableStaking {
cert := toShortID(ip)
HandshakeNet.vdrs.Remove(cert)
}
cert := ids.ShortID{}
if pendingCert, exists := HandshakeNet.pending.GetID(addr); exists {
cert = pendingCert
} else if connectedCert, exists := HandshakeNet.connections.GetID(addr); exists {
cert = connectedCert
} else {
return
}
HandshakeNet.pending.RemoveIP(addr)
HandshakeNet.connections.RemoveIP(addr)
HandshakeNet.numPeers.Set(float64(HandshakeNet.connections.Len()))
HandshakeNet.log.Warn("Disconnected from %s", ip)
HandshakeNet.awaitingLock.Lock()
defer HandshakeNet.awaitingLock.Unlock()
for _, awaiting := range HandshakeNet.awaiting {
awaiting.Remove(cert)
}
return
}
HandshakeNet.log.Debug("Connected to %s", ip)
// If we're enforcing staking, use a peer's certificate to uniquely identify them
// Otherwise, use a hash of their ip to identify them
cert := ids.ShortID{}
if HandshakeNet.enableStaking {
cert = getPeerCert(_conn)
if connected {
HandshakeNet.connectedToPeer(_conn, addr)
} else {
cert = toShortID(ip)
HandshakeNet.disconnectedFromPeer(addr)
}
HandshakeNet.pending.Add(addr, cert)
certID := cert.LongID()
handler := new(func())
*handler = func() {
if HandshakeNet.pending.ContainsIP(addr) {
HandshakeNet.SendGetVersion(addr)
HandshakeNet.versionTimeout.Put(certID, *handler)
}
}
(*handler)()
}
// unknownPeerHandler notifies of an unknown peer connection attempt
//export unknownPeerHandler
func unknownPeerHandler(_addr *C.netaddr_t, _cert *C.x509_t, _ unsafe.Pointer) {
addr := salticidae.NetAddrFromC(salticidae.CNetAddr(_addr))
addr := salticidae.NetAddrFromC(salticidae.CNetAddr(_addr)).Copy(true)
ip := toIPDesc(addr)
HandshakeNet.log.Info("Adding peer %s", ip)
cert := ids.ShortID{}
if HandshakeNet.enableStaking {
cert = getCert(salticidae.X509FromC(salticidae.CX509(_cert)))
} else {
cert = toShortID(ip)
}
HandshakeNet.reconnectTimeout.Put(cert.LongID(), func() {
HandshakeNet.net.DelPeer(addr)
})
HandshakeNet.net.AddPeer(addr)
}
@ -522,16 +566,20 @@ func peerList(_msg *C.struct_msg_t, _conn *C.struct_msgnetwork_conn_t, _ unsafe.
cErr := salticidae.NewError()
for _, ip := range ips {
HandshakeNet.log.Verbo("Trying to adding peer %s", ip)
addr := salticidae.NewNetAddrFromIPPortString(ip.String(), false, &cErr)
addr := salticidae.NewNetAddrFromIPPortString(ip.String(), true, &cErr)
if cErr.GetCode() == 0 && !HandshakeNet.myAddr.IsEq(addr) { // Make sure not to connect to myself
ip := toIPDesc(addr)
ipCert := toShortID(ip)
if !HandshakeNet.pending.ContainsIP(addr) && !HandshakeNet.connections.ContainsIP(addr) {
HandshakeNet.log.Debug("Adding peer %s", ip)
HandshakeNet.reconnectTimeout.Put(ipCert.LongID(), func() {
HandshakeNet.net.DelPeer(addr)
})
HandshakeNet.net.AddPeer(addr)
}
}
addr.Free()
}
}

View File

@ -366,9 +366,9 @@ func (s *Voting) PullQuery(validatorIDs ids.ShortSet, chainID ids.ID, requestID
vID := validatorID
if addr, exists := s.conns.GetIP(vID); exists {
addrs = append(addrs, addr)
s.log.Verbo("Sending a PushQuery to %s", toIPDesc(addr))
s.log.Verbo("Sending a PullQuery to %s", toIPDesc(addr))
} else {
s.log.Warn("Attempted to send a PushQuery message to a disconnected validator: %s", vID)
s.log.Warn("Attempted to send a PullQuery message to a disconnected validator: %s", vID)
s.executor.Add(func() { s.router.QueryFailed(vID, chainID, requestID) })
}
}

View File

@ -9,6 +9,7 @@ import (
"github.com/ava-labs/gecko/ids"
"github.com/ava-labs/gecko/snow"
"github.com/ava-labs/gecko/snow/choices"
"github.com/ava-labs/gecko/utils/logging"
)
type issuableVM interface {
@ -17,17 +18,18 @@ type issuableVM interface {
// Issuer manages all the chain transaction flushing.
type Issuer struct {
lock sync.Mutex
vms map[[32]byte]issuableVM
locks map[[32]byte]sync.Locker
lock sync.Mutex
log logging.Logger
vms map[[32]byte]issuableVM
locks map[[32]byte]sync.Locker
callbacks chan func()
}
// Initialize this flusher
func (i *Issuer) Initialize() {
func (i *Issuer) Initialize(log logging.Logger) {
i.lock.Lock()
defer i.lock.Unlock()
i.log = log
i.vms = make(map[[32]byte]issuableVM)
i.locks = make(map[[32]byte]sync.Locker)
i.callbacks = make(chan func(), 1000)
@ -64,8 +66,12 @@ func (i *Issuer) IssueTx(chainID ids.ID, tx []byte, finalized func(choices.Statu
lock.Lock()
defer lock.Unlock()
if vm, exists := i.vms[key]; exists {
vm.IssueTx(tx, finalized)
if _, err := vm.IssueTx(tx, finalized); err != nil {
i.log.Error("Issuing the tx returned with %s unexpectedly", err)
}
}
}
} else {
i.log.Warn("Attempted to issue a Tx to an unsupported chain %s", chainID)
}
}

View File

@ -4,9 +4,8 @@
package node
import (
"github.com/ava-labs/go-ethereum/p2p/nat"
"github.com/ava-labs/gecko/database"
"github.com/ava-labs/gecko/nat"
"github.com/ava-labs/gecko/snow/consensus/avalanche"
"github.com/ava-labs/gecko/snow/networking/router"
"github.com/ava-labs/gecko/utils"
@ -16,7 +15,7 @@ import (
// Config contains all of the configurations of an Ava node.
type Config struct {
// protocol to use for opening the network interface
Nat nat.Interface
Nat nat.Router
// ID of the network this node should connect to
NetworkID uint32
@ -56,6 +55,9 @@ type Config struct {
// Logging configuration
LoggingConfig logging.Config
// Plugin directory
PluginDir string
// Consensus configuration
ConsensusParams avalanche.Parameters

Some files were not shown because too many files have changed in this diff Show More