mirror of https://github.com/poanetwork/gecko.git
Merge branch 'cascade' into latency
This commit is contained in:
commit
4e20130db8
|
@ -18,6 +18,9 @@ awscpu
|
||||||
# Output of the go coverage tool, specifically when used with LiteIDE
|
# Output of the go coverage tool, specifically when used with LiteIDE
|
||||||
*.out
|
*.out
|
||||||
|
|
||||||
|
# ignore GoLand metafiles directory
|
||||||
|
.idea/
|
||||||
|
|
||||||
*logs/
|
*logs/
|
||||||
|
|
||||||
.vscode*
|
.vscode*
|
||||||
|
@ -42,4 +45,4 @@ db*
|
||||||
bin/
|
bin/
|
||||||
build/
|
build/
|
||||||
|
|
||||||
*/mykey/staker.*
|
keys/staker.*
|
||||||
|
|
|
@ -54,7 +54,7 @@ The Gecko binary, named `ava`, is in the `build` directory.
|
||||||
- Build the docker image of latest gecko branch by `scripts/build_image.sh`.
|
- 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
|
- 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.
|
`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,
|
--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
|
you may want to extend the docker image with required credentials for
|
||||||
staking and TLS.)
|
staking and TLS.)
|
||||||
|
|
|
@ -21,10 +21,30 @@ import (
|
||||||
"github.com/ava-labs/gecko/vms/components/codec"
|
"github.com/ava-labs/gecko/vms/components/codec"
|
||||||
|
|
||||||
jsoncodec "github.com/ava-labs/gecko/utils/json"
|
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 (
|
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 ...
|
// KeyValuePair ...
|
||||||
|
@ -114,7 +134,11 @@ func (ks *Keystore) CreateUser(_ *http.Request, args *CreateUserArgs, reply *Cre
|
||||||
ks.lock.Lock()
|
ks.lock.Lock()
|
||||||
defer ks.lock.Unlock()
|
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 == "" {
|
if args.Username == "" {
|
||||||
return errEmptyUsername
|
return errEmptyUsername
|
||||||
|
@ -123,6 +147,10 @@ func (ks *Keystore) CreateUser(_ *http.Request, args *CreateUserArgs, reply *Cre
|
||||||
return fmt.Errorf("user already exists: %s", args.Username)
|
return fmt.Errorf("user already exists: %s", args.Username)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if zxcvbn.PasswordStrength(args.Password, nil).Score < requiredPassScore {
|
||||||
|
return errWeakPassword
|
||||||
|
}
|
||||||
|
|
||||||
usr := &User{}
|
usr := &User{}
|
||||||
if err := usr.Initialize(args.Password); err != nil {
|
if err := usr.Initialize(args.Password); err != nil {
|
||||||
return err
|
return err
|
||||||
|
|
|
@ -5,6 +5,8 @@ package keystore
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
|
"fmt"
|
||||||
|
"math/rand"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/ava-labs/gecko/database/memdb"
|
"github.com/ava-labs/gecko/database/memdb"
|
||||||
|
@ -12,6 +14,12 @@ import (
|
||||||
"github.com/ava-labs/gecko/utils/logging"
|
"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) {
|
func TestServiceListNoUsers(t *testing.T) {
|
||||||
ks := Keystore{}
|
ks := Keystore{}
|
||||||
ks.Initialize(logging.NoLog{}, memdb.New())
|
ks.Initialize(logging.NoLog{}, memdb.New())
|
||||||
|
@ -33,7 +41,7 @@ func TestServiceCreateUser(t *testing.T) {
|
||||||
reply := CreateUserReply{}
|
reply := CreateUserReply{}
|
||||||
if err := ks.CreateUser(nil, &CreateUserArgs{
|
if err := ks.CreateUser(nil, &CreateUserArgs{
|
||||||
Username: "bob",
|
Username: "bob",
|
||||||
Password: "launch",
|
Password: strongPassword,
|
||||||
}, &reply); err != nil {
|
}, &reply); err != nil {
|
||||||
t.Fatal(err)
|
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) {
|
func TestServiceCreateDuplicate(t *testing.T) {
|
||||||
ks := Keystore{}
|
ks := Keystore{}
|
||||||
ks.Initialize(logging.NoLog{}, memdb.New())
|
ks.Initialize(logging.NoLog{}, memdb.New())
|
||||||
|
@ -64,7 +144,7 @@ func TestServiceCreateDuplicate(t *testing.T) {
|
||||||
reply := CreateUserReply{}
|
reply := CreateUserReply{}
|
||||||
if err := ks.CreateUser(nil, &CreateUserArgs{
|
if err := ks.CreateUser(nil, &CreateUserArgs{
|
||||||
Username: "bob",
|
Username: "bob",
|
||||||
Password: "launch",
|
Password: strongPassword,
|
||||||
}, &reply); err != nil {
|
}, &reply); err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
@ -77,7 +157,7 @@ func TestServiceCreateDuplicate(t *testing.T) {
|
||||||
reply := CreateUserReply{}
|
reply := CreateUserReply{}
|
||||||
if err := ks.CreateUser(nil, &CreateUserArgs{
|
if err := ks.CreateUser(nil, &CreateUserArgs{
|
||||||
Username: "bob",
|
Username: "bob",
|
||||||
Password: "launch!",
|
Password: strongPassword,
|
||||||
}, &reply); err == nil {
|
}, &reply); err == nil {
|
||||||
t.Fatalf("Should have errored due to the username already existing")
|
t.Fatalf("Should have errored due to the username already existing")
|
||||||
}
|
}
|
||||||
|
@ -90,7 +170,7 @@ func TestServiceCreateUserNoName(t *testing.T) {
|
||||||
|
|
||||||
reply := CreateUserReply{}
|
reply := CreateUserReply{}
|
||||||
if err := ks.CreateUser(nil, &CreateUserArgs{
|
if err := ks.CreateUser(nil, &CreateUserArgs{
|
||||||
Password: "launch",
|
Password: strongPassword,
|
||||||
}, &reply); err == nil {
|
}, &reply); err == nil {
|
||||||
t.Fatalf("Shouldn't have allowed empty username")
|
t.Fatalf("Shouldn't have allowed empty username")
|
||||||
}
|
}
|
||||||
|
@ -104,7 +184,7 @@ func TestServiceUseBlockchainDB(t *testing.T) {
|
||||||
reply := CreateUserReply{}
|
reply := CreateUserReply{}
|
||||||
if err := ks.CreateUser(nil, &CreateUserArgs{
|
if err := ks.CreateUser(nil, &CreateUserArgs{
|
||||||
Username: "bob",
|
Username: "bob",
|
||||||
Password: "launch",
|
Password: strongPassword,
|
||||||
}, &reply); err != nil {
|
}, &reply); err != nil {
|
||||||
t.Fatal(err)
|
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 {
|
if err != nil {
|
||||||
t.Fatal(err)
|
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 {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
@ -144,7 +224,7 @@ func TestServiceExportImport(t *testing.T) {
|
||||||
reply := CreateUserReply{}
|
reply := CreateUserReply{}
|
||||||
if err := ks.CreateUser(nil, &CreateUserArgs{
|
if err := ks.CreateUser(nil, &CreateUserArgs{
|
||||||
Username: "bob",
|
Username: "bob",
|
||||||
Password: "launch",
|
Password: strongPassword,
|
||||||
}, &reply); err != nil {
|
}, &reply); err != nil {
|
||||||
t.Fatal(err)
|
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 {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
@ -166,7 +246,7 @@ func TestServiceExportImport(t *testing.T) {
|
||||||
exportReply := ExportUserReply{}
|
exportReply := ExportUserReply{}
|
||||||
if err := ks.ExportUser(nil, &ExportUserArgs{
|
if err := ks.ExportUser(nil, &ExportUserArgs{
|
||||||
Username: "bob",
|
Username: "bob",
|
||||||
Password: "launch",
|
Password: strongPassword,
|
||||||
}, &exportReply); err != nil {
|
}, &exportReply); err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
@ -178,7 +258,7 @@ func TestServiceExportImport(t *testing.T) {
|
||||||
reply := ImportUserReply{}
|
reply := ImportUserReply{}
|
||||||
if err := newKS.ImportUser(nil, &ImportUserArgs{
|
if err := newKS.ImportUser(nil, &ImportUserArgs{
|
||||||
Username: "bob",
|
Username: "bob",
|
||||||
Password: "launch",
|
Password: strongPassword,
|
||||||
User: exportReply.User,
|
User: exportReply.User,
|
||||||
}, &reply); err != nil {
|
}, &reply); err != nil {
|
||||||
t.Fatal(err)
|
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 {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,28 @@
|
||||||
|
// (c) 2019-2020, Ava Labs, Inc. All rights reserved.
|
||||||
|
// See the file LICENSE for licensing terms.
|
||||||
|
|
||||||
|
package atomic
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/ava-labs/gecko/database"
|
||||||
|
"github.com/ava-labs/gecko/ids"
|
||||||
|
)
|
||||||
|
|
||||||
|
// BlockchainSharedMemory provides the API for a blockchain to interact with
|
||||||
|
// shared memory of another blockchain
|
||||||
|
type BlockchainSharedMemory struct {
|
||||||
|
blockchainID ids.ID
|
||||||
|
sm *SharedMemory
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetDatabase returns and locks the provided DB
|
||||||
|
func (bsm *BlockchainSharedMemory) GetDatabase(id ids.ID) database.Database {
|
||||||
|
sharedID := bsm.sm.sharedID(id, bsm.blockchainID)
|
||||||
|
return bsm.sm.GetDatabase(sharedID)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ReleaseDatabase unlocks the provided DB
|
||||||
|
func (bsm *BlockchainSharedMemory) ReleaseDatabase(id ids.ID) {
|
||||||
|
sharedID := bsm.sm.sharedID(id, bsm.blockchainID)
|
||||||
|
bsm.sm.ReleaseDatabase(sharedID)
|
||||||
|
}
|
|
@ -0,0 +1,34 @@
|
||||||
|
// (c) 2019-2020, Ava Labs, Inc. All rights reserved.
|
||||||
|
// See the file LICENSE for licensing terms.
|
||||||
|
|
||||||
|
package atomic
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/ava-labs/gecko/database/memdb"
|
||||||
|
"github.com/ava-labs/gecko/utils/logging"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestBlockchainSharedMemory(t *testing.T) {
|
||||||
|
sm := SharedMemory{}
|
||||||
|
sm.Initialize(logging.NoLog{}, memdb.New())
|
||||||
|
|
||||||
|
bsm0 := sm.NewBlockchainSharedMemory(blockchainID0)
|
||||||
|
bsm1 := sm.NewBlockchainSharedMemory(blockchainID1)
|
||||||
|
|
||||||
|
sharedDB0 := bsm0.GetDatabase(blockchainID1)
|
||||||
|
if err := sharedDB0.Put([]byte{1}, []byte{2}); err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
bsm0.ReleaseDatabase(blockchainID1)
|
||||||
|
|
||||||
|
sharedDB1 := bsm1.GetDatabase(blockchainID0)
|
||||||
|
if value, err := sharedDB1.Get([]byte{1}); err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
} else if !bytes.Equal(value, []byte{2}) {
|
||||||
|
t.Fatalf("database.Get Returned: 0x%x ; Expected: 0x%x", value, []byte{2})
|
||||||
|
}
|
||||||
|
bsm1.ReleaseDatabase(blockchainID0)
|
||||||
|
}
|
|
@ -0,0 +1,105 @@
|
||||||
|
// (c) 2019-2020, Ava Labs, Inc. All rights reserved.
|
||||||
|
// See the file LICENSE for licensing terms.
|
||||||
|
|
||||||
|
package atomic
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"sync"
|
||||||
|
|
||||||
|
"github.com/ava-labs/gecko/database"
|
||||||
|
"github.com/ava-labs/gecko/database/prefixdb"
|
||||||
|
"github.com/ava-labs/gecko/ids"
|
||||||
|
"github.com/ava-labs/gecko/utils/hashing"
|
||||||
|
"github.com/ava-labs/gecko/utils/logging"
|
||||||
|
"github.com/ava-labs/gecko/vms/components/codec"
|
||||||
|
)
|
||||||
|
|
||||||
|
type rcLock struct {
|
||||||
|
lock sync.Mutex
|
||||||
|
count int
|
||||||
|
}
|
||||||
|
|
||||||
|
// SharedMemory is the interface for shared memory inside a subnet
|
||||||
|
type SharedMemory struct {
|
||||||
|
lock sync.Mutex
|
||||||
|
log logging.Logger
|
||||||
|
codec codec.Codec
|
||||||
|
locks map[[32]byte]*rcLock
|
||||||
|
db database.Database
|
||||||
|
}
|
||||||
|
|
||||||
|
// Initialize the SharedMemory
|
||||||
|
func (sm *SharedMemory) Initialize(log logging.Logger, db database.Database) {
|
||||||
|
sm.log = log
|
||||||
|
sm.codec = codec.NewDefault()
|
||||||
|
sm.locks = make(map[[32]byte]*rcLock)
|
||||||
|
sm.db = db
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewBlockchainSharedMemory returns a new BlockchainSharedMemory
|
||||||
|
func (sm *SharedMemory) NewBlockchainSharedMemory(id ids.ID) *BlockchainSharedMemory {
|
||||||
|
return &BlockchainSharedMemory{
|
||||||
|
blockchainID: id,
|
||||||
|
sm: sm,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetDatabase returns and locks the provided DB
|
||||||
|
func (sm *SharedMemory) GetDatabase(id ids.ID) database.Database {
|
||||||
|
lock := sm.makeLock(id)
|
||||||
|
lock.Lock()
|
||||||
|
|
||||||
|
return prefixdb.New(id.Bytes(), sm.db)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ReleaseDatabase unlocks the provided DB
|
||||||
|
func (sm *SharedMemory) ReleaseDatabase(id ids.ID) {
|
||||||
|
lock := sm.releaseLock(id)
|
||||||
|
lock.Unlock()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (sm *SharedMemory) makeLock(id ids.ID) *sync.Mutex {
|
||||||
|
sm.lock.Lock()
|
||||||
|
defer sm.lock.Unlock()
|
||||||
|
|
||||||
|
key := id.Key()
|
||||||
|
rc, exists := sm.locks[key]
|
||||||
|
if !exists {
|
||||||
|
rc = &rcLock{}
|
||||||
|
sm.locks[key] = rc
|
||||||
|
}
|
||||||
|
rc.count++
|
||||||
|
return &rc.lock
|
||||||
|
}
|
||||||
|
|
||||||
|
func (sm *SharedMemory) releaseLock(id ids.ID) *sync.Mutex {
|
||||||
|
sm.lock.Lock()
|
||||||
|
defer sm.lock.Unlock()
|
||||||
|
|
||||||
|
key := id.Key()
|
||||||
|
rc, exists := sm.locks[key]
|
||||||
|
if !exists {
|
||||||
|
panic("Attemping to free an unknown lock")
|
||||||
|
}
|
||||||
|
rc.count--
|
||||||
|
if rc.count == 0 {
|
||||||
|
delete(sm.locks, key)
|
||||||
|
}
|
||||||
|
return &rc.lock
|
||||||
|
}
|
||||||
|
|
||||||
|
// sharedID calculates the ID of the shared memory space
|
||||||
|
func (sm *SharedMemory) sharedID(id1, id2 ids.ID) ids.ID {
|
||||||
|
idKey1 := id1.Key()
|
||||||
|
idKey2 := id2.Key()
|
||||||
|
|
||||||
|
if bytes.Compare(idKey1[:], idKey2[:]) == 1 {
|
||||||
|
idKey1, idKey2 = idKey2, idKey1
|
||||||
|
}
|
||||||
|
|
||||||
|
combinedBytes, err := sm.codec.Marshal([2][32]byte{idKey1, idKey2})
|
||||||
|
sm.log.AssertNoError(err)
|
||||||
|
|
||||||
|
return ids.NewID(hashing.ComputeHash256Array(combinedBytes))
|
||||||
|
}
|
|
@ -0,0 +1,69 @@
|
||||||
|
// (c) 2019-2020, Ava Labs, Inc. All rights reserved.
|
||||||
|
// See the file LICENSE for licensing terms.
|
||||||
|
|
||||||
|
package atomic
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/ava-labs/gecko/database/memdb"
|
||||||
|
"github.com/ava-labs/gecko/ids"
|
||||||
|
"github.com/ava-labs/gecko/utils/logging"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
blockchainID0 = ids.Empty.Prefix(0)
|
||||||
|
blockchainID1 = ids.Empty.Prefix(1)
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestSharedMemorySharedID(t *testing.T) {
|
||||||
|
sm := SharedMemory{}
|
||||||
|
sm.Initialize(logging.NoLog{}, memdb.New())
|
||||||
|
|
||||||
|
sharedID0 := sm.sharedID(blockchainID0, blockchainID1)
|
||||||
|
sharedID1 := sm.sharedID(blockchainID1, blockchainID0)
|
||||||
|
|
||||||
|
if !sharedID0.Equals(sharedID1) {
|
||||||
|
t.Fatalf("SharedMemory.sharedID should be communitive")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestSharedMemoryMakeReleaseLock(t *testing.T) {
|
||||||
|
sm := SharedMemory{}
|
||||||
|
sm.Initialize(logging.NoLog{}, memdb.New())
|
||||||
|
|
||||||
|
sharedID := sm.sharedID(blockchainID0, blockchainID1)
|
||||||
|
|
||||||
|
lock0 := sm.makeLock(sharedID)
|
||||||
|
|
||||||
|
if lock1 := sm.makeLock(sharedID); lock0 != lock1 {
|
||||||
|
t.Fatalf("SharedMemory.makeLock should have returned the same lock")
|
||||||
|
}
|
||||||
|
sm.releaseLock(sharedID)
|
||||||
|
|
||||||
|
if lock2 := sm.makeLock(sharedID); lock0 != lock2 {
|
||||||
|
t.Fatalf("SharedMemory.makeLock should have returned the same lock")
|
||||||
|
}
|
||||||
|
sm.releaseLock(sharedID)
|
||||||
|
sm.releaseLock(sharedID)
|
||||||
|
|
||||||
|
if lock3 := sm.makeLock(sharedID); lock0 == lock3 {
|
||||||
|
t.Fatalf("SharedMemory.releaseLock should have returned freed the lock")
|
||||||
|
}
|
||||||
|
sm.releaseLock(sharedID)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestSharedMemoryUnknownFree(t *testing.T) {
|
||||||
|
sm := SharedMemory{}
|
||||||
|
sm.Initialize(logging.NoLog{}, memdb.New())
|
||||||
|
|
||||||
|
sharedID := sm.sharedID(blockchainID0, blockchainID1)
|
||||||
|
|
||||||
|
defer func() {
|
||||||
|
if recover() == nil {
|
||||||
|
t.Fatalf("Should have panicked due to an unknown free")
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
|
||||||
|
sm.releaseLock(sharedID)
|
||||||
|
}
|
|
@ -0,0 +1,21 @@
|
||||||
|
// (c) 2019-2020, Ava Labs, Inc. All rights reserved.
|
||||||
|
// See the file LICENSE for licensing terms.
|
||||||
|
|
||||||
|
package atomic
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/ava-labs/gecko/database"
|
||||||
|
)
|
||||||
|
|
||||||
|
// WriteAll assumes all batches have the same underlying database. Batches
|
||||||
|
// should not be modified after being passed to this function.
|
||||||
|
func WriteAll(baseBatch database.Batch, batches ...database.Batch) error {
|
||||||
|
baseBatch = baseBatch.Inner()
|
||||||
|
for _, batch := range batches {
|
||||||
|
batch = batch.Inner()
|
||||||
|
if err := batch.Replay(baseBatch); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return baseBatch.Write()
|
||||||
|
}
|
|
@ -0,0 +1,61 @@
|
||||||
|
// (c) 2019-2020, Ava Labs, Inc. All rights reserved.
|
||||||
|
// See the file LICENSE for licensing terms.
|
||||||
|
|
||||||
|
package atomic
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/ava-labs/gecko/database/memdb"
|
||||||
|
"github.com/ava-labs/gecko/database/prefixdb"
|
||||||
|
"github.com/ava-labs/gecko/database/versiondb"
|
||||||
|
"github.com/ava-labs/gecko/utils/logging"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestWriteAll(t *testing.T) {
|
||||||
|
baseDB := memdb.New()
|
||||||
|
prefixedDBChain := prefixdb.New([]byte{0}, baseDB)
|
||||||
|
prefixedDBSharedMemory := prefixdb.New([]byte{1}, baseDB)
|
||||||
|
|
||||||
|
sm := SharedMemory{}
|
||||||
|
sm.Initialize(logging.NoLog{}, prefixedDBSharedMemory)
|
||||||
|
|
||||||
|
sharedID := sm.sharedID(blockchainID0, blockchainID1)
|
||||||
|
|
||||||
|
sharedDB := sm.GetDatabase(sharedID)
|
||||||
|
|
||||||
|
writeDB0 := versiondb.New(prefixedDBChain)
|
||||||
|
writeDB1 := versiondb.New(sharedDB)
|
||||||
|
defer sm.ReleaseDatabase(sharedID)
|
||||||
|
|
||||||
|
if err := writeDB0.Put([]byte{1}, []byte{2}); err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
if err := writeDB1.Put([]byte{2}, []byte{3}); err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
batch0, err := writeDB0.CommitBatch()
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
batch1, err := writeDB1.CommitBatch()
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := WriteAll(batch0, batch1); err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if value, err := prefixedDBChain.Get([]byte{1}); err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
} else if !bytes.Equal(value, []byte{2}) {
|
||||||
|
t.Fatalf("database.Get Returned: 0x%x ; Expected: 0x%x", value, []byte{2})
|
||||||
|
} else if value, err := sharedDB.Get([]byte{2}); err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
} else if !bytes.Equal(value, []byte{3}) {
|
||||||
|
t.Fatalf("database.Get Returned: 0x%x ; Expected: 0x%x", value, []byte{3})
|
||||||
|
}
|
||||||
|
}
|
|
@ -9,6 +9,7 @@ import (
|
||||||
|
|
||||||
"github.com/ava-labs/gecko/api"
|
"github.com/ava-labs/gecko/api"
|
||||||
"github.com/ava-labs/gecko/api/keystore"
|
"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"
|
||||||
"github.com/ava-labs/gecko/database/prefixdb"
|
"github.com/ava-labs/gecko/database/prefixdb"
|
||||||
"github.com/ava-labs/gecko/ids"
|
"github.com/ava-labs/gecko/ids"
|
||||||
|
@ -26,6 +27,7 @@ import (
|
||||||
"github.com/ava-labs/gecko/snow/triggers"
|
"github.com/ava-labs/gecko/snow/triggers"
|
||||||
"github.com/ava-labs/gecko/snow/validators"
|
"github.com/ava-labs/gecko/snow/validators"
|
||||||
"github.com/ava-labs/gecko/utils/logging"
|
"github.com/ava-labs/gecko/utils/logging"
|
||||||
|
"github.com/ava-labs/gecko/utils/math"
|
||||||
"github.com/ava-labs/gecko/vms"
|
"github.com/ava-labs/gecko/vms"
|
||||||
|
|
||||||
avacon "github.com/ava-labs/gecko/snow/consensus/avalanche"
|
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
|
// That is, [chainID].String() is an alias for the chain, too
|
||||||
ids.Aliaser
|
ids.Aliaser
|
||||||
|
|
||||||
|
stakingEnabled bool // True iff the network has staking enabled
|
||||||
log logging.Logger
|
log logging.Logger
|
||||||
logFactory logging.Factory
|
logFactory logging.Factory
|
||||||
vmManager vms.Manager // Manage mappings from vm ID --> vm
|
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
|
awaiter Awaiter // Waits for required connections before running bootstrapping
|
||||||
server *api.Server // Handles HTTP API calls
|
server *api.Server // Handles HTTP API calls
|
||||||
keystore *keystore.Keystore
|
keystore *keystore.Keystore
|
||||||
|
sharedMemory *atomic.SharedMemory
|
||||||
|
|
||||||
unblocked bool
|
unblocked bool
|
||||||
blockedChains []ChainParameters
|
blockedChains []ChainParameters
|
||||||
|
@ -120,6 +124,7 @@ type manager struct {
|
||||||
// <validators> validate this chain
|
// <validators> validate this chain
|
||||||
// TODO: Make this function take less arguments
|
// TODO: Make this function take less arguments
|
||||||
func New(
|
func New(
|
||||||
|
stakingEnabled bool,
|
||||||
log logging.Logger,
|
log logging.Logger,
|
||||||
logFactory logging.Factory,
|
logFactory logging.Factory,
|
||||||
vmManager vms.Manager,
|
vmManager vms.Manager,
|
||||||
|
@ -135,6 +140,7 @@ func New(
|
||||||
awaiter Awaiter,
|
awaiter Awaiter,
|
||||||
server *api.Server,
|
server *api.Server,
|
||||||
keystore *keystore.Keystore,
|
keystore *keystore.Keystore,
|
||||||
|
sharedMemory *atomic.SharedMemory,
|
||||||
) Manager {
|
) Manager {
|
||||||
timeoutManager := timeout.Manager{}
|
timeoutManager := timeout.Manager{}
|
||||||
timeoutManager.Initialize(requestTimeout)
|
timeoutManager.Initialize(requestTimeout)
|
||||||
|
@ -143,6 +149,7 @@ func New(
|
||||||
router.Initialize(log, &timeoutManager)
|
router.Initialize(log, &timeoutManager)
|
||||||
|
|
||||||
m := &manager{
|
m := &manager{
|
||||||
|
stakingEnabled: stakingEnabled,
|
||||||
log: log,
|
log: log,
|
||||||
logFactory: logFactory,
|
logFactory: logFactory,
|
||||||
vmManager: vmManager,
|
vmManager: vmManager,
|
||||||
|
@ -159,6 +166,7 @@ func New(
|
||||||
awaiter: awaiter,
|
awaiter: awaiter,
|
||||||
server: server,
|
server: server,
|
||||||
keystore: keystore,
|
keystore: keystore,
|
||||||
|
sharedMemory: sharedMemory,
|
||||||
}
|
}
|
||||||
m.Initialize()
|
m.Initialize()
|
||||||
return m
|
return m
|
||||||
|
@ -246,6 +254,7 @@ func (m *manager) ForceCreateChain(chain ChainParameters) {
|
||||||
NodeID: m.nodeID,
|
NodeID: m.nodeID,
|
||||||
HTTP: m.server,
|
HTTP: m.server,
|
||||||
Keystore: m.keystore.NewBlockchainKeyStore(chain.ID),
|
Keystore: m.keystore.NewBlockchainKeyStore(chain.ID),
|
||||||
|
SharedMemory: m.sharedMemory.NewBlockchainSharedMemory(chain.ID),
|
||||||
BCLookup: m,
|
BCLookup: m,
|
||||||
}
|
}
|
||||||
consensusParams := m.consensusParams
|
consensusParams := m.consensusParams
|
||||||
|
@ -256,7 +265,13 @@ func (m *manager) ForceCreateChain(chain ChainParameters) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// The validators of this blockchain
|
// 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 {
|
if !ok {
|
||||||
m.log.Error("couldn't get validator set of subnet with ID %s. The subnet may not exist", chain.SubnetID)
|
m.log.Error("couldn't get validator set of subnet with ID %s. The subnet may not exist", chain.SubnetID)
|
||||||
return
|
return
|
||||||
|
@ -353,7 +368,7 @@ func (m *manager) createAvalancheChain(
|
||||||
msgChan := make(chan common.Message, defaultChannelSize)
|
msgChan := make(chan common.Message, defaultChannelSize)
|
||||||
|
|
||||||
if err := vm.Initialize(ctx, vmDB, genesisData, msgChan, fxs); err != nil {
|
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
|
// Handles serialization/deserialization of vertices and also the
|
||||||
|
@ -376,13 +391,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{
|
engine.Initialize(avaeng.Config{
|
||||||
BootstrapConfig: avaeng.BootstrapConfig{
|
BootstrapConfig: avaeng.BootstrapConfig{
|
||||||
Config: common.Config{
|
Config: common.Config{
|
||||||
Context: ctx,
|
Context: ctx,
|
||||||
Validators: validators,
|
Validators: validators,
|
||||||
Beacons: beacons,
|
Beacons: beacons,
|
||||||
Alpha: (beacons.Len() + 1) / 2,
|
Alpha: bootstrapWeight/2 + 1, // must be > 50%
|
||||||
Sender: &sender,
|
Sender: &sender,
|
||||||
},
|
},
|
||||||
VtxBlocked: vtxBlocker,
|
VtxBlocked: vtxBlocker,
|
||||||
|
@ -403,6 +427,8 @@ func (m *manager) createAvalancheChain(
|
||||||
go ctx.Log.RecoverAndPanic(handler.Dispatch)
|
go ctx.Log.RecoverAndPanic(handler.Dispatch)
|
||||||
|
|
||||||
awaiting := &networking.AwaitingConnections{
|
awaiting := &networking.AwaitingConnections{
|
||||||
|
Requested: beacons,
|
||||||
|
WeightRequired: (3*bootstrapWeight + 3) / 4, // 75% must be connected to
|
||||||
Finish: func() {
|
Finish: func() {
|
||||||
ctx.Lock.Lock()
|
ctx.Lock.Lock()
|
||||||
defer ctx.Lock.Unlock()
|
defer ctx.Lock.Unlock()
|
||||||
|
@ -410,10 +436,6 @@ func (m *manager) createAvalancheChain(
|
||||||
engine.Startup()
|
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)
|
m.awaiter.AwaitConnections(awaiting)
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
|
@ -454,6 +476,15 @@ func (m *manager) createSnowmanChain(
|
||||||
sender := sender.Sender{}
|
sender := sender.Sender{}
|
||||||
sender.Initialize(ctx, m.sender, m.chainRouter, m.timeoutManager)
|
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
|
// The engine handles consensus
|
||||||
engine := smeng.Transitive{}
|
engine := smeng.Transitive{}
|
||||||
engine.Initialize(smeng.Config{
|
engine.Initialize(smeng.Config{
|
||||||
|
@ -462,7 +493,7 @@ func (m *manager) createSnowmanChain(
|
||||||
Context: ctx,
|
Context: ctx,
|
||||||
Validators: validators,
|
Validators: validators,
|
||||||
Beacons: beacons,
|
Beacons: beacons,
|
||||||
Alpha: (beacons.Len() + 1) / 2,
|
Alpha: bootstrapWeight/2 + 1, // must be > 50%
|
||||||
Sender: &sender,
|
Sender: &sender,
|
||||||
},
|
},
|
||||||
Blocked: blocked,
|
Blocked: blocked,
|
||||||
|
@ -482,6 +513,8 @@ func (m *manager) createSnowmanChain(
|
||||||
go ctx.Log.RecoverAndPanic(handler.Dispatch)
|
go ctx.Log.RecoverAndPanic(handler.Dispatch)
|
||||||
|
|
||||||
awaiting := &networking.AwaitingConnections{
|
awaiting := &networking.AwaitingConnections{
|
||||||
|
Requested: beacons,
|
||||||
|
WeightRequired: (3*bootstrapWeight + 3) / 4, // 75% must be connected to
|
||||||
Finish: func() {
|
Finish: func() {
|
||||||
ctx.Lock.Lock()
|
ctx.Lock.Lock()
|
||||||
defer ctx.Lock.Unlock()
|
defer ctx.Lock.Unlock()
|
||||||
|
@ -489,10 +522,6 @@ func (m *manager) createSnowmanChain(
|
||||||
engine.Startup()
|
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)
|
m.awaiter.AwaitConnections(awaiting)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,37 @@
|
||||||
|
package chains
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/ava-labs/gecko/ids"
|
||||||
|
"github.com/ava-labs/gecko/snow/networking/router"
|
||||||
|
)
|
||||||
|
|
||||||
|
// MockManager implements Manager but does nothing. Always returns nil error.
|
||||||
|
// To be used only in tests (namely in package platformvm)
|
||||||
|
type MockManager struct{}
|
||||||
|
|
||||||
|
// Router ...
|
||||||
|
func (mm MockManager) Router() router.Router { return nil }
|
||||||
|
|
||||||
|
// CreateChain ...
|
||||||
|
func (mm MockManager) CreateChain(ChainParameters) {}
|
||||||
|
|
||||||
|
// ForceCreateChain ...
|
||||||
|
func (mm MockManager) ForceCreateChain(ChainParameters) {}
|
||||||
|
|
||||||
|
// AddRegistrant ...
|
||||||
|
func (mm MockManager) AddRegistrant(Registrant) {}
|
||||||
|
|
||||||
|
// Lookup ...
|
||||||
|
func (mm MockManager) Lookup(string) (ids.ID, error) { return ids.ID{}, nil }
|
||||||
|
|
||||||
|
// LookupVM ...
|
||||||
|
func (mm MockManager) LookupVM(string) (ids.ID, error) { return ids.ID{}, nil }
|
||||||
|
|
||||||
|
// Aliases ...
|
||||||
|
func (mm MockManager) Aliases(ids.ID) []string { return nil }
|
||||||
|
|
||||||
|
// Alias ...
|
||||||
|
func (mm MockManager) Alias(ids.ID, string) error { return nil }
|
||||||
|
|
||||||
|
// Shutdown ...
|
||||||
|
func (mm MockManager) Shutdown() {}
|
|
@ -23,6 +23,11 @@ type Batch interface {
|
||||||
|
|
||||||
// Replay replays the batch contents.
|
// Replay replays the batch contents.
|
||||||
Replay(w KeyValueWriter) error
|
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.
|
// Batcher wraps the NewBatch method of a backing data store.
|
||||||
|
|
|
@ -184,6 +184,9 @@ func (b *batch) Replay(w database.KeyValueWriter) error {
|
||||||
return updateError(replay.err)
|
return updateError(replay.err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Inner returns itself
|
||||||
|
func (b *batch) Inner() database.Batch { return b }
|
||||||
|
|
||||||
type replayer struct {
|
type replayer struct {
|
||||||
writer database.KeyValueWriter
|
writer database.KeyValueWriter
|
||||||
err error
|
err error
|
||||||
|
|
|
@ -208,6 +208,9 @@ func (b *batch) Replay(w database.KeyValueWriter) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Inner returns itself
|
||||||
|
func (b *batch) Inner() database.Batch { return b }
|
||||||
|
|
||||||
type iterator struct {
|
type iterator struct {
|
||||||
initialized bool
|
initialized bool
|
||||||
keys []string
|
keys []string
|
||||||
|
|
|
@ -69,6 +69,9 @@ func (*Batch) Reset() {}
|
||||||
// Replay does nothing
|
// Replay does nothing
|
||||||
func (*Batch) Replay(database.KeyValueWriter) error { return database.ErrClosed }
|
func (*Batch) Replay(database.KeyValueWriter) error { return database.ErrClosed }
|
||||||
|
|
||||||
|
// Inner returns itself
|
||||||
|
func (b *Batch) Inner() database.Batch { return b }
|
||||||
|
|
||||||
// Iterator does nothing
|
// Iterator does nothing
|
||||||
type Iterator struct{ Err error }
|
type Iterator struct{ Err error }
|
||||||
|
|
||||||
|
|
|
@ -17,6 +17,7 @@ var (
|
||||||
TestBatchDelete,
|
TestBatchDelete,
|
||||||
TestBatchReset,
|
TestBatchReset,
|
||||||
TestBatchReplay,
|
TestBatchReplay,
|
||||||
|
TestBatchInner,
|
||||||
TestIterator,
|
TestIterator,
|
||||||
TestIteratorStart,
|
TestIteratorStart,
|
||||||
TestIteratorPrefix,
|
TestIteratorPrefix,
|
||||||
|
@ -299,6 +300,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 ...
|
// TestIterator ...
|
||||||
func TestIterator(t *testing.T, db Database) {
|
func TestIterator(t *testing.T, db Database) {
|
||||||
key1 := []byte("hello1")
|
key1 := []byte("hello1")
|
||||||
|
|
|
@ -184,29 +184,55 @@ func (db *Database) Commit() error {
|
||||||
db.lock.Lock()
|
db.lock.Lock()
|
||||||
defer db.lock.Unlock()
|
defer db.lock.Unlock()
|
||||||
|
|
||||||
if db.mem == nil {
|
batch, err := db.commitBatch()
|
||||||
return database.ErrClosed
|
if err != nil {
|
||||||
|
return err
|
||||||
}
|
}
|
||||||
if len(db.mem) == 0 {
|
if err := batch.Write(); err != nil {
|
||||||
return 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()
|
batch := db.db.NewBatch()
|
||||||
for key, value := range db.mem {
|
for key, value := range db.mem {
|
||||||
if value.delete {
|
if value.delete {
|
||||||
if err := batch.Delete([]byte(key)); err != nil {
|
if err := batch.Delete([]byte(key)); err != nil {
|
||||||
return err
|
return nil, err
|
||||||
}
|
}
|
||||||
} else if err := batch.Put([]byte(key), value.value); err != nil {
|
} else if err := batch.Put([]byte(key), value.value); err != nil {
|
||||||
return err
|
return nil, err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if err := batch.Write(); err != nil {
|
if err := batch.Write(); err != nil {
|
||||||
return err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
db.mem = make(map[string]valueDelete, memdb.DefaultSize)
|
return batch, nil
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Close implements the database.Database interface
|
// Close implements the database.Database interface
|
||||||
|
@ -289,6 +315,9 @@ func (b *batch) Replay(w database.KeyValueWriter) error {
|
||||||
return nil
|
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
|
// iterator walks over both the in memory database and the underlying database
|
||||||
// at the same time.
|
// at the same time.
|
||||||
type iterator struct {
|
type iterator struct {
|
||||||
|
|
|
@ -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) {
|
func TestSetDatabase(t *testing.T) {
|
||||||
baseDB := memdb.New()
|
baseDB := memdb.New()
|
||||||
newDB := memdb.New()
|
newDB := memdb.New()
|
||||||
|
|
|
@ -0,0 +1,78 @@
|
||||||
|
// (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/evm"
|
||||||
|
"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/" + 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"},
|
||||||
|
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 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 generalAliases, chainAliases, vmAliases, nil
|
||||||
|
}
|
|
@ -0,0 +1,108 @@
|
||||||
|
// (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/evm"
|
||||||
|
)
|
||||||
|
|
||||||
|
// 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, FundedEVMAddresses, StakerIDs []string
|
||||||
|
ParsedMintAddresses, ParsedFundedAddresses, ParsedStakerIDs []ids.ShortID
|
||||||
|
}
|
||||||
|
|
||||||
|
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",
|
||||||
|
},
|
||||||
|
FundedEVMAddresses: []string{
|
||||||
|
"0x572f4D80f10f663B5049F789546f25f70Bb62a7F",
|
||||||
|
},
|
||||||
|
StakerIDs: []string{
|
||||||
|
"NX4zVkuiRJZYe6Nzzav7GXN3TakUet3Co",
|
||||||
|
"CMsa8cMw4eib1Hb8GG4xiUKAq5eE1BwUX",
|
||||||
|
"DsMP6jLhi1MkDVc3qx9xx9AAZWx8e87Jd",
|
||||||
|
"N86eodVZja3GEyZJTo3DFUPGpxEEvjGHs",
|
||||||
|
"EkKeGSLUbHrrtuayBtbwgWDRUiAziC3ao",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
DefaultConfig = Config{
|
||||||
|
MintAddresses: []string{},
|
||||||
|
FundedAddresses: []string{
|
||||||
|
// Private key: ewoqjP7PxY4yr3iLTpLisriqt94hdyDFNgchSxGGztUrTXtNN
|
||||||
|
"6Y3kysjF9jnHnYkdS9yGAuoHyae2eNmeV",
|
||||||
|
},
|
||||||
|
FundedEVMAddresses: []string{
|
||||||
|
// Private key: evm.GenesisTestKey
|
||||||
|
evm.GenesisTestAddr,
|
||||||
|
},
|
||||||
|
StakerIDs: []string{
|
||||||
|
"7Xhw2mDxuDS44j42TCB6U5579esbSt3Lg",
|
||||||
|
"MFrZFVCXPv5iCn6M9K6XduxGTYp891xXZ",
|
||||||
|
"NFBbbJ4qCmNaCzeW7sxErhvWqvEQMnYcN",
|
||||||
|
"GWPcbFJZFfZreETSoWjPimr846mXEKCtu",
|
||||||
|
"P7oB2McjBGgW2NXXWVYjV8JEDFoW9xDE5",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
// GetConfig ...
|
||||||
|
func GetConfig(networkID uint32) *Config {
|
||||||
|
switch networkID {
|
||||||
|
case CascadeID:
|
||||||
|
return &CascadeConfig
|
||||||
|
default:
|
||||||
|
return &DefaultConfig
|
||||||
|
}
|
||||||
|
}
|
|
@ -3,511 +3,316 @@
|
||||||
|
|
||||||
package genesis
|
package genesis
|
||||||
|
|
||||||
// TODO: Move this to a separate repo and leave only a byte array
|
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"math"
|
"math/big"
|
||||||
"regexp"
|
"time"
|
||||||
"strconv"
|
|
||||||
"strings"
|
"github.com/ava-labs/coreth/core"
|
||||||
|
|
||||||
|
"github.com/ava-labs/go-ethereum/common"
|
||||||
|
"github.com/ava-labs/go-ethereum/params"
|
||||||
|
|
||||||
"github.com/ava-labs/gecko/ids"
|
"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/avm"
|
||||||
|
"github.com/ava-labs/gecko/vms/components/codec"
|
||||||
"github.com/ava-labs/gecko/vms/evm"
|
"github.com/ava-labs/gecko/vms/evm"
|
||||||
|
"github.com/ava-labs/gecko/vms/nftfx"
|
||||||
"github.com/ava-labs/gecko/vms/platformvm"
|
"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/spchainvm"
|
||||||
"github.com/ava-labs/gecko/vms/spdagvm"
|
"github.com/ava-labs/gecko/vms/spdagvm"
|
||||||
"github.com/ava-labs/gecko/vms/timestampvm"
|
"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"
|
|
||||||
)
|
|
||||||
|
|
||||||
var (
|
|
||||||
validNetworkName = regexp.MustCompile(`network-[0-9]+`)
|
|
||||||
)
|
|
||||||
|
|
||||||
// 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.
|
// Genesis returns the genesis data of the Platform Chain.
|
||||||
// Since the Platform Chain causes the creation of all other
|
// Since an AVA network has exactly one Platform Chain, and the Platform Chain
|
||||||
// chains, this function returns the genesis data of the entire network.
|
// 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].
|
// The ID of the new network is [networkID].
|
||||||
func Genesis(networkID uint32) []byte {
|
|
||||||
if networkID != LocalID {
|
// FromConfig ...
|
||||||
panic("unknown network ID provided")
|
func FromConfig(networkID uint32, config *Config) ([]byte, error) {
|
||||||
|
if err := config.init(); err != nil {
|
||||||
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
return []byte{
|
// Specify the genesis state of the AVM
|
||||||
0x00, 0x00, 0x00, 0x01, 0x3c, 0xb7, 0xd3, 0x84,
|
avmArgs := avm.BuildGenesisArgs{}
|
||||||
0x2e, 0x8c, 0xee, 0x6a, 0x0e, 0xbd, 0x09, 0xf1,
|
{
|
||||||
0xfe, 0x88, 0x4f, 0x68, 0x61, 0xe1, 0xb2, 0x9c,
|
ava := avm.AssetDefinition{
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
Name: "AVA",
|
||||||
0x00, 0x00, 0x12, 0x30, 0x9c, 0xe5, 0x40, 0x00,
|
Symbol: "AVA",
|
||||||
0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00,
|
Denomination: 9,
|
||||||
0x05, 0xde, 0x31, 0xb4, 0xd8, 0xb2, 0x29, 0x91,
|
InitialState: map[string][]interface{}{},
|
||||||
0xd5, 0x1a, 0xa6, 0xaa, 0x1f, 0xc7, 0x33, 0xf2,
|
}
|
||||||
0x3a, 0x85, 0x1a, 0x8c, 0x94, 0x00, 0x00, 0x12,
|
|
||||||
0x30, 0x9c, 0xe5, 0x40, 0x00, 0x00, 0x00, 0x00,
|
if len(config.MintAddresses) > 0 {
|
||||||
0x00, 0x5d, 0xbb, 0x75, 0x80, 0x00, 0x00, 0x00,
|
ava.InitialState["variableCap"] = []interface{}{avm.Owners{
|
||||||
0x00, 0x5f, 0x9c, 0xa9, 0x00, 0x00, 0x00, 0x30,
|
Threshold: 1,
|
||||||
0x39, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
Minters: config.MintAddresses,
|
||||||
0x00, 0x3c, 0xb7, 0xd3, 0x84, 0x2e, 0x8c, 0xee,
|
}}
|
||||||
0x6a, 0x0e, 0xbd, 0x09, 0xf1, 0xfe, 0x88, 0x4f,
|
}
|
||||||
0x68, 0x61, 0xe1, 0xb2, 0x9c, 0x00, 0x00, 0x00,
|
for _, addr := range config.FundedAddresses {
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
ava.InitialState["fixedCap"] = append(ava.InitialState["fixedCap"], avm.Holder{
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
Amount: json.Uint64(45 * units.MegaAva),
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
Address: addr,
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
})
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
}
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
avmArgs.GenesisData = map[string]avm.AssetDefinition{
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
// The AVM starts out with one asset, $AVA
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0xaa, 0x18,
|
"AVA": ava,
|
||||||
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,
|
|
||||||
}
|
}
|
||||||
|
avmReply := avm.BuildGenesisReply{}
|
||||||
|
|
||||||
|
avmSS := avm.StaticService{}
|
||||||
|
err := avmSS.BuildGenesis(nil, &avmArgs, &avmReply)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Specify the genesis state of Athereum (the built-in instance of the EVM)
|
||||||
|
evmBalance, success := new(big.Int).SetString("33b2e3c9fd0804000000000", 16)
|
||||||
|
if success != true {
|
||||||
|
return nil, errors.New("problem creating evm genesis state")
|
||||||
|
}
|
||||||
|
|
||||||
|
alloc := core.GenesisAlloc{}
|
||||||
|
for _, addr := range config.FundedEVMAddresses {
|
||||||
|
alloc[common.HexToAddress(addr)] = core.GenesisAccount{
|
||||||
|
Balance: evmBalance,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
evmArgs := core.Genesis{
|
||||||
|
Config: ¶ms.ChainConfig{
|
||||||
|
ChainID: big.NewInt(43110),
|
||||||
|
HomesteadBlock: big.NewInt(0),
|
||||||
|
DAOForkBlock: big.NewInt(0),
|
||||||
|
DAOForkSupport: true,
|
||||||
|
EIP150Block: big.NewInt(0),
|
||||||
|
EIP150Hash: common.HexToHash("0x2086799aeebeae135c246c65021c82b4e15a2c451340993aacfd2751886514f0"),
|
||||||
|
EIP155Block: big.NewInt(0),
|
||||||
|
EIP158Block: big.NewInt(0),
|
||||||
|
ByzantiumBlock: big.NewInt(0),
|
||||||
|
ConstantinopleBlock: big.NewInt(0),
|
||||||
|
PetersburgBlock: big.NewInt(0),
|
||||||
|
},
|
||||||
|
Nonce: 0,
|
||||||
|
Timestamp: 0,
|
||||||
|
ExtraData: []byte{0},
|
||||||
|
GasLimit: 100000000,
|
||||||
|
Difficulty: big.NewInt(0),
|
||||||
|
Mixhash: common.HexToHash("0x0000000000000000000000000000000000000000000000000000000000000000"),
|
||||||
|
Coinbase: common.HexToAddress("0x0000000000000000000000000000000000000000"),
|
||||||
|
Alloc: alloc,
|
||||||
|
Number: 0,
|
||||||
|
GasUsed: 0,
|
||||||
|
ParentHash: common.HexToHash("0x0000000000000000000000000000000000000000000000000000000000000000"),
|
||||||
|
}
|
||||||
|
evmSS := evm.StaticService{}
|
||||||
|
evmReply, err := evmSS.BuildGenesis(nil, &evmArgs)
|
||||||
|
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: evmReply,
|
||||||
|
SubnetID: platformvm.DefaultSubnetID,
|
||||||
|
VMID: evm.ID,
|
||||||
|
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 ...
|
// VMGenesis ...
|
||||||
func VMGenesis(networkID uint32, vmID ids.ID) *platformvm.CreateChainTx {
|
func VMGenesis(networkID uint32, vmID ids.ID) (*platformvm.CreateChainTx, error) {
|
||||||
genesisBytes := Genesis(networkID)
|
genesisBytes, err := Genesis(networkID)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
genesis := platformvm.Genesis{}
|
genesis := platformvm.Genesis{}
|
||||||
platformvm.Codec.Unmarshal(genesisBytes, &genesis)
|
platformvm.Codec.Unmarshal(genesisBytes, &genesis)
|
||||||
|
if err := genesis.Initialize(); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
for _, chain := range genesis.Chains {
|
for _, chain := range genesis.Chains {
|
||||||
if chain.VMID.Equals(vmID) {
|
if chain.VMID.Equals(vmID) {
|
||||||
return chain
|
return chain, nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return nil
|
return nil, fmt.Errorf("couldn't find subnet with VM ID %s", vmID)
|
||||||
|
}
|
||||||
|
|
||||||
|
// AVAAssetID ...
|
||||||
|
func AVAAssetID(networkID uint32) (ids.ID, error) {
|
||||||
|
createAVM, err := VMGenesis(networkID, avm.ID)
|
||||||
|
if err != nil {
|
||||||
|
return ids.ID{}, err
|
||||||
|
}
|
||||||
|
|
||||||
|
c := codec.NewDefault()
|
||||||
|
errs := wrappers.Errs{}
|
||||||
|
errs.Add(
|
||||||
|
c.RegisterType(&avm.BaseTx{}),
|
||||||
|
c.RegisterType(&avm.CreateAssetTx{}),
|
||||||
|
c.RegisterType(&avm.OperationTx{}),
|
||||||
|
c.RegisterType(&avm.ImportTx{}),
|
||||||
|
c.RegisterType(&avm.ExportTx{}),
|
||||||
|
c.RegisterType(&secp256k1fx.TransferInput{}),
|
||||||
|
c.RegisterType(&secp256k1fx.MintOutput{}),
|
||||||
|
c.RegisterType(&secp256k1fx.TransferOutput{}),
|
||||||
|
c.RegisterType(&secp256k1fx.MintOperation{}),
|
||||||
|
c.RegisterType(&secp256k1fx.Credential{}),
|
||||||
|
)
|
||||||
|
if errs.Errored() {
|
||||||
|
return ids.ID{}, errs.Err
|
||||||
|
}
|
||||||
|
|
||||||
|
genesis := avm.Genesis{}
|
||||||
|
if err := c.Unmarshal(createAVM.GenesisData, &genesis); err != nil {
|
||||||
|
return ids.ID{}, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(genesis.Txs) == 0 {
|
||||||
|
return ids.ID{}, errors.New("genesis creates no transactions")
|
||||||
|
}
|
||||||
|
genesisTx := genesis.Txs[0]
|
||||||
|
|
||||||
|
tx := avm.Tx{UnsignedTx: &genesisTx.CreateAssetTx}
|
||||||
|
txBytes, err := c.Marshal(&tx)
|
||||||
|
if err != nil {
|
||||||
|
return ids.ID{}, err
|
||||||
|
}
|
||||||
|
tx.Initialize(txBytes)
|
||||||
|
|
||||||
|
return tx.ID(), nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,6 +6,7 @@ package genesis
|
||||||
import (
|
import (
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
"github.com/ava-labs/gecko/ids"
|
||||||
"github.com/ava-labs/gecko/vms/avm"
|
"github.com/ava-labs/gecko/vms/avm"
|
||||||
"github.com/ava-labs/gecko/vms/evm"
|
"github.com/ava-labs/gecko/vms/evm"
|
||||||
"github.com/ava-labs/gecko/vms/platformvm"
|
"github.com/ava-labs/gecko/vms/platformvm"
|
||||||
|
@ -17,11 +18,11 @@ func TestNetworkName(t *testing.T) {
|
||||||
if name := NetworkName(MainnetID); name != MainnetName {
|
if name := NetworkName(MainnetID); name != MainnetName {
|
||||||
t.Fatalf("NetworkID was incorrectly named. Result: %s ; Expected: %s", name, MainnetName)
|
t.Fatalf("NetworkID was incorrectly named. Result: %s ; Expected: %s", name, MainnetName)
|
||||||
}
|
}
|
||||||
if name := NetworkName(TestnetID); name != BorealisName {
|
if name := NetworkName(TestnetID); name != CascadeName {
|
||||||
t.Fatalf("NetworkID was incorrectly named. Result: %s ; Expected: %s", name, BorealisName)
|
t.Fatalf("NetworkID was incorrectly named. Result: %s ; Expected: %s", name, CascadeName)
|
||||||
}
|
}
|
||||||
if name := NetworkName(BorealisID); name != BorealisName {
|
if name := NetworkName(CascadeID); name != CascadeName {
|
||||||
t.Fatalf("NetworkID was incorrectly named. Result: %s ; Expected: %s", name, BorealisName)
|
t.Fatalf("NetworkID was incorrectly named. Result: %s ; Expected: %s", name, CascadeName)
|
||||||
}
|
}
|
||||||
if name := NetworkName(4294967295); name != "network-4294967295" {
|
if name := NetworkName(4294967295); name != "network-4294967295" {
|
||||||
t.Fatalf("NetworkID was incorrectly named. Result: %s ; Expected: %s", name, "network-4294967295")
|
t.Fatalf("NetworkID was incorrectly named. Result: %s ; Expected: %s", name, "network-4294967295")
|
||||||
|
@ -45,7 +46,7 @@ func TestNetworkID(t *testing.T) {
|
||||||
t.Fatalf("Returned wrong network. Expected: %d ; Returned %d", TestnetID, id)
|
t.Fatalf("Returned wrong network. Expected: %d ; Returned %d", TestnetID, id)
|
||||||
}
|
}
|
||||||
|
|
||||||
id, err = NetworkID(BorealisName)
|
id, err = NetworkID(CascadeName)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
@ -53,7 +54,7 @@ func TestNetworkID(t *testing.T) {
|
||||||
t.Fatalf("Returned wrong network. Expected: %d ; Returned %d", TestnetID, id)
|
t.Fatalf("Returned wrong network. Expected: %d ; Returned %d", TestnetID, id)
|
||||||
}
|
}
|
||||||
|
|
||||||
id, err = NetworkID("bOrEaLiS")
|
id, err = NetworkID("cAsCaDe")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
@ -91,7 +92,7 @@ func TestNetworkID(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestAliases(t *testing.T) {
|
func TestAliases(t *testing.T) {
|
||||||
generalAliases, _, _ := Aliases(LocalID)
|
generalAliases, _, _, _ := Aliases(LocalID)
|
||||||
if _, exists := generalAliases["vm/"+platformvm.ID.String()]; !exists {
|
if _, exists := generalAliases["vm/"+platformvm.ID.String()]; !exists {
|
||||||
t.Fatalf("Should have a custom alias from the vm")
|
t.Fatalf("Should have a custom alias from the vm")
|
||||||
} else if _, exists := generalAliases["vm/"+avm.ID.String()]; !exists {
|
} else if _, exists := generalAliases["vm/"+avm.ID.String()]; !exists {
|
||||||
|
@ -106,9 +107,84 @@ func TestAliases(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestGenesis(t *testing.T) {
|
func TestGenesis(t *testing.T) {
|
||||||
genesisBytes := Genesis(LocalID)
|
genesisBytes, err := Genesis(LocalID)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
genesis := platformvm.Genesis{}
|
genesis := platformvm.Genesis{}
|
||||||
if err := platformvm.Codec.Unmarshal(genesisBytes, &genesis); err != nil {
|
if err := platformvm.Codec.Unmarshal(genesisBytes, &genesis); err != nil {
|
||||||
t.Fatal(err)
|
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: evm.ID,
|
||||||
|
expectedID: "2mUYSXfLrDtigwbzj1LxKVsHwELghc5sisoXrzJwLqAAQHF4i",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
networkID: LocalID,
|
||||||
|
vmID: evm.ID,
|
||||||
|
expectedID: "tZGm6RCkeGpVETUTp11DW3UYFZmm69zfqxchpHrSF7wgy8rmw",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, test := range tests {
|
||||||
|
genesisTx, err := VMGenesis(test.networkID, test.vmID)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
if result := genesisTx.ID().String(); test.expectedID != result {
|
||||||
|
t.Fatalf("%s genesisID with networkID %d was expected to be %s but was %s",
|
||||||
|
test.vmID,
|
||||||
|
test.networkID,
|
||||||
|
test.expectedID,
|
||||||
|
result)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestAVAAssetID(t *testing.T) {
|
||||||
|
tests := []struct {
|
||||||
|
networkID uint32
|
||||||
|
expectedID string
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
networkID: CascadeID,
|
||||||
|
expectedID: "21d7KVtPrubc5fHr6CGNcgbUb4seUjmZKr35ZX7BZb5iP8pXWA",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
networkID: LocalID,
|
||||||
|
expectedID: "n8XH5JY1EX5VYqDeAhB4Zd4GKxi9UNQy6oPpMsCAj1Q6xkiiL",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, test := range tests {
|
||||||
|
avaID, err := AVAAssetID(test.networkID)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
if result := avaID.String(); test.expectedID != result {
|
||||||
|
t.Fatalf("AVA assetID with networkID %d was expected to be %s but was %s",
|
||||||
|
test.networkID,
|
||||||
|
test.expectedID,
|
||||||
|
result)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,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)
|
||||||
|
}
|
|
@ -95,7 +95,7 @@ func (b *Bag) Mode() (ID, int) { return b.mode, b.modeFreq }
|
||||||
func (b *Bag) Threshold() Set { return b.metThreshold }
|
func (b *Bag) Threshold() Set { return b.metThreshold }
|
||||||
|
|
||||||
// Filter returns the bag of ids with the same counts as this bag, except all
|
// 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.
|
// as id.
|
||||||
func (b *Bag) Filter(start, end int, id ID) Bag {
|
func (b *Bag) Filter(start, end int, id ID) Bag {
|
||||||
newBag := Bag{}
|
newBag := Bag{}
|
||||||
|
|
145
ids/id_test.go
145
ids/id_test.go
|
@ -5,6 +5,7 @@ package ids
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
|
"reflect"
|
||||||
"testing"
|
"testing"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -29,10 +30,6 @@ func TestID(t *testing.T) {
|
||||||
if b := id.Bytes(); !bytes.Equal(hash[:], b) {
|
if b := id.Bytes(); !bytes.Equal(hash[:], b) {
|
||||||
t.Fatalf("ID.Bytes returned wrong bytes")
|
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) {
|
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")
|
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")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -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)
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,7 +1,7 @@
|
||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
set -ex
|
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
|
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."
|
echo "staker.key or staker.crt already exists. Not generating new key/certificiate."
|
|
@ -1,6 +0,0 @@
|
||||||
#!/bin/sh
|
|
||||||
set -ex
|
|
||||||
|
|
||||||
openssl genrsa -out `dirname "$0"`/staker.key 4096
|
|
||||||
openssl req -new -sha256 -key `dirname "$0"`/staker.key -subj "/C=US/ST=NY/O=Avalabs/CN=ava" -out `dirname "$0"`/staker.csr
|
|
||||||
openssl x509 -req -in `dirname "$0"`/staker.csr -CA `dirname "$0"`/rootCA.crt -CAkey `dirname "$0"`/rootCA.key -CAcreateserial -out `dirname "$0"`/staker.crt -days 365250 -sha256
|
|
|
@ -1 +0,0 @@
|
||||||
BAF3B5C5C6D0D14A
|
|
|
@ -1,27 +0,0 @@
|
||||||
-----BEGIN CERTIFICATE REQUEST-----
|
|
||||||
MIIEfzCCAmcCAQAwOjELMAkGA1UEBhMCVVMxCzAJBgNVBAgMAk5ZMRAwDgYDVQQK
|
|
||||||
DAdBdmFsYWJzMQwwCgYDVQQDDANhdmEwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAw
|
|
||||||
ggIKAoICAQDKYSRw/W0YpYH/MTQhiFrR0m89l6yTuzLpDtjudr/5RnhIPvtqk7YI
|
|
||||||
Gm/m9l29xwR4J5r7SZGs+70yBetkbS+h7PwJ2rmWDwbrdyJKvVBhqf8kSn+VU2Le
|
|
||||||
PSIcJj193LDyWhV1H4lqNkUkcAR76Fh9qjMvA2p0vJ66+eDLXlph/RYapQx9HgOj
|
|
||||||
/0BmAKMrYCyo5BhRih+Ougg8aK4G9PQTIA5G2wTWW2QkHxM/QppFjZd/XwQeJ2H6
|
|
||||||
ubWMFc5fttf6AzpJvFIDBu/JDCKWiCu5m8t4GL8w2OrIx8Js19lF4YYE2eojCreq
|
|
||||||
gPi64S3ocqwKsDoySTw6/5iKQ5BUYwUXX3z7EXOqD8SMHefUKeczj4WvAaZLzR27
|
|
||||||
qXm55EgRYQAIX4fhmY7NfSop3Wh0Eo62+JHoM/1g+UgOXlbnWpY95Mgd7/fwDSWL
|
|
||||||
u4IxE0/uq8VufIbfC4yrY8qlTVfAffI1ldRdvJjPJBPiQ0CNrOl60LVptpkGc9sh
|
|
||||||
H7wZ2bP0bEnYKTgLAfOzD8Ut71O2AOIa80A1GNFl4Yle/MSNJOcQOSpgtWdREzIU
|
|
||||||
oenAjfuzM4OeTr4cRg4+VYTAo9KHKriN1DuewNzGd8WjKAVHmcIMjqISLTlzMhds
|
|
||||||
dm+OmfQ6OvyX7v0GTOBbhP09NGcww5A0gCzXN18FS5oxnxe6OG9D0wIDAQABoAAw
|
|
||||||
DQYJKoZIhvcNAQELBQADggIBAE7VplAZTEGHpYwXZvhlVg0qDsb/7IQj77eNteSU
|
|
||||||
33Dq6u7QLgS+Ea04Xv5BHnhnBoWRtrNR8WLTw64cuj6p/sqXiQsSNDgxNDPuPG+g
|
|
||||||
1FFi6wjgtoIJnx/QrITuUyO/MRy1awKLHlGfbY6yXSdLCC9bqLSIRm0tx+E+jo5C
|
|
||||||
0r5+ZOcLK8ZXWq9uHjmekX0hoN4qzsbQ0J5IeMh9ag+698aqzBSEDljLHg614yiK
|
|
||||||
FxtpD+23O0XfAdgqFgXRLLg3tt8AkVuys7r/uwHoz9du+nwW2U5nsMIYBXLV2mq3
|
|
||||||
1KbpXDTlVwaSoA2LP8dpmvbyTgNbXsjPdS91Rrzd7fcsammcSV0aWPiXmIbTLtn8
|
|
||||||
61ZRR0uj+jB68cRjSvegnheifsGyq6alr8OSUMdeWVyiPy2O7N6fUVj+Fmyzl5Ph
|
|
||||||
fl9UPZTmt/zOZrcSBoWjtZfmQVfw29SfMYwlNKALN4eOT6XwBLDK4uu4UXSoXwi+
|
|
||||||
V8evUUfBWcrcXHMTIFhoZbW/b7gjhnv148XWYI0ta8pjt/akzlPLtf4ETPqfECNN
|
|
||||||
4+p2w9+R5ktzCLeceXQc8eN+ZwjIt31zG48J7Sl1wJB13VR0jPy6zDsyUIswIVfe
|
|
||||||
7gp7GHg8R0lzDpEYCvU+R7RUWK6xcpjt7+mTHM70csnnOg7uPqnXqOdtVplr0y+R
|
|
||||||
pmqJ
|
|
||||||
-----END CERTIFICATE REQUEST-----
|
|
|
@ -1,5 +0,0 @@
|
||||||
#!/bin/sh
|
|
||||||
set -ex
|
|
||||||
|
|
||||||
openssl genrsa -out `dirname "$0"`/rootCA.key 4096
|
|
||||||
openssl req -x509 -new -nodes -key `dirname "$0"`/rootCA.key -sha256 -days 365250 -out `dirname "$0"`/rootCA.crt
|
|
|
@ -1,6 +0,0 @@
|
||||||
#!/bin/sh
|
|
||||||
set -ex
|
|
||||||
|
|
||||||
openssl genrsa -out `dirname "$0"`/staker.key 4096
|
|
||||||
openssl req -new -sha256 -key `dirname "$0"`/staker.key -subj "/C=US/ST=NY/O=Avalabs/CN=ava" -out `dirname "$0"`/staker.csr
|
|
||||||
openssl x509 -req -in `dirname "$0"`/staker.csr -CA `dirname "$0"`/rootCA.crt -CAkey `dirname "$0"`/rootCA.key -CAcreateserial -out `dirname "$0"`/staker.crt -days 365250 -sha256
|
|
|
@ -1,34 +0,0 @@
|
||||||
-----BEGIN CERTIFICATE-----
|
|
||||||
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
|
|
||||||
DB8IRfWqBx2nWw==
|
|
||||||
-----END CERTIFICATE-----
|
|
|
@ -1,51 +0,0 @@
|
||||||
-----BEGIN RSA PRIVATE KEY-----
|
|
||||||
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
|
|
||||||
-----END RSA PRIVATE KEY-----
|
|
|
@ -1 +0,0 @@
|
||||||
BAF3B5C5C6D0D14A
|
|
|
@ -1,27 +0,0 @@
|
||||||
-----BEGIN CERTIFICATE REQUEST-----
|
|
||||||
MIIEfzCCAmcCAQAwOjELMAkGA1UEBhMCVVMxCzAJBgNVBAgMAk5ZMRAwDgYDVQQK
|
|
||||||
DAdBdmFsYWJzMQwwCgYDVQQDDANhdmEwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAw
|
|
||||||
ggIKAoICAQDdToR60na6NuR9iSAUMyzPXJNMWVQbLyT5/iZCiJ3BB4YWMBhfxpJW
|
|
||||||
JiWXcM+znDgpJuyCEeh5Dp6ZY3Fe7k6Hht6FmFpDjwnjpQmdkEKUg00G+ElPTp/U
|
|
||||||
smsPL+JAswPqBZWpMBS3dsXQNunMMtMGlrf5S0l6XX4y7kc/GTxYgveWZ9JtR/m2
|
|
||||||
KNer+wjgBHqJ4rPqnHB30sDYPZg91Cz1Ak8Bb2w2I108zQVgKK6eIqNKXJJ/4piz
|
|
||||||
SZdU4920wMxYBpnfDAchnxei9U/v3QbT7eKUI2fGr+hOWTIWU80+VeOBt8a6P4sS
|
|
||||||
9AQh5/6G8qwmAqO3YQ9dxN82iu/H3+N+GGa/M0r5rEWrzwIuFhwKvyQcpPRBm2yQ
|
|
||||||
nBnhL9G5kN6n4OBM0KsgZ3CYlHZSg4eWcNgBt1WCFsQc7vfUFaJnr8QP3pF4V/4B
|
|
||||||
ok7wTO5HN0A1EYEVYuX53NGnrKVe+Fg9+xMOgXPWkUNqdvpI9ZbV3Z0S5866qF3/
|
|
||||||
vBZrhgCrKc5E/vMexBRe8Ki4wKqONVhi9WGUcRHvFEikc+7VrPj0YaG6zVLd+uOA
|
|
||||||
JN81fKOPYo4X4sZrMyPYl3OjGtMhfV4KvCaLEr1duOklqO6cCvGQ8iAlLVy3VJyW
|
|
||||||
5GJ0D0KyiAir4VNdAJKo1ZgiGivJLWulTfjUifCN9o115AiqJxiqwwIDAQABoAAw
|
|
||||||
DQYJKoZIhvcNAQELBQADggIBAM2IHKsQsebxTD50QQXtSNbyRzG/GpMZuZXn/QYO
|
|
||||||
QGW0ThJwtcmx6cqQvuyBovH5WhB9QUBFjiKkR7Qef7HUsgxU1cJA75gBfb2GMUru
|
|
||||||
Q+T37xOxtr6S2TcKOq/LvdJaTYmAHmW9V7vwEcrMRa9lWVTEmJIKTuxiUubpXtup
|
|
||||||
8OB8WLIvDikVtKtegvl6VCaTApCkUfuLhf7DERQ6sGLXWz6dVQcfvbfcXK2fn1Ik
|
|
||||||
Koxqy1SSz/rPb4u9NEk1yqvJQdpgnbTM3drTPHiIHCA7F6SjMu5tekHtVQkFOd6c
|
|
||||||
B0geEwyxY97zqnFv5YXiukXEaAnCRAlOuIZXRqtK6GFthTWo33YpB2KaRUtJ7IuP
|
|
||||||
og4Q/zjDs8DEc/qbbUbhyulExz6uoyRKO4j/gG3ESC6j09j7Eungt1LDhyt8p3wD
|
|
||||||
pytIIPkTseykO0CcEpEcGbES6d3u4PrFJ75XWxMkNZVK8mC3faxx2kJLfS1+4Fg8
|
|
||||||
A0zbcN6qwm1ezGq2vGQcyVKyFVWJQAEAFuSO8sjW6dk3ClfE+MNGUvxTQMe96V14
|
|
||||||
jGRICCp9aJrJXA3u0iQaUX0cXmlhegAYk7Ho/Ef3k/PcP8DzZ8Ck839oRHBw4pPv
|
|
||||||
tKbyiKnOcet7AFGwsiM2t5VLrj4jovhRLEiaXrCaxNe6j4xs63TEb+8uTCzKyktC
|
|
||||||
4BFq
|
|
||||||
-----END CERTIFICATE REQUEST-----
|
|
|
@ -1,5 +0,0 @@
|
||||||
#!/bin/sh
|
|
||||||
set -ex
|
|
||||||
|
|
||||||
openssl genrsa -out `dirname "$0"`/rootCA.key 4096
|
|
||||||
openssl req -x509 -new -nodes -key `dirname "$0"`/rootCA.key -sha256 -days 365250 -out `dirname "$0"`/rootCA.crt
|
|
|
@ -1,6 +0,0 @@
|
||||||
#!/bin/sh
|
|
||||||
set -ex
|
|
||||||
|
|
||||||
openssl genrsa -out `dirname "$0"`/staker.key 4096
|
|
||||||
openssl req -new -sha256 -key `dirname "$0"`/staker.key -subj "/C=US/ST=NY/O=Avalabs/CN=ava" -out `dirname "$0"`/staker.csr
|
|
||||||
openssl x509 -req -in `dirname "$0"`/staker.csr -CA `dirname "$0"`/rootCA.crt -CAkey `dirname "$0"`/rootCA.key -CAcreateserial -out `dirname "$0"`/staker.crt -days 365250 -sha256
|
|
|
@ -1,34 +0,0 @@
|
||||||
-----BEGIN CERTIFICATE-----
|
|
||||||
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
|
|
||||||
DB8IRfWqBx2nWw==
|
|
||||||
-----END CERTIFICATE-----
|
|
|
@ -1,51 +0,0 @@
|
||||||
-----BEGIN RSA PRIVATE KEY-----
|
|
||||||
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
|
|
||||||
-----END RSA PRIVATE KEY-----
|
|
|
@ -1 +0,0 @@
|
||||||
BAF3B5C5C6D0D14A
|
|
|
@ -1,27 +0,0 @@
|
||||||
-----BEGIN CERTIFICATE REQUEST-----
|
|
||||||
MIIEfzCCAmcCAQAwOjELMAkGA1UEBhMCVVMxCzAJBgNVBAgMAk5ZMRAwDgYDVQQK
|
|
||||||
DAdBdmFsYWJzMQwwCgYDVQQDDANhdmEwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAw
|
|
||||||
ggIKAoICAQC8mVDToHbkUF2gRdVfpydZLNKeQ38d6HZFkUM3U1dWLZFSZNvagN8h
|
|
||||||
lQvY/tQu3A40p19WgKbzWZre3tg1Akw8Jztdz9gl4RMn142IIO3CiwIptkE0Jopb
|
|
||||||
ZhmG5fAC2n/MXQtfieI3hzeR04LW4JgLKzf3Nn8xZdlBgJfBmL5qUUnE7O7IbJGG
|
|
||||||
ma6gSD3ewetE6KQZtNtf0xRIv08doZKYwTl6ItkdGK76ufqq098GVwWvA1wSune4
|
|
||||||
+MFgs9N4eFJj6Jyt85fiK/cwPx7KRdgYgBzrZQ4EPshRnwWrBTieOOaJvAA2RMxM
|
|
||||||
EYzKRrJAAsYI1zxtNyqIUaBTcxmaz+NXUGW+wHwITic0Gp/XQm2Lwr/lxIV6OnAl
|
|
||||||
L3CgbSXirSnoG+eHQ+vDzBAcRDkTAgv/GUIzlfqT2StTK02uIBgJYzvFTG4plHit
|
|
||||||
ccRfy8wxsh5Z8xG99lmPQQtLsnlQAV+Li06Cb8CH4hUVoiWiVs5QAahqWmv5fpoX
|
|
||||||
0Es26RyUHXGbjE202pyMMA7jUerUVKMijOoGZtcH6zB4p/dJ0TtToRwOgrA7NCI9
|
|
||||||
AYVtqVXrXG/udj8ur2r1bTVwIbHsOeTEP3gY0mHRWm2E/bLjt9vbYIRUxR8xWnLk
|
|
||||||
beBziNTwg+36jdDF+6gu3cUz/nbSn8YY+Y1jjXuM3lqF8iMaAobhuwIDAQABoAAw
|
|
||||||
DQYJKoZIhvcNAQELBQADggIBAEWU13T1alCni4R36J65TrGfIljW8LGhmWRo5xoV
|
|
||||||
YW7HxxZ/WTAFSwAv0yHCGq+H/tebRZhvua+c+jP16YBDoAp5neGWW57gLDg+35H5
|
|
||||||
guLo73p/qM6hyaUGSfyO9D1nS1QX8R0r70TQYbIrVB4uQeTM2pEYR6NYO7bjPEWr
|
|
||||||
WwC6RnbtnsNGTeoH+LwiM+uY//VB/tUe1u2y6U8HkIXJo7j4+NqUL1xXmYmC6Rph
|
|
||||||
PNI3MAZUL40z1VX7fn/Vp7+rc0CBUsFMOLfLmSgL8jsQeKuyVAQKA4xzWQ2qeuGV
|
|
||||||
Bv24rHbnSxYSu8tMs31LZPn+fsvNWB9iU7MEiTUr+8nAPEAANNaBwaD1EUkzC1WC
|
|
||||||
OcCUpMgkhVuzfHq+eXWnw3cGVvEZ8A4DzOyl1ZFofxBX7IOOv0lmpDQSeEQlmKPF
|
|
||||||
LdWI2JJM76BjeXI7l5HbOmRJv1kYFwBq/biDxCSmmNX8uHvAj1EgDNXvr/pRw7rT
|
|
||||||
6yKOLtk1GSCCrrYQijCXRx2u276+j8MtC5i6FVcUoaSYD+nx2+ApOnZlYR7xsJYw
|
|
||||||
5ECaeDagjHP472FY/fuhy/UwAIFm5gCcVFs3A2M/Iyn+vsAW5WEdh+fwGiWxfw49
|
|
||||||
Y5KRT8u7BD0R5T5UYxYwzYekEzxsoD3bvQGx/4tboSUxkOd7pVymbuGzIsQ18heI
|
|
||||||
78pG
|
|
||||||
-----END CERTIFICATE REQUEST-----
|
|
|
@ -1,5 +0,0 @@
|
||||||
#!/bin/sh
|
|
||||||
set -ex
|
|
||||||
|
|
||||||
openssl genrsa -out `dirname "$0"`/rootCA.key 4096
|
|
||||||
openssl req -x509 -new -nodes -key `dirname "$0"`/rootCA.key -sha256 -days 365250 -out `dirname "$0"`/rootCA.crt
|
|
|
@ -1,6 +0,0 @@
|
||||||
#!/bin/sh
|
|
||||||
set -ex
|
|
||||||
|
|
||||||
openssl genrsa -out `dirname "$0"`/staker.key 4096
|
|
||||||
openssl req -new -sha256 -key `dirname "$0"`/staker.key -subj "/C=US/ST=NY/O=Avalabs/CN=ava" -out `dirname "$0"`/staker.csr
|
|
||||||
openssl x509 -req -in `dirname "$0"`/staker.csr -CA `dirname "$0"`/rootCA.crt -CAkey `dirname "$0"`/rootCA.key -CAcreateserial -out `dirname "$0"`/staker.crt -days 365250 -sha256
|
|
|
@ -1,34 +0,0 @@
|
||||||
-----BEGIN CERTIFICATE-----
|
|
||||||
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
|
|
||||||
DB8IRfWqBx2nWw==
|
|
||||||
-----END CERTIFICATE-----
|
|
|
@ -1,51 +0,0 @@
|
||||||
-----BEGIN RSA PRIVATE KEY-----
|
|
||||||
MIIJJwIBAAKCAgEAnjlJxZXy2wI0741MgG5Riw+SFyCOunQcTIIdjdcSTGwu4Oq1
|
|
||||||
6w3K/f1gDTFDczcU/V7b22MV4dYnPLNXw7Uf7rJyj3dAC3OH3EQtgPfTVir7HnnJ
|
|
||||||
mtKNnE0gLlObPV7BN8PfXmU1HTgzomaqOtK0i4uxYVSbo/g6Bezh1qqfKr1q7g9h
|
|
||||||
Kt6Nxt7Fbn2srEuvIroBy/4T0DHTihLfeD0qo+aVHHSV+7fHieQgoiX5VorXALkL
|
|
||||||
AkNhn3UqkRsLxnZi9N5UMf7+HP8y8qXUIRqor/gbkUEoYTJ39sZHExVAXjUbuWIk
|
|
||||||
tpfM8vJmco7afbVm4mGQD0xl6W3VTQu5BTnTmpTsjNZyYoUQhvUw6tyVoXX0izsd
|
|
||||||
CUlYrIOjb+F+NIJk7zMft5H0QbMrJDBmHCRgLJwkPjhEoQerqz9nZ0dSWksiBEnu
|
|
||||||
TXvVM2Qv37Eue27y/WXNOSF6ZI1471qyontVy+mcwcdtBekPEmmLyNOdXwifwSiV
|
|
||||||
Kpop43r+fPBttInuAd6GCkOELUOVc9HNO3+S1AqU0ZZPlt0129gXJhN31+7vxoll
|
|
||||||
JsmjyNLZ/KRa4GA6CeVXxWbCkNruIczcQQIHKF/kYoEnWMGVc7VnJ8nuw1Nu5Uzt
|
|
||||||
RzYmQHgBIp2bcZnewW/3keNJMkBQ5GMTilDV6ziR8NQqrMMcf5sQdoYgYlMCAwEA
|
|
||||||
AQKCAgAhNota05AoEv2Dr5h4eS/azgjvm+D6GLd8A/AqPxRTQH5SrlJDpiCPUmmg
|
|
||||||
O1AaVlyslwX1toX4YxjXcBojNdkfJQxRO0oRXU4Oma0nnl4Zf2o5Sn1cZ4hcYAA6
|
|
||||||
WUiECGjsyMwRp5MPsCV+mKhxMpu9kzRH5xfIwqmDZuc9RZGlyh8xG79c3VzLeyXc
|
|
||||||
fLsLa9O2qW8JICuOj3cFS9LnDYfu4c85Kuv06+4R7vY+s1P0q65YM3+xGO3cKB8o
|
|
||||||
WJIPNfityCHKYOl8ssFCGDdAP7VbQuyegBv20z5FafevdM2POPy53HUycwkNkn6Y
|
|
||||||
243Xx4VyTeKMo4/dATY+NxC+nRXiz4jLna5a7IIIzjAHl2kF6iJVasd3+X/xWHsM
|
|
||||||
Lx9iDRjERf+J+y58GaDxetXL1C0xm7Rv28yMYVPAzpucvS4i72Xj7X8JkO3az3Qv
|
|
||||||
/wqBnxj8ouh+5jvT0nqCJsFZwK0F7Dr3na2lSf34XBCTnd9//FfSIY7mDIddxuVF
|
|
||||||
2rKKOl2KkvbDUuSKVZwdJeAp1CccN6SfLnxKy+436Z5hYzBIeGyejpCMWivDJ2I3
|
|
||||||
wjs4w4IPobT5dqaSdPYFTKJnoDv62vYbIN3o8pQ3QUXwmRPyKoPuxe7OZZyec43R
|
|
||||||
WUtajiW6AXjxUoEtPPPHAT/3pGKG2a0VGtDfjLjpp5OtQmteiQKCAQEAz62n9Lh1
|
|
||||||
POdC4088GEqrGPhq5MUz2j2pOCjEZ7utmD+Lo8x95McCU+jf4UJ+rbaf96dvjPRC
|
|
||||||
T0Sc6X6IvvQycJubzQe6XX6eyZsr67qpuY2MGze+NvmO4LcCOfNHerRyLK2DoGLW
|
|
||||||
jQVxJNsBIFo0T7iSuUICbfxKdKxfH+27rPANEvpqS5BJalAfeGPEL0GgUTKQmswc
|
|
||||||
23Pnu5mkb7TWLKNVq7o/5PxvXyKmJQaFHCV98pqQr/HhXd79dMD12TPZRvsNgPGK
|
|
||||||
XOsmPtC5RHhbs/Wmdk3X3ihoVezou2VPeWCIrCANCuU0zZBK1igVC3FGeUK8u1Dl
|
|
||||||
jrTkRsNTLbBiPwKCAQEAwwngBBjbdRCVvUVWIBQBOk/t/6WyeAVH4O/fq32KklW+
|
|
||||||
/SN5yeZhXjwMrFhSOqFUDipg/C4Imf5S3V+MlXO4lQsZzZa0d0euBIBt0SEcGE8P
|
|
||||||
rAkGcvwPfISBfYCnPem1ax01ixNJBxWDrgkfHZchywNPFgopiqpYR7X5ttACctCl
|
|
||||||
KLaDOXn667QmG1icsVgZV3L8gBxEdyjhmUGWFH/auS28oxqhUgiXrUQXbJKCesGD
|
|
||||||
E39r/SyOAGP5ZtTkWmNDp2+va8lSJwL1Ix+6qvexi/hIIGoFlSh5w+BwnBlxBL4C
|
|
||||||
cUanaXRtIqQ9rcO/xhZ7izmQzruNARLDPGIJ59MS7QKCAQBGR3wJAssZ2yD1j4DE
|
|
||||||
r7AK+TYjSODtP+SeDp24hPiQByEYQ0FvRDFzd+Ebd8cqvhyQUGcdiiNOc+et1JYu
|
|
||||||
GLFhDifBUJYuwYS2sP5B/Z8mHdKF+20xaW6CeSwVtFBCJAJnQCjFA+2bN3Y8hKhy
|
|
||||||
7FO7jriIXOA5nCEOLq7aPTc/pNSn0XpbK+7MPWUI9qoTW+AG2le5Ks2xLh4DjFDr
|
|
||||||
RIUeAgAh5xtsQEjoJu+WpAgzqDRg/xFrmS0s+SNIeWw5HqSuspK1SggKvcDpjPTF
|
|
||||||
SP2vfrfgXSNqGL6GJW/0yqoEZziZFxeS0lH2JphMtK+6eZDhxEXeFdg5XNnLYJor
|
|
||||||
Yf89AoIBAHbRLESys/c0HFTKybYPGdRhXzcvxXKynOBeoZ9Cgsm1LP3fv9EM5WJY
|
|
||||||
KMxRnf6Ty7Y5gQ4AKUNPGUI9dFKTxe4ebiC938EOzOd3Ke+OQSRZ/c0rTl98SR7t
|
|
||||||
Rkmjt77TAq93gufv3rxPEgJTEj6flHmt0V8236nXLqK5LKB/Rg6WJxePYJACTKeM
|
|
||||||
/u4H5KVxazbIGSUek2MYZ59KwlhIr4HCaDng/kgQbf6jDbYZ5x1LiEO3i50XqIZ6
|
|
||||||
YTSRG3ApKsz1ECQU6FRVy+sS6FBBR0ti/OWqUS5WEyAOOewO37go3SoPBewLfnTt
|
|
||||||
I5oZN1pA1hCyCBK5VSRDPucpPqmY/90CggEAbFRUDyEkq9p7/Va/PYJLMe+1zGoy
|
|
||||||
+jCC1nm5LioxrUdpE+CV1t1cVutnlI3sRD+79oX/zwlwQ+pCx1XOMCmGs4uZUx5f
|
|
||||||
UtpGnsPamlyQKyQfPam3N4+4gaY9LLPiYCrI/XQh+vZQNlQTStuKLtb0R8+4wEER
|
|
||||||
KDTtC2cNN5fSnexEifpvq5yK3x6bH66pPyuRE27vVQ7diPar9A+VwkLs+zGbfnWW
|
|
||||||
MP/zYUbuiatC/LozcYLs/01m3Nu6oYi0OP/nFofepXNpQoZO8jKpnGRVVJ0EfgSe
|
|
||||||
f3qb9nkygj+gqGWT+PY6H39xKFz0h7dmmcP3Z7CrYXFEFfTCsUgbOKulAA==
|
|
||||||
-----END RSA PRIVATE KEY-----
|
|
|
@ -1 +0,0 @@
|
||||||
BAF3B5C5C6D0D14A
|
|
|
@ -1,27 +0,0 @@
|
||||||
-----BEGIN CERTIFICATE REQUEST-----
|
|
||||||
MIIEfzCCAmcCAQAwOjELMAkGA1UEBhMCVVMxCzAJBgNVBAgMAk5ZMRAwDgYDVQQK
|
|
||||||
DAdBdmFsYWJzMQwwCgYDVQQDDANhdmEwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAw
|
|
||||||
ggIKAoICAQDZnDoDHE2nj82xDjH0Tb7OXMqQDHz+zbLidt6MSI1XB3vOAIEiPqrt
|
|
||||||
enGnqRbVFcm5GZxvxh4YQD8CjKSk1qgZJczs0DPSiGQ8Efl4PGO4xnEbllgL3PUR
|
|
||||||
PWp7mEV3oh6fxICgQKTBlT671EnFzB5lyJWpumRzvA1vyhBMsY8aO+xdq5LUFltY
|
|
||||||
zBdvpgLXVaDwHZQ2PQEWtF0d0JO2N0WFFDGNmx6n8pKSeIAVDsTwZCZK+FCeeEyo
|
|
||||||
GfXsINsc0yCMQslawkfOMqA9yBV3Ji6QmFYKyGYt65MWGNqPA4XrIyliKwCCXwz9
|
|
||||||
mjaWyN7rAyw9cWlLMODNmDORWzGRZ5290MEAEIZsqjYHVitRTM/RnNIadToZGO0y
|
|
||||||
5uAkM14cmTvnsK1CP92qtfSisq75W/I91drThoEtTK78UGOl/5Q1YBR08F+tSUWZ
|
|
||||||
WyHeI6UOBUCGC2bCtmzKMl7vU25lG6mbCR1JuQi6RYpnfMjXH36lV4S7fTvSwwuR
|
|
||||||
03h2F3H1eFkWNG2lbFrW0dzDCPg3lXwmFQ65hUcQhctznoBz5C1lF2eW03wuVgxi
|
|
||||||
nnuVlJHjy/GrqmWsASn1PDuVs4k7k6DJfwyHAiA0uxXrGfxYvp7H8j4+2YOmWiWl
|
|
||||||
5xYgrEDjur5n8Zx46PHQer2Avq3sbEGEe1MCtXJlj3drd5Him3m+NQIDAQABoAAw
|
|
||||||
DQYJKoZIhvcNAQELBQADggIBAMdZKzx/Qz07D/ISgEe10+XofO5It86g12YJBgGN
|
|
||||||
4UEnKNk1quJIs0PAwcDNp7G4BpEMuP5xjyf4q976gzAkTg2kcB+LK85eGGSxkxAt
|
|
||||||
uFQPlFvk85qn4k7wLSx2zkqs47ItvqK5Ev8lLCZ/HfIy+7y57BKqDTvzhXarE3lq
|
|
||||||
bEZketwQvDcQPN7Ho9gxDMMQDeE2NeDyYhQtCMlX8PnmBRhWZ4CExODMdm8TrTJJ
|
|
||||||
5HDoj+fXCaSSbXPN25LKYSKOEM4wtzHa91hQK7JGoeHuSS0zFxDwXNKi3sLLtKTH
|
|
||||||
jsYL/E9bH2NxKPRoHwCJMS0N2jUqnHFyhQUp8VtJlxN0IsPLZGXFapVo4fk2hDpF
|
|
||||||
OapX0kysLV37KEklVHucQclU5SeTpzoS7gYXqvOJ3Q/IFR6CFAkCHaDggWpB/sVm
|
|
||||||
OPG6Pt6XXbGNCav9+Am+0q4UD5O1Sbobx+0XJu3VtnuZdn4Mt0uBSL1DZdG9ceig
|
|
||||||
mGz4bx1kvnzhL1LOAPmxOYqrLCwqJRkRCa+25uRNqBAqWcU48pwoxC3RLyWvy2UN
|
|
||||||
8Or+TsBzPUldq8yWn3s0/zE8yui6pxzpGUD2TfbUT78O0HJKn5nQjrjVdQZhaA4t
|
|
||||||
KnrZCz7lIrHRXf2Hbsg/9QgHhcpkknc98z0trNQHncp/kxUvrBJyJGrUh1DEkOSe
|
|
||||||
f9p0
|
|
||||||
-----END CERTIFICATE REQUEST-----
|
|
|
@ -1,5 +0,0 @@
|
||||||
#!/bin/sh
|
|
||||||
set -ex
|
|
||||||
|
|
||||||
openssl genrsa -out `dirname "$0"`/rootCA.key 4096
|
|
||||||
openssl req -x509 -new -nodes -key `dirname "$0"`/rootCA.key -sha256 -days 365250 -out `dirname "$0"`/rootCA.crt
|
|
|
@ -1,6 +0,0 @@
|
||||||
#!/bin/sh
|
|
||||||
set -ex
|
|
||||||
|
|
||||||
openssl genrsa -out `dirname "$0"`/staker.key 4096
|
|
||||||
openssl req -new -sha256 -key `dirname "$0"`/staker.key -subj "/C=US/ST=NY/O=Avalabs/CN=ava" -out `dirname "$0"`/staker.csr
|
|
||||||
openssl x509 -req -in `dirname "$0"`/staker.csr -CA `dirname "$0"`/rootCA.crt -CAkey `dirname "$0"`/rootCA.key -CAcreateserial -out `dirname "$0"`/staker.crt -days 365250 -sha256
|
|
|
@ -1,34 +0,0 @@
|
||||||
-----BEGIN CERTIFICATE-----
|
|
||||||
MIIF1jCCA76gAwIBAgIJALI1DF9cpwfEMA0GCSqGSIb3DQEBCwUAMH8xCzAJBgNV
|
|
||||||
BAYTAlVTMQswCQYDVQQIDAJOWTEPMA0GA1UEBwwGSXRoYWNhMRAwDgYDVQQKDAdB
|
|
||||||
dmFsYWJzMQ4wDAYDVQQLDAVHZWNrbzEMMAoGA1UEAwwDYXZhMSIwIAYJKoZIhvcN
|
|
||||||
AQkBFhNzdGVwaGVuQGF2YWxhYnMub3JnMCAXDTE5MDIyODIwNTkyNFoYDzMwMTkw
|
|
||||||
MzA4MjA1OTI0WjB/MQswCQYDVQQGEwJVUzELMAkGA1UECAwCTlkxDzANBgNVBAcM
|
|
||||||
Bkl0aGFjYTEQMA4GA1UECgwHQXZhbGFiczEOMAwGA1UECwwFR2Vja28xDDAKBgNV
|
|
||||||
BAMMA2F2YTEiMCAGCSqGSIb3DQEJARYTc3RlcGhlbkBhdmFsYWJzLm9yZzCCAiIw
|
|
||||||
DQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAJ45ScWV8tsCNO+NTIBuUYsPkhcg
|
|
||||||
jrp0HEyCHY3XEkxsLuDqtesNyv39YA0xQ3M3FP1e29tjFeHWJzyzV8O1H+6yco93
|
|
||||||
QAtzh9xELYD301Yq+x55yZrSjZxNIC5Tmz1ewTfD315lNR04M6JmqjrStIuLsWFU
|
|
||||||
m6P4OgXs4daqnyq9au4PYSrejcbexW59rKxLryK6Acv+E9Ax04oS33g9KqPmlRx0
|
|
||||||
lfu3x4nkIKIl+VaK1wC5CwJDYZ91KpEbC8Z2YvTeVDH+/hz/MvKl1CEaqK/4G5FB
|
|
||||||
KGEyd/bGRxMVQF41G7liJLaXzPLyZnKO2n21ZuJhkA9MZelt1U0LuQU505qU7IzW
|
|
||||||
cmKFEIb1MOrclaF19Is7HQlJWKyDo2/hfjSCZO8zH7eR9EGzKyQwZhwkYCycJD44
|
|
||||||
RKEHq6s/Z2dHUlpLIgRJ7k171TNkL9+xLntu8v1lzTkhemSNeO9asqJ7VcvpnMHH
|
|
||||||
bQXpDxJpi8jTnV8In8EolSqaKeN6/nzwbbSJ7gHehgpDhC1DlXPRzTt/ktQKlNGW
|
|
||||||
T5bdNdvYFyYTd9fu78aJZSbJo8jS2fykWuBgOgnlV8VmwpDa7iHM3EECByhf5GKB
|
|
||||||
J1jBlXO1ZyfJ7sNTbuVM7Uc2JkB4ASKdm3GZ3sFv95HjSTJAUORjE4pQ1es4kfDU
|
|
||||||
KqzDHH+bEHaGIGJTAgMBAAGjUzBRMB0GA1UdDgQWBBQr2T0duSMkvGXe3bSdWcei
|
|
||||||
73QtwzAfBgNVHSMEGDAWgBQr2T0duSMkvGXe3bSdWcei73QtwzAPBgNVHRMBAf8E
|
|
||||||
BTADAQH/MA0GCSqGSIb3DQEBCwUAA4ICAQBpP18zCdzvnSdPigg9wx+a8Znr4aJj
|
|
||||||
FxZYwBY6/BmKb56ke9g+zKKCw2dYYkRYDcTOEfuBgBvNeCSJv4R5rmkukkL8RCIG
|
|
||||||
XV/WfSn2d3Mnz5KTgGQS6Q9s5qx+8ydkiGZthi+8a8ltXczyYrvWgd47U0NWTcOY
|
|
||||||
omjgF6XF+hVLWLgiwmA468pd7wyCsuJJkyxxeyDPXQ422I1AJW/7c5JQQa+lDNsv
|
|
||||||
Vna6420mZ/DiQd3stFkdjhRjmBZvGQ09g6l3zo6TgI1TWr5TMYPrempBVCWPNilC
|
|
||||||
XaMysU77+tPutI+7kMBuGvLuZtPrH/2uTYdXWPodyORm5i2ABF6In3VISPD9YNc0
|
|
||||||
gWx3PYGi2BfdnZepCojsffUMlhT3SsiAKMYv5FhW8LQBNMRR4721U1Vf5f8fzNQn
|
|
||||||
3E55TthV5HXZQ6HcLhkmOvH8CMqtWGETTbBtYSA2AVMjoqs7QDGkfsCH9UuwGd1N
|
|
||||||
W12JOf53XyOQT2XwWerSQC2kv7elsTh6Bk7PhvrCi0OwCVSGny5IQY/aXM1n6Z6s
|
|
||||||
scJlZmq6P3AJZ3tRtBt9yDK7iIW7mzNLTb/kAjsNQh06oETJIJ0CIgL0Bn6CANYU
|
|
||||||
kNqB4oTxmAhdOPKNgqaIwdZAL1VDIVaQEcvGeZRduo7yZvA/MhuQD8IIKSeOBFaD
|
|
||||||
DB8IRfWqBx2nWw==
|
|
||||||
-----END CERTIFICATE-----
|
|
|
@ -1,51 +0,0 @@
|
||||||
-----BEGIN RSA PRIVATE KEY-----
|
|
||||||
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
|
|
||||||
-----END RSA PRIVATE KEY-----
|
|
|
@ -1 +0,0 @@
|
||||||
BAF3B5C5C6D0D14A
|
|
|
@ -1,27 +0,0 @@
|
||||||
-----BEGIN CERTIFICATE REQUEST-----
|
|
||||||
MIIEfzCCAmcCAQAwOjELMAkGA1UEBhMCVVMxCzAJBgNVBAgMAk5ZMRAwDgYDVQQK
|
|
||||||
DAdBdmFsYWJzMQwwCgYDVQQDDANhdmEwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAw
|
|
||||||
ggIKAoICAQDgK5r5vdHtJFEgw7hGE/lzKaHcvwzr32armq0k9tYchJXfT3k1j1lX
|
|
||||||
tBAdcUN3gSRKjgzH/vjbn0ea3AiDCUd2Mck/n0KcJZ43S5I7ZjP7rbav296bKCZ1
|
|
||||||
Hr7r5gXYFhk+3aUsVfDUqAPBwyP8KeV31ARVA/s+WPeWqs69QXTdyJuBYE5pr40v
|
|
||||||
1Sf+ebUInZ37uGY3kiO0Ex/JgcoQsGJzrWD/ztbRCFIvrdNJZd0pGvMlmTKp7XsM
|
|
||||||
R3cpvqk770//MLCdyGW/1IArTSuD1vd7mBX1JyVXKycYN0vIOtbgxPOFutUyqDOe
|
|
||||||
P7o51q4iPS3dCRgfmn/hWLwy+CtJe0BGKsb4tk0tKxo0se8v9JA8mUtnmzmMt4Y9
|
|
||||||
jijOrCOB7XwWKmJYEm8N5Ubcy6cp2oL8vQVtzz3PXrkFt+3cFt1jrjdpQYgH4jyk
|
|
||||||
kWDeOjEfy1FCwzsNRudLTvLhfLn86/ZT4cLZ9JI7/WW0IPC8Fc7lhznJ+bIQUeEn
|
|
||||||
daGdgVkxuEg0MxdrMr0jU0IFoXySRXNRzcDWZShEjBTv7tnFxLmoNU+uJb/KpMH6
|
|
||||||
sRYi3zs85ecaMKNyG+LDmBahUlHx5hKAH49O8855+AMhsg91ONZJldjQX0oZrIKz
|
|
||||||
K5BpsqeTl4c2Yt/fALiZaeFk1pBEsvVeMOBCIuWE+b4UIEaLAOhxfwIDAQABoAAw
|
|
||||||
DQYJKoZIhvcNAQELBQADggIBAMWzSdk6C53ijuLYOt77BAYpxnxRvKA1tsxJd9K5
|
|
||||||
+R+ZGiuTLXWArgClhhwx65OTeqrwkVlh2CZoVTBeEMzvxn6zHO4S20KcWJ1lWU76
|
|
||||||
OIrBZrAecBVXB5LmttUkvlMgVlWLQuVpVJiEn1jW6KeABqWKCLz7Au8TzHfr1HQ4
|
|
||||||
1ukndu3SsKVwSIy0ZHFpQaXvzA8f0V93ap9R2RVw9BXqCJDe+BtQPvlCwOrvQ7d3
|
|
||||||
gg+3aymbqUx3hrscEvd1ETad7LyFw3QfPcr1j1FwPH+K1/UDrWxIzxmO+HM5Lh8f
|
|
||||||
269aYceysgv/xa/KpANTxVAM7j1SE1CjjI5e5CQJVZ+gtAqTIv3lLkk0dWQksObN
|
|
||||||
Z1tTtJkFAUNbGsMadtVeTmx2eBcRi4LEv0DIPyyWUQTWwTYtaMFi8I0bYPk1T/fV
|
|
||||||
9umR6jqZ0l1qdiuLYOSYUx4iI5SAmCrA/kEINOj0u2gqqkxdOgUVsuKqer4w9Iyt
|
|
||||||
qOhhOHwctRo+cIhpVwcF2ouJeNrFqoBzOgHKQxBvcDWJM8ra5GCNIvD3MP4Q63hy
|
|
||||||
b4fkBcYwb1B2ETH9nSDtfW+JLjt70rvf6IxAiXRRiOv4fPzaUlK49NRVgjzx5Iu+
|
|
||||||
8Zq4+I+S6qZOROWsOVSpJu44VvNZd5bMB9dEHnkoGxkPjo8pkC/o0uZbxsnZScSL
|
|
||||||
WGxS
|
|
||||||
-----END CERTIFICATE REQUEST-----
|
|
|
@ -1,5 +0,0 @@
|
||||||
#!/bin/sh
|
|
||||||
set -ex
|
|
||||||
|
|
||||||
openssl genrsa -out `dirname "$0"`/rootCA.key 4096
|
|
||||||
openssl req -x509 -new -nodes -key `dirname "$0"`/rootCA.key -sha256 -days 365250 -out `dirname "$0"`/rootCA.crt
|
|
|
@ -1,34 +0,0 @@
|
||||||
-----BEGIN CERTIFICATE-----
|
|
||||||
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
|
|
||||||
DB8IRfWqBx2nWw==
|
|
||||||
-----END CERTIFICATE-----
|
|
|
@ -1,51 +0,0 @@
|
||||||
-----BEGIN RSA PRIVATE KEY-----
|
|
||||||
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
|
|
||||||
-----END RSA PRIVATE KEY-----
|
|
|
@ -1 +0,0 @@
|
||||||
BAF3B5C5C6D0D164
|
|
|
@ -0,0 +1 @@
|
||||||
|
BAF3B5C5C6D0D166
|
111
main/params.go
111
main/params.go
|
@ -8,6 +8,7 @@ import (
|
||||||
"flag"
|
"flag"
|
||||||
"fmt"
|
"fmt"
|
||||||
"net"
|
"net"
|
||||||
|
"os"
|
||||||
"path"
|
"path"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
@ -32,6 +33,22 @@ var (
|
||||||
Err error
|
Err error
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// GetIPs returns the default IPs for each network
|
||||||
|
func GetIPs(networkID uint32) []string {
|
||||||
|
switch networkID {
|
||||||
|
case genesis.CascadeID:
|
||||||
|
return []string{
|
||||||
|
"3.227.207.132:21001",
|
||||||
|
"34.207.133.167:21001",
|
||||||
|
"107.23.241.199:21001",
|
||||||
|
"54.197.215.186:21001",
|
||||||
|
"18.234.153.22:21001",
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
var (
|
var (
|
||||||
errBootstrapMismatch = errors.New("more bootstrap IDs provided than bootstrap IPs")
|
errBootstrapMismatch = errors.New("more bootstrap IDs provided than bootstrap IPs")
|
||||||
)
|
)
|
||||||
|
@ -44,72 +61,81 @@ func init() {
|
||||||
loggingConfig, err := logging.DefaultConfig()
|
loggingConfig, err := logging.DefaultConfig()
|
||||||
errs.Add(err)
|
errs.Add(err)
|
||||||
|
|
||||||
|
fs := flag.NewFlagSet("gecko", flag.ContinueOnError)
|
||||||
|
|
||||||
// NetworkID:
|
// NetworkID:
|
||||||
networkName := flag.String("network-id", genesis.LocalName, "Network ID this node will connect to")
|
networkName := fs.String("network-id", genesis.CascadeName, "Network ID this node will connect to")
|
||||||
|
|
||||||
// Ava fees:
|
// 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:
|
// Assertions:
|
||||||
flag.BoolVar(&loggingConfig.Assertions, "assertions-enabled", true, "Turn on assertion execution")
|
fs.BoolVar(&loggingConfig.Assertions, "assertions-enabled", true, "Turn on assertion execution")
|
||||||
|
|
||||||
// Crypto:
|
// 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:
|
// Database:
|
||||||
db := flag.Bool("db-enabled", true, "Turn on persistent storage")
|
db := fs.Bool("db-enabled", true, "Turn on persistent storage")
|
||||||
dbDir := flag.String("db-dir", "db", "Database directory for Ava state")
|
dbDir := fs.String("db-dir", "db", "Database directory for Ava state")
|
||||||
|
|
||||||
// IP:
|
// IP:
|
||||||
consensusIP := flag.String("public-ip", "", "Public IP of this node")
|
consensusIP := fs.String("public-ip", "", "Public IP of this node")
|
||||||
|
|
||||||
// HTTP Server:
|
// HTTP Server:
|
||||||
httpPort := flag.Uint("http-port", 9650, "Port of the HTTP server")
|
httpPort := fs.Uint("http-port", 9650, "Port of the HTTP server")
|
||||||
flag.BoolVar(&Config.EnableHTTPS, "http-tls-enabled", false, "Upgrade the HTTP server to HTTPs")
|
fs.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")
|
fs.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")
|
fs.StringVar(&Config.HTTPSCertFile, "http-tls-cert-file", "", "TLS certificate file for the HTTPs server")
|
||||||
|
|
||||||
// Bootstrapping:
|
// 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")
|
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 := flag.String("bootstrap-ids", "", "Comma separated list of bootstrap peer ids to connect to. Example: JR4dVmy6ffUGAKCBDkyCbeZbyHQBeDsET,8CrVPQZ4VSqgL8zTdvL14G8HqAfrBr4z")
|
bootstrapIDs := fs.String("bootstrap-ids", "default", "Comma separated list of bootstrap peer ids to connect to. Example: JR4dVmy6ffUGAKCBDkyCbeZbyHQBeDsET,8CrVPQZ4VSqgL8zTdvL14G8HqAfrBr4z")
|
||||||
|
|
||||||
// Staking:
|
// Staking:
|
||||||
consensusPort := flag.Uint("staking-port", 9651, "Port of the consensus server")
|
consensusPort := fs.Uint("staking-port", 9651, "Port of the consensus server")
|
||||||
flag.BoolVar(&Config.EnableStaking, "staking-tls-enabled", true, "Require TLS to authenticate staking connections")
|
fs.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")
|
fs.StringVar(&Config.StakingKeyFile, "staking-tls-key-file", "keys/staker.key", "TLS private key file for staking connections")
|
||||||
flag.StringVar(&Config.StakingCertFile, "staking-tls-cert-file", "", "TLS certificate file for staking connections")
|
fs.StringVar(&Config.StakingCertFile, "staking-tls-cert-file", "keys/staker.crt", "TLS certificate file for staking connections")
|
||||||
|
|
||||||
// Logging:
|
// Logging:
|
||||||
logsDir := flag.String("log-dir", "", "Logging directory for Ava")
|
logsDir := fs.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}")
|
logLevel := fs.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}")
|
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")
|
fs.IntVar(&Config.ConsensusParams.K, "snow-sample-size", 5, "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")
|
fs.IntVar(&Config.ConsensusParams.Alpha, "snow-quorum-size", 4, "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")
|
fs.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")
|
fs.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")
|
fs.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.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:
|
// Enable/Disable APIs:
|
||||||
flag.BoolVar(&Config.AdminAPIEnabled, "api-admin-enabled", true, "If true, this node exposes the Admin API")
|
fs.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")
|
fs.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")
|
fs.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.IPCEnabled, "api-ipcs-enabled", false, "If true, IPCs can be opened")
|
||||||
|
|
||||||
// Throughput Server
|
// Throughput Server
|
||||||
throughputPort := flag.Uint("xput-server-port", 9652, "Port of the deprecated throughput test server")
|
throughputPort := fs.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")
|
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)
|
networkID, err := genesis.NetworkID(*networkName)
|
||||||
errs.Add(err)
|
errs.Add(err)
|
||||||
|
|
||||||
if networkID != genesis.LocalID {
|
|
||||||
errs.Add(fmt.Errorf("the only supported networkID is: %s", genesis.LocalName))
|
|
||||||
}
|
|
||||||
|
|
||||||
Config.NetworkID = networkID
|
Config.NetworkID = networkID
|
||||||
|
|
||||||
// DB:
|
// DB:
|
||||||
|
@ -143,6 +169,9 @@ func init() {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Bootstrapping:
|
// Bootstrapping:
|
||||||
|
if *bootstrapIPs == "default" {
|
||||||
|
*bootstrapIPs = strings.Join(GetIPs(networkID), ",")
|
||||||
|
}
|
||||||
for _, ip := range strings.Split(*bootstrapIPs, ",") {
|
for _, ip := range strings.Split(*bootstrapIPs, ",") {
|
||||||
if ip != "" {
|
if ip != "" {
|
||||||
addr, err := utils.ToIPDesc(ip)
|
addr, err := utils.ToIPDesc(ip)
|
||||||
|
@ -152,6 +181,14 @@ func init() {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if *bootstrapIDs == "default" {
|
||||||
|
if *bootstrapIPs == "" {
|
||||||
|
*bootstrapIDs = ""
|
||||||
|
} else {
|
||||||
|
*bootstrapIDs = strings.Join(genesis.GetConfig(networkID).StakerIDs, ",")
|
||||||
|
}
|
||||||
|
}
|
||||||
if Config.EnableStaking {
|
if Config.EnableStaking {
|
||||||
i := 0
|
i := 0
|
||||||
cb58 := formatting.CB58{}
|
cb58 := formatting.CB58{}
|
||||||
|
|
|
@ -54,6 +54,13 @@ Periodically gossip peerlists.
|
||||||
stakers should be in the set).
|
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 (
|
const (
|
||||||
// CurrentVersion this avalanche instance is executing.
|
// CurrentVersion this avalanche instance is executing.
|
||||||
CurrentVersion = "avalanche/0.0.1"
|
CurrentVersion = "avalanche/0.0.1"
|
||||||
|
@ -70,6 +77,9 @@ const (
|
||||||
// GetVersionTimeout is the amount of time to wait before sending a
|
// GetVersionTimeout is the amount of time to wait before sending a
|
||||||
// getVersion message to a partially connected peer
|
// getVersion message to a partially connected peer
|
||||||
GetVersionTimeout = 2 * time.Second
|
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
|
// 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
|
connections AddrCert // Connections that I think are connected
|
||||||
|
|
||||||
versionTimeout timer.TimeoutManager
|
versionTimeout timer.TimeoutManager
|
||||||
|
reconnectTimeout timer.TimeoutManager
|
||||||
peerListGossiper *timer.Repeater
|
peerListGossiper *timer.Repeater
|
||||||
|
|
||||||
awaitingLock sync.Mutex
|
awaitingLock sync.Mutex
|
||||||
|
@ -143,6 +154,10 @@ func (nm *Handshake) Initialize(
|
||||||
|
|
||||||
nm.versionTimeout.Initialize(GetVersionTimeout)
|
nm.versionTimeout.Initialize(GetVersionTimeout)
|
||||||
go nm.log.RecoverAndPanic(nm.versionTimeout.Dispatch)
|
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)
|
nm.peerListGossiper = timer.NewRepeater(nm.gossipPeerList, PeerListGossipSpacing)
|
||||||
go nm.log.RecoverAndPanic(nm.peerListGossiper.Dispatch)
|
go nm.log.RecoverAndPanic(nm.peerListGossiper.Dispatch)
|
||||||
}
|
}
|
||||||
|
@ -290,6 +305,73 @@ func checkPeerCertificate(_ *C.struct_msgnetwork_conn_t, connected C.bool, _ uns
|
||||||
return connected
|
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
|
// peerHandler notifies a change to the set of connected peers
|
||||||
// connected is true if a new peer is connected
|
// connected is true if a new peer is connected
|
||||||
// connected is false if a formerly connected peer has disconnected
|
// 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))
|
pConn := salticidae.PeerNetworkConnFromC(salticidae.CPeerNetworkConn(_conn))
|
||||||
addr := pConn.GetPeerAddr(true)
|
addr := pConn.GetPeerAddr(true)
|
||||||
|
|
||||||
ip := toIPDesc(addr)
|
if connected {
|
||||||
if !connected {
|
HandshakeNet.connectedToPeer(_conn, addr)
|
||||||
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)
|
|
||||||
} else {
|
} 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
|
// unknownPeerHandler notifies of an unknown peer connection attempt
|
||||||
//export unknownPeerHandler
|
//export unknownPeerHandler
|
||||||
func unknownPeerHandler(_addr *C.netaddr_t, _cert *C.x509_t, _ unsafe.Pointer) {
|
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)
|
ip := toIPDesc(addr)
|
||||||
HandshakeNet.log.Info("Adding peer %s", ip)
|
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)
|
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()
|
cErr := salticidae.NewError()
|
||||||
for _, ip := range ips {
|
for _, ip := range ips {
|
||||||
HandshakeNet.log.Verbo("Trying to adding peer %s", ip)
|
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
|
if cErr.GetCode() == 0 && !HandshakeNet.myAddr.IsEq(addr) { // Make sure not to connect to myself
|
||||||
ip := toIPDesc(addr)
|
ip := toIPDesc(addr)
|
||||||
|
ipCert := toShortID(ip)
|
||||||
|
|
||||||
if !HandshakeNet.pending.ContainsIP(addr) && !HandshakeNet.connections.ContainsIP(addr) {
|
if !HandshakeNet.pending.ContainsIP(addr) && !HandshakeNet.connections.ContainsIP(addr) {
|
||||||
HandshakeNet.log.Debug("Adding peer %s", ip)
|
HandshakeNet.log.Debug("Adding peer %s", ip)
|
||||||
|
|
||||||
|
HandshakeNet.reconnectTimeout.Put(ipCert.LongID(), func() {
|
||||||
|
HandshakeNet.net.DelPeer(addr)
|
||||||
|
})
|
||||||
HandshakeNet.net.AddPeer(addr)
|
HandshakeNet.net.AddPeer(addr)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
addr.Free()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -366,9 +366,9 @@ func (s *Voting) PullQuery(validatorIDs ids.ShortSet, chainID ids.ID, requestID
|
||||||
vID := validatorID
|
vID := validatorID
|
||||||
if addr, exists := s.conns.GetIP(vID); exists {
|
if addr, exists := s.conns.GetIP(vID); exists {
|
||||||
addrs = append(addrs, addr)
|
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 {
|
} 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) })
|
s.executor.Add(func() { s.router.QueryFailed(vID, chainID, requestID) })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
164
node/node.go
164
node/node.go
|
@ -25,6 +25,7 @@ import (
|
||||||
"github.com/ava-labs/gecko/api/keystore"
|
"github.com/ava-labs/gecko/api/keystore"
|
||||||
"github.com/ava-labs/gecko/api/metrics"
|
"github.com/ava-labs/gecko/api/metrics"
|
||||||
"github.com/ava-labs/gecko/chains"
|
"github.com/ava-labs/gecko/chains"
|
||||||
|
"github.com/ava-labs/gecko/chains/atomic"
|
||||||
"github.com/ava-labs/gecko/database"
|
"github.com/ava-labs/gecko/database"
|
||||||
"github.com/ava-labs/gecko/database/prefixdb"
|
"github.com/ava-labs/gecko/database/prefixdb"
|
||||||
"github.com/ava-labs/gecko/genesis"
|
"github.com/ava-labs/gecko/genesis"
|
||||||
|
@ -35,10 +36,13 @@ import (
|
||||||
"github.com/ava-labs/gecko/snow/validators"
|
"github.com/ava-labs/gecko/snow/validators"
|
||||||
"github.com/ava-labs/gecko/utils/hashing"
|
"github.com/ava-labs/gecko/utils/hashing"
|
||||||
"github.com/ava-labs/gecko/utils/logging"
|
"github.com/ava-labs/gecko/utils/logging"
|
||||||
|
"github.com/ava-labs/gecko/utils/wrappers"
|
||||||
"github.com/ava-labs/gecko/vms"
|
"github.com/ava-labs/gecko/vms"
|
||||||
"github.com/ava-labs/gecko/vms/avm"
|
"github.com/ava-labs/gecko/vms/avm"
|
||||||
"github.com/ava-labs/gecko/vms/evm"
|
"github.com/ava-labs/gecko/vms/evm"
|
||||||
|
"github.com/ava-labs/gecko/vms/nftfx"
|
||||||
"github.com/ava-labs/gecko/vms/platformvm"
|
"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/secp256k1fx"
|
||||||
"github.com/ava-labs/gecko/vms/spchainvm"
|
"github.com/ava-labs/gecko/vms/spchainvm"
|
||||||
"github.com/ava-labs/gecko/vms/spdagvm"
|
"github.com/ava-labs/gecko/vms/spdagvm"
|
||||||
|
@ -49,6 +53,10 @@ const (
|
||||||
maxMessageSize = 1 << 25 // maximum size of a message sent with salticidae
|
maxMessageSize = 1 << 25 // maximum size of a message sent with salticidae
|
||||||
)
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
genesisHashKey = []byte("genesisID")
|
||||||
|
)
|
||||||
|
|
||||||
// MainNode is the reference for node callbacks
|
// MainNode is the reference for node callbacks
|
||||||
var MainNode = Node{}
|
var MainNode = Node{}
|
||||||
|
|
||||||
|
@ -68,6 +76,9 @@ type Node struct {
|
||||||
// Handles calls to Keystore API
|
// Handles calls to Keystore API
|
||||||
keystoreServer keystore.Keystore
|
keystoreServer keystore.Keystore
|
||||||
|
|
||||||
|
// Manages shared memory
|
||||||
|
sharedMemory atomic.SharedMemory
|
||||||
|
|
||||||
// Manages creation of blockchains and routing messages to them
|
// Manages creation of blockchains and routing messages to them
|
||||||
chainManager chains.Manager
|
chainManager chains.Manager
|
||||||
|
|
||||||
|
@ -285,7 +296,38 @@ func (n *Node) Dispatch() { n.EC.Dispatch() }
|
||||||
******************************************************************************
|
******************************************************************************
|
||||||
*/
|
*/
|
||||||
|
|
||||||
func (n *Node) initDatabase() { n.DB = n.Config.DB }
|
func (n *Node) initDatabase() error {
|
||||||
|
n.DB = n.Config.DB
|
||||||
|
|
||||||
|
expectedGenesis, err := genesis.Genesis(n.Config.NetworkID)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
rawExpectedGenesisHash := hashing.ComputeHash256(expectedGenesis)
|
||||||
|
|
||||||
|
rawGenesisHash, err := n.DB.Get(genesisHashKey)
|
||||||
|
if err == database.ErrNotFound {
|
||||||
|
rawGenesisHash = rawExpectedGenesisHash
|
||||||
|
err = n.DB.Put(genesisHashKey, rawGenesisHash)
|
||||||
|
}
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
genesisHash, err := ids.ToID(rawGenesisHash)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
expectedGenesisHash, err := ids.ToID(rawExpectedGenesisHash)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if !genesisHash.Equals(expectedGenesisHash) {
|
||||||
|
return fmt.Errorf("db contains invalid genesis hash. DB Genesis: %s Generated Genesis: %s", genesisHash, expectedGenesisHash)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
// Initialize this node's ID
|
// Initialize this node's ID
|
||||||
// If staking is disabled, a node's ID is a hash of its IP
|
// If staking is disabled, a node's ID is a hash of its IP
|
||||||
|
@ -320,14 +362,29 @@ func (n *Node) initNodeID() error {
|
||||||
// AVM, EVM, Simple Payments DAG, Simple Payments Chain
|
// AVM, EVM, Simple Payments DAG, Simple Payments Chain
|
||||||
// The Platform VM is registered in initStaking because
|
// The Platform VM is registered in initStaking because
|
||||||
// its factory needs to reference n.chainManager, which is nil right now
|
// its factory needs to reference n.chainManager, which is nil right now
|
||||||
func (n *Node) initVMManager() {
|
func (n *Node) initVMManager() error {
|
||||||
|
avaAssetID, err := genesis.AVAAssetID(n.Config.NetworkID)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
n.vmManager = vms.NewManager(&n.APIServer, n.HTTPLog)
|
n.vmManager = vms.NewManager(&n.APIServer, n.HTTPLog)
|
||||||
n.vmManager.RegisterVMFactory(avm.ID, &avm.Factory{})
|
|
||||||
n.vmManager.RegisterVMFactory(evm.ID, &evm.Factory{})
|
errs := wrappers.Errs{}
|
||||||
n.vmManager.RegisterVMFactory(spdagvm.ID, &spdagvm.Factory{TxFee: n.Config.AvaTxFee})
|
errs.Add(
|
||||||
n.vmManager.RegisterVMFactory(spchainvm.ID, &spchainvm.Factory{})
|
n.vmManager.RegisterVMFactory(avm.ID, &avm.Factory{
|
||||||
n.vmManager.RegisterVMFactory(secp256k1fx.ID, &secp256k1fx.Factory{})
|
AVA: avaAssetID,
|
||||||
n.vmManager.RegisterVMFactory(timestampvm.ID, ×tampvm.Factory{})
|
Platform: ids.Empty,
|
||||||
|
}),
|
||||||
|
n.vmManager.RegisterVMFactory(evm.ID, &evm.Factory{}),
|
||||||
|
n.vmManager.RegisterVMFactory(spdagvm.ID, &spdagvm.Factory{TxFee: n.Config.AvaTxFee}),
|
||||||
|
n.vmManager.RegisterVMFactory(spchainvm.ID, &spchainvm.Factory{}),
|
||||||
|
n.vmManager.RegisterVMFactory(timestampvm.ID, ×tampvm.Factory{}),
|
||||||
|
n.vmManager.RegisterVMFactory(secp256k1fx.ID, &secp256k1fx.Factory{}),
|
||||||
|
n.vmManager.RegisterVMFactory(nftfx.ID, &nftfx.Factory{}),
|
||||||
|
n.vmManager.RegisterVMFactory(propertyfx.ID, &propertyfx.Factory{}),
|
||||||
|
)
|
||||||
|
return errs.Err
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create the EventDispatcher used for hooking events
|
// Create the EventDispatcher used for hooking events
|
||||||
|
@ -343,38 +400,64 @@ func (n *Node) initEventDispatcher() {
|
||||||
// Initializes the Platform chain.
|
// Initializes the Platform chain.
|
||||||
// Its genesis data specifies the other chains that should
|
// Its genesis data specifies the other chains that should
|
||||||
// be created.
|
// be created.
|
||||||
func (n *Node) initChains() {
|
func (n *Node) initChains() error {
|
||||||
n.Log.Info("initializing chains")
|
n.Log.Info("initializing chains")
|
||||||
|
|
||||||
vdrs := n.vdrs
|
vdrs := n.vdrs
|
||||||
|
|
||||||
|
// If staking is disabled, ignore updates to Subnets' validator sets
|
||||||
|
// Instead of updating node's validator manager, platform chain makes changes
|
||||||
|
// to its own local validator manager (which isn't used for sampling)
|
||||||
if !n.Config.EnableStaking {
|
if !n.Config.EnableStaking {
|
||||||
defaultSubnetValidators := validators.NewSet()
|
defaultSubnetValidators := validators.NewSet()
|
||||||
|
defaultSubnetValidators.Add(validators.NewValidator(n.ID, 1))
|
||||||
vdrs = validators.NewManager()
|
vdrs = validators.NewManager()
|
||||||
vdrs.PutValidatorSet(platformvm.DefaultSubnetID, defaultSubnetValidators)
|
vdrs.PutValidatorSet(platformvm.DefaultSubnetID, defaultSubnetValidators)
|
||||||
}
|
}
|
||||||
|
|
||||||
n.vmManager.RegisterVMFactory(
|
avaAssetID, err := genesis.AVAAssetID(n.Config.NetworkID)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
createAVMTx, err := genesis.VMGenesis(n.Config.NetworkID, avm.ID)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
err = n.vmManager.RegisterVMFactory(
|
||||||
/*vmID=*/ platformvm.ID,
|
/*vmID=*/ platformvm.ID,
|
||||||
/*vmFactory=*/ &platformvm.Factory{
|
/*vmFactory=*/ &platformvm.Factory{
|
||||||
ChainManager: n.chainManager,
|
ChainManager: n.chainManager,
|
||||||
Validators: vdrs,
|
Validators: vdrs,
|
||||||
|
StakingEnabled: n.Config.EnableStaking,
|
||||||
|
AVA: avaAssetID,
|
||||||
|
AVM: createAVMTx.ID(),
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
beacons := validators.NewSet()
|
beacons := validators.NewSet()
|
||||||
for _, peer := range n.Config.BootstrapPeers {
|
for _, peer := range n.Config.BootstrapPeers {
|
||||||
beacons.Add(validators.NewValidator(peer.ID, 1))
|
beacons.Add(validators.NewValidator(peer.ID, 1))
|
||||||
}
|
}
|
||||||
|
|
||||||
genesisBytes := genesis.Genesis(n.Config.NetworkID)
|
genesisBytes, err := genesis.Genesis(n.Config.NetworkID)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
// Create the Platform Chain
|
// Create the Platform Chain
|
||||||
n.chainManager.ForceCreateChain(chains.ChainParameters{
|
n.chainManager.ForceCreateChain(chains.ChainParameters{
|
||||||
ID: ids.Empty,
|
ID: ids.Empty,
|
||||||
|
SubnetID: platformvm.DefaultSubnetID,
|
||||||
GenesisData: genesisBytes, // Specifies other chains to create
|
GenesisData: genesisBytes, // Specifies other chains to create
|
||||||
VMAlias: platformvm.ID.String(),
|
VMAlias: platformvm.ID.String(),
|
||||||
CustomBeacons: beacons,
|
CustomBeacons: beacons,
|
||||||
})
|
})
|
||||||
|
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// initAPIServer initializes the server that handles HTTP calls
|
// initAPIServer initializes the server that handles HTTP calls
|
||||||
|
@ -400,6 +483,7 @@ func (n *Node) initAPIServer() {
|
||||||
// Assumes n.DB, n.vdrs all initialized (non-nil)
|
// Assumes n.DB, n.vdrs all initialized (non-nil)
|
||||||
func (n *Node) initChainManager() {
|
func (n *Node) initChainManager() {
|
||||||
n.chainManager = chains.New(
|
n.chainManager = chains.New(
|
||||||
|
n.Config.EnableStaking,
|
||||||
n.Log,
|
n.Log,
|
||||||
n.LogFactory,
|
n.LogFactory,
|
||||||
n.vmManager,
|
n.vmManager,
|
||||||
|
@ -415,12 +499,20 @@ func (n *Node) initChainManager() {
|
||||||
n.ValidatorAPI,
|
n.ValidatorAPI,
|
||||||
&n.APIServer,
|
&n.APIServer,
|
||||||
&n.keystoreServer,
|
&n.keystoreServer,
|
||||||
|
&n.sharedMemory,
|
||||||
)
|
)
|
||||||
|
|
||||||
n.chainManager.AddRegistrant(&n.APIServer)
|
n.chainManager.AddRegistrant(&n.APIServer)
|
||||||
}
|
}
|
||||||
|
|
||||||
// initWallet initializes the Wallet service
|
// initSharedMemory initializes the shared memory for cross chain interation
|
||||||
|
func (n *Node) initSharedMemory() {
|
||||||
|
n.Log.Info("initializing SharedMemory")
|
||||||
|
sharedMemoryDB := prefixdb.New([]byte("shared memory"), n.DB)
|
||||||
|
n.sharedMemory.Initialize(n.Log, sharedMemoryDB)
|
||||||
|
}
|
||||||
|
|
||||||
|
// initKeystoreAPI initializes the keystore service
|
||||||
// Assumes n.APIServer is already set
|
// Assumes n.APIServer is already set
|
||||||
func (n *Node) initKeystoreAPI() {
|
func (n *Node) initKeystoreAPI() {
|
||||||
n.Log.Info("initializing Keystore API")
|
n.Log.Info("initializing Keystore API")
|
||||||
|
@ -464,24 +556,35 @@ func (n *Node) initIPCAPI() {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Give chains and VMs aliases as specified by the genesis information
|
// Give chains and VMs aliases as specified by the genesis information
|
||||||
func (n *Node) initAliases() {
|
func (n *Node) initAliases() error {
|
||||||
n.Log.Info("initializing aliases")
|
n.Log.Info("initializing aliases")
|
||||||
defaultAliases, chainAliases, vmAliases := genesis.Aliases(n.Config.NetworkID)
|
defaultAliases, chainAliases, vmAliases, err := genesis.Aliases(n.Config.NetworkID)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
for chainIDKey, aliases := range chainAliases {
|
for chainIDKey, aliases := range chainAliases {
|
||||||
chainID := ids.NewID(chainIDKey)
|
chainID := ids.NewID(chainIDKey)
|
||||||
for _, alias := range aliases {
|
for _, alias := range aliases {
|
||||||
n.Log.AssertNoError(n.chainManager.Alias(chainID, alias))
|
if err := n.chainManager.Alias(chainID, alias); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for vmIDKey, aliases := range vmAliases {
|
for vmIDKey, aliases := range vmAliases {
|
||||||
vmID := ids.NewID(vmIDKey)
|
vmID := ids.NewID(vmIDKey)
|
||||||
for _, alias := range aliases {
|
for _, alias := range aliases {
|
||||||
n.Log.AssertNoError(n.vmManager.Alias(vmID, alias))
|
if err := n.vmManager.Alias(vmID, alias); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for url, aliases := range defaultAliases {
|
for url, aliases := range defaultAliases {
|
||||||
n.APIServer.AddAliases(url, aliases...)
|
if err := n.APIServer.AddAliases(url, aliases...); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Initialize this node
|
// Initialize this node
|
||||||
|
@ -496,12 +599,17 @@ func (n *Node) Initialize(Config *Config, logger logging.Logger, logFactory logg
|
||||||
}
|
}
|
||||||
n.HTTPLog = httpLog
|
n.HTTPLog = httpLog
|
||||||
|
|
||||||
n.initDatabase() // Set up the node's database
|
if err := n.initDatabase(); err != nil { // Set up the node's database
|
||||||
|
return fmt.Errorf("problem initializing database: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
if err = n.initNodeID(); err != nil { // Derive this node's ID
|
if err = n.initNodeID(); err != nil { // Derive this node's ID
|
||||||
return fmt.Errorf("problem initializing staker ID: %w", err)
|
return fmt.Errorf("problem initializing staker ID: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// initialize shared memory
|
||||||
|
n.initSharedMemory()
|
||||||
|
|
||||||
// Start HTTP APIs
|
// Start HTTP APIs
|
||||||
n.initAPIServer() // Start the API Server
|
n.initAPIServer() // Start the API Server
|
||||||
n.initKeystoreAPI() // Start the Keystore API
|
n.initKeystoreAPI() // Start the Keystore API
|
||||||
|
@ -511,8 +619,13 @@ func (n *Node) Initialize(Config *Config, logger logging.Logger, logFactory logg
|
||||||
if err = n.initNetlib(); err != nil { // Set up all networking
|
if err = n.initNetlib(); err != nil { // Set up all networking
|
||||||
return fmt.Errorf("problem initializing networking: %w", err)
|
return fmt.Errorf("problem initializing networking: %w", err)
|
||||||
}
|
}
|
||||||
n.initValidatorNet() // Set up the validator handshake + authentication
|
if err := n.initValidatorNet(); err != nil { // Set up the validator handshake + authentication
|
||||||
n.initVMManager() // Set up the vm manager
|
return fmt.Errorf("problem initializing validator network: %w", err)
|
||||||
|
}
|
||||||
|
if err := n.initVMManager(); err != nil { // Set up the vm manager
|
||||||
|
return fmt.Errorf("problem initializing the VM manager: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
n.initEventDispatcher() // Set up the event dipatcher
|
n.initEventDispatcher() // Set up the event dipatcher
|
||||||
n.initChainManager() // Set up the chain manager
|
n.initChainManager() // Set up the chain manager
|
||||||
n.initConsensusNet() // Set up the main consensus network
|
n.initConsensusNet() // Set up the main consensus network
|
||||||
|
@ -524,10 +637,11 @@ func (n *Node) Initialize(Config *Config, logger logging.Logger, logFactory logg
|
||||||
|
|
||||||
n.initAdminAPI() // Start the Admin API
|
n.initAdminAPI() // Start the Admin API
|
||||||
n.initIPCAPI() // Start the IPC API
|
n.initIPCAPI() // Start the IPC API
|
||||||
n.initAliases() // Set up aliases
|
|
||||||
n.initChains() // Start the Platform chain
|
|
||||||
|
|
||||||
return nil
|
if err := n.initAliases(); err != nil { // Set up aliases
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return n.initChains() // Start the Platform chain
|
||||||
}
|
}
|
||||||
|
|
||||||
// Shutdown this node
|
// Shutdown this node
|
||||||
|
|
|
@ -2,8 +2,6 @@ borealis_bootstrap:
|
||||||
hosts:
|
hosts:
|
||||||
bootstrap1:
|
bootstrap1:
|
||||||
ansible_host: 3.227.207.132
|
ansible_host: 3.227.207.132
|
||||||
staking_tls_key_file: "/home/ubuntu/go/src/github.com/ava-labs/gecko/keys/keys1/staker.key"
|
|
||||||
staking_tls_cert_file: "/home/ubuntu/go/src/github.com/ava-labs/gecko/keys/keys1/staker.crt"
|
|
||||||
http_tls_enabled: true
|
http_tls_enabled: true
|
||||||
http_tls_key_file: "/home/ubuntu/ssl/privkey.pem"
|
http_tls_key_file: "/home/ubuntu/ssl/privkey.pem"
|
||||||
http_tls_cert_file: "/home/ubuntu/ssl/fullchain.pem"
|
http_tls_cert_file: "/home/ubuntu/ssl/fullchain.pem"
|
||||||
|
@ -11,7 +9,7 @@ borealis_bootstrap:
|
||||||
ansible_connection: ssh
|
ansible_connection: ssh
|
||||||
ansible_user: ubuntu
|
ansible_user: ubuntu
|
||||||
|
|
||||||
network_id: "borealis"
|
network_id: "cascade"
|
||||||
api_admin_enabled: true
|
api_admin_enabled: true
|
||||||
api_keystore_enabled: true
|
api_keystore_enabled: true
|
||||||
api_metrics_enabled: true
|
api_metrics_enabled: true
|
||||||
|
@ -28,6 +26,8 @@ borealis_bootstrap:
|
||||||
bootstrap_ids: ""
|
bootstrap_ids: ""
|
||||||
staking_port: 21001
|
staking_port: 21001
|
||||||
staking_tls_enabled: true
|
staking_tls_enabled: true
|
||||||
|
staking_tls_key_file: "/home/ubuntu/keys/staker.key"
|
||||||
|
staking_tls_cert_file: "/home/ubuntu/keys/staker.crt"
|
||||||
log_dir: "/home/ubuntu/.gecko"
|
log_dir: "/home/ubuntu/.gecko"
|
||||||
log_level: debug
|
log_level: debug
|
||||||
snow_sample_size: 3
|
snow_sample_size: 3
|
||||||
|
@ -44,25 +44,17 @@ borealis_node:
|
||||||
hosts:
|
hosts:
|
||||||
node1:
|
node1:
|
||||||
ansible_host: 34.207.133.167
|
ansible_host: 34.207.133.167
|
||||||
staking_tls_key_file: "/home/ubuntu/go/src/github.com/ava-labs/gecko/keys/keys2/staker.key"
|
|
||||||
staking_tls_cert_file: "/home/ubuntu/go/src/github.com/ava-labs/gecko/keys/keys2/staker.crt"
|
|
||||||
node2:
|
node2:
|
||||||
ansible_host: 107.23.241.199
|
ansible_host: 107.23.241.199
|
||||||
staking_tls_key_file: "/home/ubuntu/go/src/github.com/ava-labs/gecko/keys/keys3/staker.key"
|
|
||||||
staking_tls_cert_file: "/home/ubuntu/go/src/github.com/ava-labs/gecko/keys/keys3/staker.crt"
|
|
||||||
node3:
|
node3:
|
||||||
ansible_host: 54.197.215.186
|
ansible_host: 54.197.215.186
|
||||||
staking_tls_key_file: "/home/ubuntu/go/src/github.com/ava-labs/gecko/keys/keys4/staker.key"
|
|
||||||
staking_tls_cert_file: "/home/ubuntu/go/src/github.com/ava-labs/gecko/keys/keys4/staker.crt"
|
|
||||||
node4:
|
node4:
|
||||||
ansible_host: 18.234.153.22
|
ansible_host: 18.234.153.22
|
||||||
staking_tls_key_file: "/home/ubuntu/go/src/github.com/ava-labs/gecko/keys/keys5/staker.key"
|
|
||||||
staking_tls_cert_file: "/home/ubuntu/go/src/github.com/ava-labs/gecko/keys/keys5/staker.crt"
|
|
||||||
vars:
|
vars:
|
||||||
ansible_connection: ssh
|
ansible_connection: ssh
|
||||||
ansible_user: ubuntu
|
ansible_user: ubuntu
|
||||||
|
|
||||||
network_id: "borealis"
|
network_id: "cascade"
|
||||||
api_admin_enabled: true
|
api_admin_enabled: true
|
||||||
api_keystore_enabled: true
|
api_keystore_enabled: true
|
||||||
api_metrics_enabled: true
|
api_metrics_enabled: true
|
||||||
|
@ -76,9 +68,11 @@ borealis_node:
|
||||||
http_tls_key_file: ""
|
http_tls_key_file: ""
|
||||||
http_tls_cert_file: ""
|
http_tls_cert_file: ""
|
||||||
bootstrap_ips: "3.227.207.132:21001"
|
bootstrap_ips: "3.227.207.132:21001"
|
||||||
bootstrap_ids: "7Xhw2mDxuDS44j42TCB6U5579esbSt3Lg"
|
bootstrap_ids: "NX4zVkuiRJZYe6Nzzav7GXN3TakUet3Co"
|
||||||
staking_port: 21001
|
staking_port: 21001
|
||||||
staking_tls_enabled: true
|
staking_tls_enabled: true
|
||||||
|
staking_tls_key_file: "/home/ubuntu/keys/staker.key"
|
||||||
|
staking_tls_cert_file: "/home/ubuntu/keys/staker.crt"
|
||||||
log_dir: "/home/ubuntu/.gecko"
|
log_dir: "/home/ubuntu/.gecko"
|
||||||
log_level: debug
|
log_level: debug
|
||||||
snow_sample_size: 3
|
snow_sample_size: 3
|
||||||
|
|
|
@ -8,6 +8,7 @@
|
||||||
ava_binary: ~/go/src/github.com/ava-labs/gecko/build/ava
|
ava_binary: ~/go/src/github.com/ava-labs/gecko/build/ava
|
||||||
repo_folder: ~/go/src/github.com/ava-labs/gecko
|
repo_folder: ~/go/src/github.com/ava-labs/gecko
|
||||||
repo_name: ava-labs/gecko
|
repo_name: ava-labs/gecko
|
||||||
|
repo_branch: cascade
|
||||||
tasks:
|
tasks:
|
||||||
- name: Kill Node
|
- name: Kill Node
|
||||||
command: killall ava
|
command: killall ava
|
||||||
|
@ -15,6 +16,7 @@
|
||||||
- git:
|
- git:
|
||||||
repo: ssh://git@github.com/{{ repo_name }}.git
|
repo: ssh://git@github.com/{{ repo_name }}.git
|
||||||
dest: "{{ repo_folder }}"
|
dest: "{{ repo_folder }}"
|
||||||
|
version: "{{ repo_branch }}"
|
||||||
update: yes
|
update: yes
|
||||||
- name: Build project
|
- name: Build project
|
||||||
command: ./scripts/build.sh
|
command: ./scripts/build.sh
|
||||||
|
|
|
@ -8,6 +8,7 @@
|
||||||
ava_binary: ~/go/src/github.com/ava-labs/gecko/build/ava
|
ava_binary: ~/go/src/github.com/ava-labs/gecko/build/ava
|
||||||
repo_folder: ~/go/src/github.com/ava-labs/gecko
|
repo_folder: ~/go/src/github.com/ava-labs/gecko
|
||||||
repo_name: ava-labs/gecko
|
repo_name: ava-labs/gecko
|
||||||
|
repo_branch: cascade
|
||||||
tasks:
|
tasks:
|
||||||
- name: Kill Node
|
- name: Kill Node
|
||||||
command: killall ava
|
command: killall ava
|
||||||
|
@ -15,6 +16,7 @@
|
||||||
- git:
|
- git:
|
||||||
repo: ssh://git@github.com/{{ repo_name }}.git
|
repo: ssh://git@github.com/{{ repo_name }}.git
|
||||||
dest: "{{ repo_folder }}"
|
dest: "{{ repo_folder }}"
|
||||||
|
version: "{{ repo_branch }}"
|
||||||
update: yes
|
update: yes
|
||||||
- name: Build project
|
- name: Build project
|
||||||
command: ./scripts/build.sh
|
command: ./scripts/build.sh
|
||||||
|
|
|
@ -1,17 +1,16 @@
|
||||||
import sys
|
#!/usr/bin/env python3
|
||||||
|
"""
|
||||||
|
Start a number of AVA nodes on Amazon EC2
|
||||||
|
"""
|
||||||
|
|
||||||
import boto3
|
import boto3
|
||||||
|
|
||||||
ec2 = boto3.client("ec2")
|
|
||||||
|
|
||||||
# Should be called with python3 aws_create.py $numBootstraps $numNodes
|
|
||||||
numBootstraps = int(sys.argv[1])
|
|
||||||
numNodes = int(sys.argv[2])
|
|
||||||
|
|
||||||
bootstapNode = "Borealis-Bootstrap"
|
bootstapNode = "Borealis-Bootstrap"
|
||||||
fullNode = "Borealis-Node"
|
fullNode = "Borealis-Node"
|
||||||
|
|
||||||
|
|
||||||
def runInstances(num: int, name: str):
|
def runInstances(ec2, num: int, name: str):
|
||||||
if num > 0:
|
if num > 0:
|
||||||
ec2.run_instances(
|
ec2.run_instances(
|
||||||
ImageId="ami-0badd1c10cb7673e9",
|
ImageId="ami-0badd1c10cb7673e9",
|
||||||
|
@ -28,8 +27,18 @@ def runInstances(num: int, name: str):
|
||||||
|
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
runInstances(numBootstraps, bootstapNode)
|
import argparse
|
||||||
runInstances(numNodes, fullNode)
|
|
||||||
|
parser = argparse.ArgumentParser(
|
||||||
|
description=__doc__,
|
||||||
|
)
|
||||||
|
parser.add_argument('numBootstraps', type=int)
|
||||||
|
parser.add_argument('numNodes', type=int)
|
||||||
|
args = parser.parse_args()
|
||||||
|
|
||||||
|
ec2 = boto3.client("ec2")
|
||||||
|
runInstances(ec2, args.numBootstraps, bootstapNode)
|
||||||
|
runInstances(ec2, args.numNodes, fullNode)
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
|
|
|
@ -12,10 +12,11 @@ import (
|
||||||
func TestParametersValid(t *testing.T) {
|
func TestParametersValid(t *testing.T) {
|
||||||
p := Parameters{
|
p := Parameters{
|
||||||
Parameters: snowball.Parameters{
|
Parameters: snowball.Parameters{
|
||||||
K: 1,
|
K: 1,
|
||||||
Alpha: 1,
|
Alpha: 1,
|
||||||
BetaVirtuous: 1,
|
BetaVirtuous: 1,
|
||||||
BetaRogue: 1,
|
BetaRogue: 1,
|
||||||
|
ConcurrentRepolls: 1,
|
||||||
},
|
},
|
||||||
Parents: 2,
|
Parents: 2,
|
||||||
BatchSize: 1,
|
BatchSize: 1,
|
||||||
|
@ -29,10 +30,11 @@ func TestParametersValid(t *testing.T) {
|
||||||
func TestParametersInvalidParents(t *testing.T) {
|
func TestParametersInvalidParents(t *testing.T) {
|
||||||
p := Parameters{
|
p := Parameters{
|
||||||
Parameters: snowball.Parameters{
|
Parameters: snowball.Parameters{
|
||||||
K: 1,
|
K: 1,
|
||||||
Alpha: 1,
|
Alpha: 1,
|
||||||
BetaVirtuous: 1,
|
BetaVirtuous: 1,
|
||||||
BetaRogue: 1,
|
BetaRogue: 1,
|
||||||
|
ConcurrentRepolls: 1,
|
||||||
},
|
},
|
||||||
Parents: 1,
|
Parents: 1,
|
||||||
BatchSize: 1,
|
BatchSize: 1,
|
||||||
|
@ -46,10 +48,11 @@ func TestParametersInvalidParents(t *testing.T) {
|
||||||
func TestParametersInvalidBatchSize(t *testing.T) {
|
func TestParametersInvalidBatchSize(t *testing.T) {
|
||||||
p := Parameters{
|
p := Parameters{
|
||||||
Parameters: snowball.Parameters{
|
Parameters: snowball.Parameters{
|
||||||
K: 1,
|
K: 1,
|
||||||
Alpha: 1,
|
Alpha: 1,
|
||||||
BetaVirtuous: 1,
|
BetaVirtuous: 1,
|
||||||
BetaRogue: 1,
|
BetaRogue: 1,
|
||||||
|
ConcurrentRepolls: 1,
|
||||||
},
|
},
|
||||||
Parents: 2,
|
Parents: 2,
|
||||||
BatchSize: 0,
|
BatchSize: 0,
|
||||||
|
|
|
@ -27,11 +27,12 @@ func TestTopologicalTxIssued(t *testing.T) { TxIssuedTest(t, TopologicalFactory{
|
||||||
func TestAvalancheVoting(t *testing.T) {
|
func TestAvalancheVoting(t *testing.T) {
|
||||||
params := Parameters{
|
params := Parameters{
|
||||||
Parameters: snowball.Parameters{
|
Parameters: snowball.Parameters{
|
||||||
Metrics: prometheus.NewRegistry(),
|
Metrics: prometheus.NewRegistry(),
|
||||||
K: 2,
|
K: 2,
|
||||||
Alpha: 2,
|
Alpha: 2,
|
||||||
BetaVirtuous: 1,
|
BetaVirtuous: 1,
|
||||||
BetaRogue: 2,
|
BetaRogue: 2,
|
||||||
|
ConcurrentRepolls: 1,
|
||||||
},
|
},
|
||||||
Parents: 2,
|
Parents: 2,
|
||||||
BatchSize: 1,
|
BatchSize: 1,
|
||||||
|
@ -106,11 +107,12 @@ func TestAvalancheVoting(t *testing.T) {
|
||||||
func TestAvalancheTransitiveVoting(t *testing.T) {
|
func TestAvalancheTransitiveVoting(t *testing.T) {
|
||||||
params := Parameters{
|
params := Parameters{
|
||||||
Parameters: snowball.Parameters{
|
Parameters: snowball.Parameters{
|
||||||
Metrics: prometheus.NewRegistry(),
|
Metrics: prometheus.NewRegistry(),
|
||||||
K: 2,
|
K: 2,
|
||||||
Alpha: 2,
|
Alpha: 2,
|
||||||
BetaVirtuous: 1,
|
BetaVirtuous: 1,
|
||||||
BetaRogue: 2,
|
BetaRogue: 2,
|
||||||
|
ConcurrentRepolls: 1,
|
||||||
},
|
},
|
||||||
Parents: 2,
|
Parents: 2,
|
||||||
BatchSize: 1,
|
BatchSize: 1,
|
||||||
|
@ -199,11 +201,12 @@ func TestAvalancheTransitiveVoting(t *testing.T) {
|
||||||
func TestAvalancheSplitVoting(t *testing.T) {
|
func TestAvalancheSplitVoting(t *testing.T) {
|
||||||
params := Parameters{
|
params := Parameters{
|
||||||
Parameters: snowball.Parameters{
|
Parameters: snowball.Parameters{
|
||||||
Metrics: prometheus.NewRegistry(),
|
Metrics: prometheus.NewRegistry(),
|
||||||
K: 2,
|
K: 2,
|
||||||
Alpha: 2,
|
Alpha: 2,
|
||||||
BetaVirtuous: 1,
|
BetaVirtuous: 1,
|
||||||
BetaRogue: 2,
|
BetaRogue: 2,
|
||||||
|
ConcurrentRepolls: 1,
|
||||||
},
|
},
|
||||||
Parents: 2,
|
Parents: 2,
|
||||||
BatchSize: 1,
|
BatchSize: 1,
|
||||||
|
@ -262,11 +265,12 @@ func TestAvalancheSplitVoting(t *testing.T) {
|
||||||
func TestAvalancheTransitiveRejection(t *testing.T) {
|
func TestAvalancheTransitiveRejection(t *testing.T) {
|
||||||
params := Parameters{
|
params := Parameters{
|
||||||
Parameters: snowball.Parameters{
|
Parameters: snowball.Parameters{
|
||||||
Metrics: prometheus.NewRegistry(),
|
Metrics: prometheus.NewRegistry(),
|
||||||
K: 2,
|
K: 2,
|
||||||
Alpha: 2,
|
Alpha: 2,
|
||||||
BetaVirtuous: 1,
|
BetaVirtuous: 1,
|
||||||
BetaRogue: 2,
|
BetaRogue: 2,
|
||||||
|
ConcurrentRepolls: 1,
|
||||||
},
|
},
|
||||||
Parents: 2,
|
Parents: 2,
|
||||||
BatchSize: 1,
|
BatchSize: 1,
|
||||||
|
@ -363,11 +367,12 @@ func TestAvalancheTransitiveRejection(t *testing.T) {
|
||||||
func TestAvalancheVirtuous(t *testing.T) {
|
func TestAvalancheVirtuous(t *testing.T) {
|
||||||
params := Parameters{
|
params := Parameters{
|
||||||
Parameters: snowball.Parameters{
|
Parameters: snowball.Parameters{
|
||||||
Metrics: prometheus.NewRegistry(),
|
Metrics: prometheus.NewRegistry(),
|
||||||
K: 2,
|
K: 2,
|
||||||
Alpha: 2,
|
Alpha: 2,
|
||||||
BetaVirtuous: 1,
|
BetaVirtuous: 1,
|
||||||
BetaRogue: 2,
|
BetaRogue: 2,
|
||||||
|
ConcurrentRepolls: 1,
|
||||||
},
|
},
|
||||||
Parents: 2,
|
Parents: 2,
|
||||||
BatchSize: 1,
|
BatchSize: 1,
|
||||||
|
@ -484,11 +489,12 @@ func TestAvalancheVirtuous(t *testing.T) {
|
||||||
func TestAvalancheIsVirtuous(t *testing.T) {
|
func TestAvalancheIsVirtuous(t *testing.T) {
|
||||||
params := Parameters{
|
params := Parameters{
|
||||||
Parameters: snowball.Parameters{
|
Parameters: snowball.Parameters{
|
||||||
Metrics: prometheus.NewRegistry(),
|
Metrics: prometheus.NewRegistry(),
|
||||||
K: 2,
|
K: 2,
|
||||||
Alpha: 2,
|
Alpha: 2,
|
||||||
BetaVirtuous: 1,
|
BetaVirtuous: 1,
|
||||||
BetaRogue: 2,
|
BetaRogue: 2,
|
||||||
|
ConcurrentRepolls: 1,
|
||||||
},
|
},
|
||||||
Parents: 2,
|
Parents: 2,
|
||||||
BatchSize: 1,
|
BatchSize: 1,
|
||||||
|
@ -567,11 +573,12 @@ func TestAvalancheIsVirtuous(t *testing.T) {
|
||||||
func TestAvalancheQuiesce(t *testing.T) {
|
func TestAvalancheQuiesce(t *testing.T) {
|
||||||
params := Parameters{
|
params := Parameters{
|
||||||
Parameters: snowball.Parameters{
|
Parameters: snowball.Parameters{
|
||||||
Metrics: prometheus.NewRegistry(),
|
Metrics: prometheus.NewRegistry(),
|
||||||
K: 1,
|
K: 1,
|
||||||
Alpha: 1,
|
Alpha: 1,
|
||||||
BetaVirtuous: 1,
|
BetaVirtuous: 1,
|
||||||
BetaRogue: 1,
|
BetaRogue: 1,
|
||||||
|
ConcurrentRepolls: 1,
|
||||||
},
|
},
|
||||||
Parents: 2,
|
Parents: 2,
|
||||||
BatchSize: 1,
|
BatchSize: 1,
|
||||||
|
@ -660,11 +667,12 @@ func TestAvalancheQuiesce(t *testing.T) {
|
||||||
func TestAvalancheOrphans(t *testing.T) {
|
func TestAvalancheOrphans(t *testing.T) {
|
||||||
params := Parameters{
|
params := Parameters{
|
||||||
Parameters: snowball.Parameters{
|
Parameters: snowball.Parameters{
|
||||||
Metrics: prometheus.NewRegistry(),
|
Metrics: prometheus.NewRegistry(),
|
||||||
K: 1,
|
K: 1,
|
||||||
Alpha: 1,
|
Alpha: 1,
|
||||||
BetaVirtuous: math.MaxInt32,
|
BetaVirtuous: math.MaxInt32,
|
||||||
BetaRogue: math.MaxInt32,
|
BetaRogue: math.MaxInt32,
|
||||||
|
ConcurrentRepolls: 1,
|
||||||
},
|
},
|
||||||
Parents: 2,
|
Parents: 2,
|
||||||
BatchSize: 1,
|
BatchSize: 1,
|
||||||
|
|
|
@ -0,0 +1,27 @@
|
||||||
|
// (c) 2019-2020, Ava Labs, Inc. All rights reserved.
|
||||||
|
// See the file LICENSE for licensing terms.
|
||||||
|
|
||||||
|
package snowball
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
)
|
||||||
|
|
||||||
|
// binarySlush is the implementation of a binary slush instance
|
||||||
|
type binarySlush struct {
|
||||||
|
// preference is the choice that last had a successful poll. Unless there
|
||||||
|
// hasn't been a successful poll, in which case it is the initially provided
|
||||||
|
// choice.
|
||||||
|
preference int
|
||||||
|
}
|
||||||
|
|
||||||
|
// Initialize implements the BinarySlush interface
|
||||||
|
func (sl *binarySlush) Initialize(choice int) { sl.preference = choice }
|
||||||
|
|
||||||
|
// Preference implements the BinarySlush interface
|
||||||
|
func (sl *binarySlush) Preference() int { return sl.preference }
|
||||||
|
|
||||||
|
// RecordSuccessfulPoll implements the BinarySlush interface
|
||||||
|
func (sl *binarySlush) RecordSuccessfulPoll(choice int) { sl.preference = choice }
|
||||||
|
|
||||||
|
func (sl *binarySlush) String() string { return fmt.Sprintf("SL(Preference = %d)", sl.preference) }
|
|
@ -9,6 +9,9 @@ import (
|
||||||
|
|
||||||
// binarySnowball is the implementation of a binary snowball instance
|
// binarySnowball is the implementation of a binary snowball instance
|
||||||
type binarySnowball struct {
|
type binarySnowball struct {
|
||||||
|
// wrap the binary snowflake logic
|
||||||
|
binarySnowflake
|
||||||
|
|
||||||
// preference is the choice with the largest number of successful polls.
|
// preference is the choice with the largest number of successful polls.
|
||||||
// Ties are broken by switching choice lazily
|
// Ties are broken by switching choice lazily
|
||||||
preference int
|
preference int
|
||||||
|
@ -16,15 +19,12 @@ type binarySnowball struct {
|
||||||
// numSuccessfulPolls tracks the total number of successful network polls of
|
// numSuccessfulPolls tracks the total number of successful network polls of
|
||||||
// the 0 and 1 choices
|
// the 0 and 1 choices
|
||||||
numSuccessfulPolls [2]int
|
numSuccessfulPolls [2]int
|
||||||
|
|
||||||
// snowflake wraps the binary snowflake logic
|
|
||||||
snowflake binarySnowflake
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Initialize implements the BinarySnowball interface
|
// Initialize implements the BinarySnowball interface
|
||||||
func (sb *binarySnowball) Initialize(beta, choice int) {
|
func (sb *binarySnowball) Initialize(beta, choice int) {
|
||||||
|
sb.binarySnowflake.Initialize(beta, choice)
|
||||||
sb.preference = choice
|
sb.preference = choice
|
||||||
sb.snowflake.Initialize(beta, choice)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Preference implements the BinarySnowball interface
|
// Preference implements the BinarySnowball interface
|
||||||
|
@ -34,7 +34,7 @@ func (sb *binarySnowball) Preference() int {
|
||||||
// this case is handled for completion. Therefore, if snowflake is
|
// this case is handled for completion. Therefore, if snowflake is
|
||||||
// finalized, then our finalized snowflake choice should be preferred.
|
// finalized, then our finalized snowflake choice should be preferred.
|
||||||
if sb.Finalized() {
|
if sb.Finalized() {
|
||||||
return sb.snowflake.Preference()
|
return sb.binarySnowflake.Preference()
|
||||||
}
|
}
|
||||||
return sb.preference
|
return sb.preference
|
||||||
}
|
}
|
||||||
|
@ -45,20 +45,14 @@ func (sb *binarySnowball) RecordSuccessfulPoll(choice int) {
|
||||||
if sb.numSuccessfulPolls[choice] > sb.numSuccessfulPolls[1-choice] {
|
if sb.numSuccessfulPolls[choice] > sb.numSuccessfulPolls[1-choice] {
|
||||||
sb.preference = choice
|
sb.preference = choice
|
||||||
}
|
}
|
||||||
sb.snowflake.RecordSuccessfulPoll(choice)
|
sb.binarySnowflake.RecordSuccessfulPoll(choice)
|
||||||
}
|
}
|
||||||
|
|
||||||
// RecordUnsuccessfulPoll implements the BinarySnowball interface
|
|
||||||
func (sb *binarySnowball) RecordUnsuccessfulPoll() { sb.snowflake.RecordUnsuccessfulPoll() }
|
|
||||||
|
|
||||||
// Finalized implements the BinarySnowball interface
|
|
||||||
func (sb *binarySnowball) Finalized() bool { return sb.snowflake.Finalized() }
|
|
||||||
|
|
||||||
func (sb *binarySnowball) String() string {
|
func (sb *binarySnowball) String() string {
|
||||||
return fmt.Sprintf(
|
return fmt.Sprintf(
|
||||||
"SB(Preference = %d, NumSuccessfulPolls[0] = %d, NumSuccessfulPolls[1] = %d, SF = %s)",
|
"SB(Preference = %d, NumSuccessfulPolls[0] = %d, NumSuccessfulPolls[1] = %d, %s)",
|
||||||
sb.preference,
|
sb.preference,
|
||||||
sb.numSuccessfulPolls[0],
|
sb.numSuccessfulPolls[0],
|
||||||
sb.numSuccessfulPolls[1],
|
sb.numSuccessfulPolls[1],
|
||||||
&sb.snowflake)
|
&sb.binarySnowflake)
|
||||||
}
|
}
|
||||||
|
|
|
@ -96,15 +96,15 @@ func TestBinarySnowballRecordUnsuccessfulPoll(t *testing.T) {
|
||||||
t.Fatalf("Finalized too late")
|
t.Fatalf("Finalized too late")
|
||||||
}
|
}
|
||||||
|
|
||||||
expected := "SB(Preference = 1, NumSuccessfulPolls[0] = 0, NumSuccessfulPolls[1] = 3, SF = SF(Preference = 1, Confidence = 2, Finalized = true))"
|
expected := "SB(Preference = 1, NumSuccessfulPolls[0] = 0, NumSuccessfulPolls[1] = 3, SF(Confidence = 2, Finalized = true, SL(Preference = 1)))"
|
||||||
if str := sb.String(); str != expected {
|
if str := sb.String(); str != expected {
|
||||||
t.Fatalf("Wrong state. Expected:\n%s\nGot:\n%s", expected, str)
|
t.Fatalf("Wrong state. Expected:\n%s\nGot:\n%s", expected, str)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestBinarySnowballAcceptWeirdColor(t *testing.T) {
|
func TestBinarySnowballAcceptWeirdColor(t *testing.T) {
|
||||||
Red := 0
|
Blue := 0
|
||||||
Blue := 1
|
Red := 1
|
||||||
|
|
||||||
beta := 2
|
beta := 2
|
||||||
|
|
||||||
|
@ -151,7 +151,7 @@ func TestBinarySnowballAcceptWeirdColor(t *testing.T) {
|
||||||
t.Fatalf("Finalized too late")
|
t.Fatalf("Finalized too late")
|
||||||
}
|
}
|
||||||
|
|
||||||
expected := "SB(Preference = 0, NumSuccessfulPolls[0] = 2, NumSuccessfulPolls[1] = 2, SF = SF(Preference = 1, Confidence = 2, Finalized = true))"
|
expected := "SB(Preference = 1, NumSuccessfulPolls[0] = 2, NumSuccessfulPolls[1] = 2, SF(Confidence = 2, Finalized = true, SL(Preference = 0)))"
|
||||||
if str := sb.String(); str != expected {
|
if str := sb.String(); str != expected {
|
||||||
t.Fatalf("Wrong state. Expected:\n%s\nGot:\n%s", expected, str)
|
t.Fatalf("Wrong state. Expected:\n%s\nGot:\n%s", expected, str)
|
||||||
}
|
}
|
||||||
|
@ -190,7 +190,7 @@ func TestBinarySnowballLockColor(t *testing.T) {
|
||||||
t.Fatalf("Finalized too late")
|
t.Fatalf("Finalized too late")
|
||||||
}
|
}
|
||||||
|
|
||||||
expected := "SB(Preference = 1, NumSuccessfulPolls[0] = 1, NumSuccessfulPolls[1] = 2, SF = SF(Preference = 0, Confidence = 1, Finalized = true))"
|
expected := "SB(Preference = 1, NumSuccessfulPolls[0] = 1, NumSuccessfulPolls[1] = 2, SF(Confidence = 1, Finalized = true, SL(Preference = 0)))"
|
||||||
if str := sb.String(); str != expected {
|
if str := sb.String(); str != expected {
|
||||||
t.Fatalf("Wrong state. Expected:\n%s\nGot:\n%s", expected, str)
|
t.Fatalf("Wrong state. Expected:\n%s\nGot:\n%s", expected, str)
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,10 +9,8 @@ import (
|
||||||
|
|
||||||
// binarySnowflake is the implementation of a binary snowflake instance
|
// binarySnowflake is the implementation of a binary snowflake instance
|
||||||
type binarySnowflake struct {
|
type binarySnowflake struct {
|
||||||
// preference is the choice that last had a successful poll. Unless there
|
// wrap the binary slush logic
|
||||||
// hasn't been a successful poll, in which case it is the initially provided
|
binarySlush
|
||||||
// choice.
|
|
||||||
preference int
|
|
||||||
|
|
||||||
// confidence tracks the number of successful polls in a row that have
|
// confidence tracks the number of successful polls in a row that have
|
||||||
// returned the preference
|
// returned the preference
|
||||||
|
@ -29,29 +27,26 @@ type binarySnowflake struct {
|
||||||
|
|
||||||
// Initialize implements the BinarySnowflake interface
|
// Initialize implements the BinarySnowflake interface
|
||||||
func (sf *binarySnowflake) Initialize(beta, choice int) {
|
func (sf *binarySnowflake) Initialize(beta, choice int) {
|
||||||
|
sf.binarySlush.Initialize(choice)
|
||||||
sf.beta = beta
|
sf.beta = beta
|
||||||
sf.preference = choice
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Preference implements the BinarySnowflake interface
|
|
||||||
func (sf *binarySnowflake) Preference() int { return sf.preference }
|
|
||||||
|
|
||||||
// RecordSuccessfulPoll implements the BinarySnowflake interface
|
// RecordSuccessfulPoll implements the BinarySnowflake interface
|
||||||
func (sf *binarySnowflake) RecordSuccessfulPoll(choice int) {
|
func (sf *binarySnowflake) RecordSuccessfulPoll(choice int) {
|
||||||
if sf.Finalized() {
|
if sf.finalized {
|
||||||
return // This instace is already decided.
|
return // This instace is already decided.
|
||||||
}
|
}
|
||||||
|
|
||||||
if sf.preference == choice {
|
if preference := sf.Preference(); preference == choice {
|
||||||
sf.confidence++
|
sf.confidence++
|
||||||
} else {
|
} else {
|
||||||
// confidence is set to 1 because there has already been 1 successful
|
// confidence is set to 1 because there has already been 1 successful
|
||||||
// poll, namely this poll.
|
// poll, namely this poll.
|
||||||
sf.confidence = 1
|
sf.confidence = 1
|
||||||
sf.preference = choice
|
|
||||||
}
|
}
|
||||||
|
|
||||||
sf.finalized = sf.confidence >= sf.beta
|
sf.finalized = sf.confidence >= sf.beta
|
||||||
|
sf.binarySlush.RecordSuccessfulPoll(choice)
|
||||||
}
|
}
|
||||||
|
|
||||||
// RecordUnsuccessfulPoll implements the BinarySnowflake interface
|
// RecordUnsuccessfulPoll implements the BinarySnowflake interface
|
||||||
|
@ -61,8 +56,8 @@ func (sf *binarySnowflake) RecordUnsuccessfulPoll() { sf.confidence = 0 }
|
||||||
func (sf *binarySnowflake) Finalized() bool { return sf.finalized }
|
func (sf *binarySnowflake) Finalized() bool { return sf.finalized }
|
||||||
|
|
||||||
func (sf *binarySnowflake) String() string {
|
func (sf *binarySnowflake) String() string {
|
||||||
return fmt.Sprintf("SF(Preference = %d, Confidence = %d, Finalized = %v)",
|
return fmt.Sprintf("SF(Confidence = %d, Finalized = %v, %s)",
|
||||||
sf.Preference(),
|
|
||||||
sf.confidence,
|
sf.confidence,
|
||||||
sf.Finalized())
|
sf.finalized,
|
||||||
|
&sf.binarySlush)
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,56 @@
|
||||||
|
// (c) 2019-2020, Ava Labs, Inc. All rights reserved.
|
||||||
|
// See the file LICENSE for licensing terms.
|
||||||
|
|
||||||
|
package snowball
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestBinarySnowflake(t *testing.T) {
|
||||||
|
Blue := 0
|
||||||
|
Red := 1
|
||||||
|
|
||||||
|
beta := 2
|
||||||
|
|
||||||
|
sf := binarySnowflake{}
|
||||||
|
sf.Initialize(beta, Red)
|
||||||
|
|
||||||
|
if pref := sf.Preference(); pref != Red {
|
||||||
|
t.Fatalf("Wrong preference. Expected %d got %d", Red, pref)
|
||||||
|
} else if sf.Finalized() {
|
||||||
|
t.Fatalf("Finalized too early")
|
||||||
|
}
|
||||||
|
|
||||||
|
sf.RecordSuccessfulPoll(Blue)
|
||||||
|
|
||||||
|
if pref := sf.Preference(); pref != Blue {
|
||||||
|
t.Fatalf("Wrong preference. Expected %d got %d", Blue, pref)
|
||||||
|
} else if sf.Finalized() {
|
||||||
|
t.Fatalf("Finalized too early")
|
||||||
|
}
|
||||||
|
|
||||||
|
sf.RecordSuccessfulPoll(Red)
|
||||||
|
|
||||||
|
if pref := sf.Preference(); pref != Red {
|
||||||
|
t.Fatalf("Wrong preference. Expected %d got %d", Red, pref)
|
||||||
|
} else if sf.Finalized() {
|
||||||
|
t.Fatalf("Finalized too early")
|
||||||
|
}
|
||||||
|
|
||||||
|
sf.RecordSuccessfulPoll(Blue)
|
||||||
|
|
||||||
|
if pref := sf.Preference(); pref != Blue {
|
||||||
|
t.Fatalf("Wrong preference. Expected %d got %d", Blue, pref)
|
||||||
|
} else if sf.Finalized() {
|
||||||
|
t.Fatalf("Finalized too early")
|
||||||
|
}
|
||||||
|
|
||||||
|
sf.RecordSuccessfulPoll(Blue)
|
||||||
|
|
||||||
|
if pref := sf.Preference(); pref != Blue {
|
||||||
|
t.Fatalf("Wrong preference. Expected %d got %d", Blue, pref)
|
||||||
|
} else if !sf.Finalized() {
|
||||||
|
t.Fatalf("Didn't finalized correctly")
|
||||||
|
}
|
||||||
|
}
|
|
@ -24,6 +24,7 @@ type Byzantine struct {
|
||||||
|
|
||||||
// Initialize implements the Consensus interface
|
// Initialize implements the Consensus interface
|
||||||
func (b *Byzantine) Initialize(params Parameters, choice ids.ID) {
|
func (b *Byzantine) Initialize(params Parameters, choice ids.ID) {
|
||||||
|
b.params = params
|
||||||
b.preference = choice
|
b.preference = choice
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,54 @@
|
||||||
|
// (c) 2019-2020, Ava Labs, Inc. All rights reserved.
|
||||||
|
// See the file LICENSE for licensing terms.
|
||||||
|
|
||||||
|
package snowball
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/ava-labs/gecko/ids"
|
||||||
|
"github.com/prometheus/client_golang/prometheus"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestByzantine(t *testing.T) {
|
||||||
|
params := Parameters{
|
||||||
|
Metrics: prometheus.NewRegistry(),
|
||||||
|
K: 1, Alpha: 1, BetaVirtuous: 3, BetaRogue: 5,
|
||||||
|
}
|
||||||
|
|
||||||
|
byzFactory := ByzantineFactory{}
|
||||||
|
byz := byzFactory.New()
|
||||||
|
byz.Initialize(params, Blue)
|
||||||
|
|
||||||
|
if ret := byz.Parameters(); ret != params {
|
||||||
|
t.Fatalf("Should have returned the correct params")
|
||||||
|
}
|
||||||
|
|
||||||
|
byz.Add(Green)
|
||||||
|
|
||||||
|
if pref := byz.Preference(); !pref.Equals(Blue) {
|
||||||
|
t.Fatalf("Wrong preference, expected %s returned %s", Blue, pref)
|
||||||
|
}
|
||||||
|
|
||||||
|
oneGreen := ids.Bag{}
|
||||||
|
oneGreen.Add(Green)
|
||||||
|
byz.RecordPoll(oneGreen)
|
||||||
|
|
||||||
|
if pref := byz.Preference(); !pref.Equals(Blue) {
|
||||||
|
t.Fatalf("Wrong preference, expected %s returned %s", Blue, pref)
|
||||||
|
}
|
||||||
|
|
||||||
|
byz.RecordUnsuccessfulPoll()
|
||||||
|
|
||||||
|
if pref := byz.Preference(); !pref.Equals(Blue) {
|
||||||
|
t.Fatalf("Wrong preference, expected %s returned %s", Blue, pref)
|
||||||
|
}
|
||||||
|
|
||||||
|
if final := byz.Finalized(); !final {
|
||||||
|
t.Fatalf("Should be marked as accepted")
|
||||||
|
}
|
||||||
|
|
||||||
|
if str := byz.String(); str != Blue.String() {
|
||||||
|
t.Fatalf("Wrong string, expected %s returned %s", Blue, str)
|
||||||
|
}
|
||||||
|
}
|
|
@ -69,6 +69,23 @@ type NnarySnowflake interface {
|
||||||
Finalized() bool
|
Finalized() bool
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// NnarySlush is a slush instance deciding between an unbounded number of
|
||||||
|
// values. After performing a network sample of k nodes, if you have alpha
|
||||||
|
// votes for one of the choices, you should vote for that choice.
|
||||||
|
type NnarySlush interface {
|
||||||
|
fmt.Stringer
|
||||||
|
|
||||||
|
// Takes in the initial choice
|
||||||
|
Initialize(initialPreference ids.ID)
|
||||||
|
|
||||||
|
// Returns the currently preferred choice to be finalized
|
||||||
|
Preference() ids.ID
|
||||||
|
|
||||||
|
// RecordSuccessfulPoll records a successful poll towards finalizing the
|
||||||
|
// specified choice. Assumes the choice was previously added.
|
||||||
|
RecordSuccessfulPoll(choice ids.ID)
|
||||||
|
}
|
||||||
|
|
||||||
// BinarySnowball augments BinarySnowflake with a counter that tracks the total
|
// BinarySnowball augments BinarySnowflake with a counter that tracks the total
|
||||||
// number of positive responses from a network sample.
|
// number of positive responses from a network sample.
|
||||||
type BinarySnowball interface{ BinarySnowflake }
|
type BinarySnowball interface{ BinarySnowflake }
|
||||||
|
@ -97,6 +114,23 @@ type BinarySnowflake interface {
|
||||||
Finalized() bool
|
Finalized() bool
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// BinarySlush is a slush instance deciding between two values. After performing
|
||||||
|
// a network sample of k nodes, if you have alpha votes for one of the choices,
|
||||||
|
// you should vote for that choice.
|
||||||
|
type BinarySlush interface {
|
||||||
|
fmt.Stringer
|
||||||
|
|
||||||
|
// Takes in the initial choice
|
||||||
|
Initialize(initialPreference int)
|
||||||
|
|
||||||
|
// Returns the currently preferred choice to be finalized
|
||||||
|
Preference() int
|
||||||
|
|
||||||
|
// RecordSuccessfulPoll records a successful poll towards finalizing the
|
||||||
|
// specified choice
|
||||||
|
RecordSuccessfulPoll(choice int)
|
||||||
|
}
|
||||||
|
|
||||||
// UnarySnowball is a snowball instance deciding on one value. After performing
|
// UnarySnowball is a snowball instance deciding on one value. After performing
|
||||||
// a network sample of k nodes, if you have alpha votes for the choice, you
|
// a network sample of k nodes, if you have alpha votes for the choice, you
|
||||||
// should vote. Otherwise, you should reset.
|
// should vote. Otherwise, you should reset.
|
||||||
|
@ -122,3 +156,29 @@ type UnarySnowball interface {
|
||||||
// Returns a new unary snowball instance with the same state
|
// Returns a new unary snowball instance with the same state
|
||||||
Clone() UnarySnowball
|
Clone() UnarySnowball
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// UnarySnowflake is a snowflake instance deciding on one value. After
|
||||||
|
// performing a network sample of k nodes, if you have alpha votes for the
|
||||||
|
// choice, you should vote. Otherwise, you should reset.
|
||||||
|
type UnarySnowflake interface {
|
||||||
|
fmt.Stringer
|
||||||
|
|
||||||
|
// Takes in the beta value
|
||||||
|
Initialize(beta int)
|
||||||
|
|
||||||
|
// RecordSuccessfulPoll records a successful poll towards finalizing
|
||||||
|
RecordSuccessfulPoll()
|
||||||
|
|
||||||
|
// RecordUnsuccessfulPoll resets the snowflake counter of this instance
|
||||||
|
RecordUnsuccessfulPoll()
|
||||||
|
|
||||||
|
// Return whether a choice has been finalized
|
||||||
|
Finalized() bool
|
||||||
|
|
||||||
|
// Returns a new binary snowball instance with the agreement parameters
|
||||||
|
// transferred. Takes in the new beta value and the original choice
|
||||||
|
Extend(beta, originalPreference int) BinarySnowflake
|
||||||
|
|
||||||
|
// Returns a new unary snowflake instance with the same state
|
||||||
|
Clone() UnarySnowflake
|
||||||
|
}
|
||||||
|
|
|
@ -22,7 +22,7 @@ func ParamsTest(t *testing.T, factory Factory) {
|
||||||
|
|
||||||
params := Parameters{
|
params := Parameters{
|
||||||
Metrics: prometheus.NewRegistry(),
|
Metrics: prometheus.NewRegistry(),
|
||||||
K: 2, Alpha: 2, BetaVirtuous: 1, BetaRogue: 2,
|
K: 2, Alpha: 2, BetaVirtuous: 1, BetaRogue: 2, ConcurrentRepolls: 1,
|
||||||
}
|
}
|
||||||
sb.Initialize(params, Red)
|
sb.Initialize(params, Red)
|
||||||
|
|
||||||
|
@ -34,5 +34,7 @@ func ParamsTest(t *testing.T, factory Factory) {
|
||||||
t.Fatalf("Wrong Beta1 parameter")
|
t.Fatalf("Wrong Beta1 parameter")
|
||||||
} else if p.BetaRogue != params.BetaRogue {
|
} else if p.BetaRogue != params.BetaRogue {
|
||||||
t.Fatalf("Wrong Beta2 parameter")
|
t.Fatalf("Wrong Beta2 parameter")
|
||||||
|
} else if p.ConcurrentRepolls != params.ConcurrentRepolls {
|
||||||
|
t.Fatalf("Wrong Repoll parameter")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,40 +15,27 @@ func (FlatFactory) New() Consensus { return &Flat{} }
|
||||||
|
|
||||||
// Flat is a naive implementation of a multi-choice snowball instance
|
// Flat is a naive implementation of a multi-choice snowball instance
|
||||||
type Flat struct {
|
type Flat struct {
|
||||||
|
// wraps the n-nary snowball logic
|
||||||
|
nnarySnowball
|
||||||
|
|
||||||
// params contains all the configurations of a snowball instance
|
// params contains all the configurations of a snowball instance
|
||||||
params Parameters
|
params Parameters
|
||||||
|
|
||||||
// snowball wraps the n-nary snowball logic
|
|
||||||
snowball nnarySnowball
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Initialize implements the Consensus interface
|
// Initialize implements the Consensus interface
|
||||||
func (f *Flat) Initialize(params Parameters, choice ids.ID) {
|
func (f *Flat) Initialize(params Parameters, choice ids.ID) {
|
||||||
|
f.nnarySnowball.Initialize(params.BetaVirtuous, params.BetaRogue, choice)
|
||||||
f.params = params
|
f.params = params
|
||||||
f.snowball.Initialize(params.BetaVirtuous, params.BetaRogue, choice)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Parameters implements the Consensus interface
|
// Parameters implements the Consensus interface
|
||||||
func (f *Flat) Parameters() Parameters { return f.params }
|
func (f *Flat) Parameters() Parameters { return f.params }
|
||||||
|
|
||||||
// Add implements the Consensus interface
|
|
||||||
func (f *Flat) Add(choice ids.ID) { f.snowball.Add(choice) }
|
|
||||||
|
|
||||||
// Preference implements the Consensus interface
|
|
||||||
func (f *Flat) Preference() ids.ID { return f.snowball.Preference() }
|
|
||||||
|
|
||||||
// RecordPoll implements the Consensus interface
|
// RecordPoll implements the Consensus interface
|
||||||
func (f *Flat) RecordPoll(votes ids.Bag) {
|
func (f *Flat) RecordPoll(votes ids.Bag) {
|
||||||
if pollMode, numVotes := votes.Mode(); numVotes >= f.params.Alpha {
|
if pollMode, numVotes := votes.Mode(); numVotes >= f.params.Alpha {
|
||||||
f.snowball.RecordSuccessfulPoll(pollMode)
|
f.nnarySnowball.RecordSuccessfulPoll(pollMode)
|
||||||
} else {
|
} else {
|
||||||
f.RecordUnsuccessfulPoll()
|
f.RecordUnsuccessfulPoll()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// RecordUnsuccessfulPoll implements the Consensus interface
|
|
||||||
func (f *Flat) RecordUnsuccessfulPoll() { f.snowball.RecordUnsuccessfulPoll() }
|
|
||||||
|
|
||||||
// Finalized implements the Consensus interface
|
|
||||||
func (f *Flat) Finalized() bool { return f.snowball.Finalized() }
|
|
||||||
func (f *Flat) String() string { return f.snowball.String() }
|
|
||||||
|
|
|
@ -65,7 +65,7 @@ func TestFlat(t *testing.T) {
|
||||||
t.Fatalf("Finalized too late")
|
t.Fatalf("Finalized too late")
|
||||||
}
|
}
|
||||||
|
|
||||||
expected := "SB(Preference = TtF4d2QWbk5vzQGTEPrN48x6vwgAoAmKQ9cbp79inpQmcRKES, NumSuccessfulPolls = 3, SF = SF(Preference = TtF4d2QWbk5vzQGTEPrN48x6vwgAoAmKQ9cbp79inpQmcRKES, Confidence = 2, Finalized = true))"
|
expected := "SB(Preference = TtF4d2QWbk5vzQGTEPrN48x6vwgAoAmKQ9cbp79inpQmcRKES, NumSuccessfulPolls = 3, SF(Confidence = 2, Finalized = true, SL(Preference = TtF4d2QWbk5vzQGTEPrN48x6vwgAoAmKQ9cbp79inpQmcRKES)))"
|
||||||
if str := f.String(); str != expected {
|
if str := f.String(); str != expected {
|
||||||
t.Fatalf("Wrong state. Expected:\n%s\nGot:\n%s", expected, str)
|
t.Fatalf("Wrong state. Expected:\n%s\nGot:\n%s", expected, str)
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,30 @@
|
||||||
|
// (c) 2019-2020, Ava Labs, Inc. All rights reserved.
|
||||||
|
// See the file LICENSE for licensing terms.
|
||||||
|
|
||||||
|
package snowball
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
"github.com/ava-labs/gecko/ids"
|
||||||
|
)
|
||||||
|
|
||||||
|
// nnarySlush is the implementation of a slush instance with an unbounded number
|
||||||
|
// of choices
|
||||||
|
type nnarySlush struct {
|
||||||
|
// preference is the choice that last had a successful poll. Unless there
|
||||||
|
// hasn't been a successful poll, in which case it is the initially provided
|
||||||
|
// choice.
|
||||||
|
preference ids.ID
|
||||||
|
}
|
||||||
|
|
||||||
|
// Initialize implements the NnarySlush interface
|
||||||
|
func (sl *nnarySlush) Initialize(choice ids.ID) { sl.preference = choice }
|
||||||
|
|
||||||
|
// Preference implements the NnarySlush interface
|
||||||
|
func (sl *nnarySlush) Preference() ids.ID { return sl.preference }
|
||||||
|
|
||||||
|
// RecordSuccessfulPoll implements the NnarySlush interface
|
||||||
|
func (sl *nnarySlush) RecordSuccessfulPoll(choice ids.ID) { sl.preference = choice }
|
||||||
|
|
||||||
|
func (sl *nnarySlush) String() string { return fmt.Sprintf("SL(Preference = %s)", sl.preference) }
|
|
@ -11,6 +11,9 @@ import (
|
||||||
|
|
||||||
// nnarySnowball is a naive implementation of a multi-color snowball instance
|
// nnarySnowball is a naive implementation of a multi-color snowball instance
|
||||||
type nnarySnowball struct {
|
type nnarySnowball struct {
|
||||||
|
// wrap the n-nary snowflake logic
|
||||||
|
nnarySnowflake
|
||||||
|
|
||||||
// preference is the choice with the largest number of successful polls.
|
// preference is the choice with the largest number of successful polls.
|
||||||
// Ties are broken by switching choice lazily
|
// Ties are broken by switching choice lazily
|
||||||
preference ids.ID
|
preference ids.ID
|
||||||
|
@ -22,21 +25,15 @@ type nnarySnowball struct {
|
||||||
// numSuccessfulPolls tracks the total number of successful network polls of
|
// numSuccessfulPolls tracks the total number of successful network polls of
|
||||||
// the choices
|
// the choices
|
||||||
numSuccessfulPolls map[[32]byte]int
|
numSuccessfulPolls map[[32]byte]int
|
||||||
|
|
||||||
// snowflake wraps the n-nary snowflake logic
|
|
||||||
snowflake nnarySnowflake
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Initialize implements the NnarySnowball interface
|
// Initialize implements the NnarySnowball interface
|
||||||
func (sb *nnarySnowball) Initialize(betaVirtuous, betaRogue int, choice ids.ID) {
|
func (sb *nnarySnowball) Initialize(betaVirtuous, betaRogue int, choice ids.ID) {
|
||||||
|
sb.nnarySnowflake.Initialize(betaVirtuous, betaRogue, choice)
|
||||||
sb.preference = choice
|
sb.preference = choice
|
||||||
sb.numSuccessfulPolls = make(map[[32]byte]int)
|
sb.numSuccessfulPolls = make(map[[32]byte]int)
|
||||||
sb.snowflake.Initialize(betaVirtuous, betaRogue, choice)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add implements the NnarySnowball interface
|
|
||||||
func (sb *nnarySnowball) Add(choice ids.ID) { sb.snowflake.Add(choice) }
|
|
||||||
|
|
||||||
// Preference implements the NnarySnowball interface
|
// Preference implements the NnarySnowball interface
|
||||||
func (sb *nnarySnowball) Preference() ids.ID {
|
func (sb *nnarySnowball) Preference() ids.ID {
|
||||||
// It is possible, with low probability, that the snowflake preference is
|
// It is possible, with low probability, that the snowflake preference is
|
||||||
|
@ -44,17 +41,13 @@ func (sb *nnarySnowball) Preference() ids.ID {
|
||||||
// this case is handled for completion. Therefore, if snowflake is
|
// this case is handled for completion. Therefore, if snowflake is
|
||||||
// finalized, then our finalized snowflake choice should be preferred.
|
// finalized, then our finalized snowflake choice should be preferred.
|
||||||
if sb.Finalized() {
|
if sb.Finalized() {
|
||||||
return sb.snowflake.Preference()
|
return sb.nnarySnowflake.Preference()
|
||||||
}
|
}
|
||||||
return sb.preference
|
return sb.preference
|
||||||
}
|
}
|
||||||
|
|
||||||
// RecordSuccessfulPoll implements the NnarySnowball interface
|
// RecordSuccessfulPoll implements the NnarySnowball interface
|
||||||
func (sb *nnarySnowball) RecordSuccessfulPoll(choice ids.ID) {
|
func (sb *nnarySnowball) RecordSuccessfulPoll(choice ids.ID) {
|
||||||
if sb.Finalized() {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
key := choice.Key()
|
key := choice.Key()
|
||||||
numSuccessfulPolls := sb.numSuccessfulPolls[key] + 1
|
numSuccessfulPolls := sb.numSuccessfulPolls[key] + 1
|
||||||
sb.numSuccessfulPolls[key] = numSuccessfulPolls
|
sb.numSuccessfulPolls[key] = numSuccessfulPolls
|
||||||
|
@ -64,16 +57,10 @@ func (sb *nnarySnowball) RecordSuccessfulPoll(choice ids.ID) {
|
||||||
sb.maxSuccessfulPolls = numSuccessfulPolls
|
sb.maxSuccessfulPolls = numSuccessfulPolls
|
||||||
}
|
}
|
||||||
|
|
||||||
sb.snowflake.RecordSuccessfulPoll(choice)
|
sb.nnarySnowflake.RecordSuccessfulPoll(choice)
|
||||||
}
|
}
|
||||||
|
|
||||||
// RecordUnsuccessfulPoll implements the NnarySnowball interface
|
|
||||||
func (sb *nnarySnowball) RecordUnsuccessfulPoll() { sb.snowflake.RecordUnsuccessfulPoll() }
|
|
||||||
|
|
||||||
// Finalized implements the NnarySnowball interface
|
|
||||||
func (sb *nnarySnowball) Finalized() bool { return sb.snowflake.Finalized() }
|
|
||||||
|
|
||||||
func (sb *nnarySnowball) String() string {
|
func (sb *nnarySnowball) String() string {
|
||||||
return fmt.Sprintf("SB(Preference = %s, NumSuccessfulPolls = %d, SF = %s)",
|
return fmt.Sprintf("SB(Preference = %s, NumSuccessfulPolls = %d, %s)",
|
||||||
sb.preference, sb.maxSuccessfulPolls, &sb.snowflake)
|
sb.preference, sb.maxSuccessfulPolls, &sb.nnarySnowflake)
|
||||||
}
|
}
|
||||||
|
|
|
@ -55,50 +55,24 @@ func TestNnarySnowball(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestNnarySnowflake(t *testing.T) {
|
func TestVirtuousNnarySnowball(t *testing.T) {
|
||||||
betaVirtuous := 2
|
betaVirtuous := 1
|
||||||
betaRogue := 2
|
betaRogue := 2
|
||||||
|
|
||||||
sf := nnarySnowflake{}
|
sb := nnarySnowball{}
|
||||||
sf.Initialize(betaVirtuous, betaRogue, Red)
|
sb.Initialize(betaVirtuous, betaRogue, Red)
|
||||||
sf.Add(Blue)
|
|
||||||
sf.Add(Green)
|
|
||||||
|
|
||||||
if pref := sf.Preference(); !Red.Equals(pref) {
|
if pref := sb.Preference(); !Red.Equals(pref) {
|
||||||
t.Fatalf("Wrong preference. Expected %s got %s", Red, pref)
|
t.Fatalf("Wrong preference. Expected %s got %s", Red, pref)
|
||||||
} else if sf.Finalized() {
|
} else if sb.Finalized() {
|
||||||
t.Fatalf("Finalized too early")
|
t.Fatalf("Finalized too early")
|
||||||
}
|
}
|
||||||
|
|
||||||
sf.RecordSuccessfulPoll(Blue)
|
sb.RecordSuccessfulPoll(Red)
|
||||||
|
|
||||||
if pref := sf.Preference(); !Blue.Equals(pref) {
|
if pref := sb.Preference(); !Red.Equals(pref) {
|
||||||
t.Fatalf("Wrong preference. Expected %s got %s", Blue, pref)
|
|
||||||
} else if sf.Finalized() {
|
|
||||||
t.Fatalf("Finalized too early")
|
|
||||||
}
|
|
||||||
|
|
||||||
sf.RecordSuccessfulPoll(Red)
|
|
||||||
|
|
||||||
if pref := sf.Preference(); !Red.Equals(pref) {
|
|
||||||
t.Fatalf("Wrong preference. Expected %s got %s", Red, pref)
|
t.Fatalf("Wrong preference. Expected %s got %s", Red, pref)
|
||||||
} else if sf.Finalized() {
|
} else if !sb.Finalized() {
|
||||||
t.Fatalf("Finalized too early")
|
|
||||||
}
|
|
||||||
|
|
||||||
sf.RecordSuccessfulPoll(Red)
|
|
||||||
|
|
||||||
if pref := sf.Preference(); !Red.Equals(pref) {
|
|
||||||
t.Fatalf("Wrong preference. Expected %s got %s", Red, pref)
|
|
||||||
} else if !sf.Finalized() {
|
|
||||||
t.Fatalf("Should be finalized")
|
|
||||||
}
|
|
||||||
|
|
||||||
sf.RecordSuccessfulPoll(Blue)
|
|
||||||
|
|
||||||
if pref := sf.Preference(); !Red.Equals(pref) {
|
|
||||||
t.Fatalf("Wrong preference. Expected %s got %s", Red, pref)
|
|
||||||
} else if !sf.Finalized() {
|
|
||||||
t.Fatalf("Should be finalized")
|
t.Fatalf("Should be finalized")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -143,7 +117,7 @@ func TestNarySnowballRecordUnsuccessfulPoll(t *testing.T) {
|
||||||
t.Fatalf("Finalized too late")
|
t.Fatalf("Finalized too late")
|
||||||
}
|
}
|
||||||
|
|
||||||
expected := "SB(Preference = TtF4d2QWbk5vzQGTEPrN48x6vwgAoAmKQ9cbp79inpQmcRKES, NumSuccessfulPolls = 3, SF = SF(Preference = TtF4d2QWbk5vzQGTEPrN48x6vwgAoAmKQ9cbp79inpQmcRKES, Confidence = 2, Finalized = true))"
|
expected := "SB(Preference = TtF4d2QWbk5vzQGTEPrN48x6vwgAoAmKQ9cbp79inpQmcRKES, NumSuccessfulPolls = 3, SF(Confidence = 2, Finalized = true, SL(Preference = TtF4d2QWbk5vzQGTEPrN48x6vwgAoAmKQ9cbp79inpQmcRKES)))"
|
||||||
if str := sb.String(); str != expected {
|
if str := sb.String(); str != expected {
|
||||||
t.Fatalf("Wrong state. Expected:\n%s\nGot:\n%s", expected, str)
|
t.Fatalf("Wrong state. Expected:\n%s\nGot:\n%s", expected, str)
|
||||||
}
|
}
|
||||||
|
@ -159,7 +133,7 @@ func TestNarySnowballRecordUnsuccessfulPoll(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestNarySnowflakeColor(t *testing.T) {
|
func TestNarySnowballDifferentSnowflakeColor(t *testing.T) {
|
||||||
betaVirtuous := 2
|
betaVirtuous := 2
|
||||||
betaRogue := 2
|
betaRogue := 2
|
||||||
|
|
||||||
|
@ -175,7 +149,7 @@ func TestNarySnowflakeColor(t *testing.T) {
|
||||||
|
|
||||||
sb.RecordSuccessfulPoll(Blue)
|
sb.RecordSuccessfulPoll(Blue)
|
||||||
|
|
||||||
if pref := sb.snowflake.Preference(); !Blue.Equals(pref) {
|
if pref := sb.nnarySnowflake.Preference(); !Blue.Equals(pref) {
|
||||||
t.Fatalf("Wrong preference. Expected %s got %s", Blue, pref)
|
t.Fatalf("Wrong preference. Expected %s got %s", Blue, pref)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -183,7 +157,7 @@ func TestNarySnowflakeColor(t *testing.T) {
|
||||||
|
|
||||||
if pref := sb.Preference(); !Blue.Equals(pref) {
|
if pref := sb.Preference(); !Blue.Equals(pref) {
|
||||||
t.Fatalf("Wrong preference. Expected %s got %s", Blue, pref)
|
t.Fatalf("Wrong preference. Expected %s got %s", Blue, pref)
|
||||||
} else if pref := sb.snowflake.Preference(); !Red.Equals(pref) {
|
} else if pref := sb.nnarySnowflake.Preference(); !Red.Equals(pref) {
|
||||||
t.Fatalf("Wrong preference. Expected %s got %s", Blue, pref)
|
t.Fatalf("Wrong preference. Expected %s got %s", Blue, pref)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,6 +12,9 @@ import (
|
||||||
// nnarySnowflake is the implementation of a snowflake instance with an
|
// nnarySnowflake is the implementation of a snowflake instance with an
|
||||||
// unbounded number of choices
|
// unbounded number of choices
|
||||||
type nnarySnowflake struct {
|
type nnarySnowflake struct {
|
||||||
|
// wrap the n-nary slush logic
|
||||||
|
nnarySlush
|
||||||
|
|
||||||
// betaVirtuous is the number of consecutive successful queries required for
|
// betaVirtuous is the number of consecutive successful queries required for
|
||||||
// finalization on a virtuous instance.
|
// finalization on a virtuous instance.
|
||||||
betaVirtuous int
|
betaVirtuous int
|
||||||
|
@ -24,11 +27,6 @@ type nnarySnowflake struct {
|
||||||
// returned the preference
|
// returned the preference
|
||||||
confidence int
|
confidence int
|
||||||
|
|
||||||
// preference is the choice that last had a successful poll. Unless there
|
|
||||||
// hasn't been a successful poll, in which case it is the initially provided
|
|
||||||
// choice.
|
|
||||||
preference ids.ID
|
|
||||||
|
|
||||||
// rogue tracks if this instance has multiple choices or only one
|
// rogue tracks if this instance has multiple choices or only one
|
||||||
rogue bool
|
rogue bool
|
||||||
|
|
||||||
|
@ -39,32 +37,31 @@ type nnarySnowflake struct {
|
||||||
|
|
||||||
// Initialize implements the NnarySnowflake interface
|
// Initialize implements the NnarySnowflake interface
|
||||||
func (sf *nnarySnowflake) Initialize(betaVirtuous, betaRogue int, choice ids.ID) {
|
func (sf *nnarySnowflake) Initialize(betaVirtuous, betaRogue int, choice ids.ID) {
|
||||||
|
sf.nnarySlush.Initialize(choice)
|
||||||
sf.betaVirtuous = betaVirtuous
|
sf.betaVirtuous = betaVirtuous
|
||||||
sf.betaRogue = betaRogue
|
sf.betaRogue = betaRogue
|
||||||
sf.preference = choice
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add implements the NnarySnowflake interface
|
// Add implements the NnarySnowflake interface
|
||||||
func (sf *nnarySnowflake) Add(choice ids.ID) { sf.rogue = sf.rogue || !choice.Equals(sf.preference) }
|
func (sf *nnarySnowflake) Add(choice ids.ID) { sf.rogue = sf.rogue || !choice.Equals(sf.preference) }
|
||||||
|
|
||||||
// Preference implements the NnarySnowflake interface
|
|
||||||
func (sf *nnarySnowflake) Preference() ids.ID { return sf.preference }
|
|
||||||
|
|
||||||
// RecordSuccessfulPoll implements the NnarySnowflake interface
|
// RecordSuccessfulPoll implements the NnarySnowflake interface
|
||||||
func (sf *nnarySnowflake) RecordSuccessfulPoll(choice ids.ID) {
|
func (sf *nnarySnowflake) RecordSuccessfulPoll(choice ids.ID) {
|
||||||
if sf.Finalized() {
|
if sf.finalized {
|
||||||
return
|
return // This instace is already decided.
|
||||||
}
|
}
|
||||||
|
|
||||||
if sf.preference.Equals(choice) {
|
if preference := sf.nnarySlush.Preference(); preference.Equals(choice) {
|
||||||
sf.confidence++
|
sf.confidence++
|
||||||
} else {
|
} else {
|
||||||
|
// confidence is set to 1 because there has already been 1 successful
|
||||||
|
// poll, namely this poll.
|
||||||
sf.confidence = 1
|
sf.confidence = 1
|
||||||
sf.preference = choice
|
|
||||||
}
|
}
|
||||||
|
|
||||||
sf.finalized = (!sf.rogue && sf.confidence >= sf.betaVirtuous) ||
|
sf.finalized = (!sf.rogue && sf.confidence >= sf.betaVirtuous) ||
|
||||||
sf.confidence >= sf.betaRogue
|
sf.confidence >= sf.betaRogue
|
||||||
|
sf.nnarySlush.RecordSuccessfulPoll(choice)
|
||||||
}
|
}
|
||||||
|
|
||||||
// RecordUnsuccessfulPoll implements the NnarySnowflake interface
|
// RecordUnsuccessfulPoll implements the NnarySnowflake interface
|
||||||
|
@ -74,8 +71,8 @@ func (sf *nnarySnowflake) RecordUnsuccessfulPoll() { sf.confidence = 0 }
|
||||||
func (sf *nnarySnowflake) Finalized() bool { return sf.finalized }
|
func (sf *nnarySnowflake) Finalized() bool { return sf.finalized }
|
||||||
|
|
||||||
func (sf *nnarySnowflake) String() string {
|
func (sf *nnarySnowflake) String() string {
|
||||||
return fmt.Sprintf("SF(Preference = %s, Confidence = %d, Finalized = %v)",
|
return fmt.Sprintf("SF(Confidence = %d, Finalized = %v, %s)",
|
||||||
sf.preference,
|
|
||||||
sf.confidence,
|
sf.confidence,
|
||||||
sf.Finalized())
|
sf.finalized,
|
||||||
|
&sf.nnarySlush)
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,134 @@
|
||||||
|
// (c) 2019-2020, Ava Labs, Inc. All rights reserved.
|
||||||
|
// See the file LICENSE for licensing terms.
|
||||||
|
|
||||||
|
package snowball
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestNnarySnowflake(t *testing.T) {
|
||||||
|
betaVirtuous := 2
|
||||||
|
betaRogue := 2
|
||||||
|
|
||||||
|
sf := nnarySnowflake{}
|
||||||
|
sf.Initialize(betaVirtuous, betaRogue, Red)
|
||||||
|
sf.Add(Blue)
|
||||||
|
sf.Add(Green)
|
||||||
|
|
||||||
|
if pref := sf.Preference(); !Red.Equals(pref) {
|
||||||
|
t.Fatalf("Wrong preference. Expected %s got %s", Red, pref)
|
||||||
|
} else if sf.Finalized() {
|
||||||
|
t.Fatalf("Finalized too early")
|
||||||
|
}
|
||||||
|
|
||||||
|
sf.RecordSuccessfulPoll(Blue)
|
||||||
|
|
||||||
|
if pref := sf.Preference(); !Blue.Equals(pref) {
|
||||||
|
t.Fatalf("Wrong preference. Expected %s got %s", Blue, pref)
|
||||||
|
} else if sf.Finalized() {
|
||||||
|
t.Fatalf("Finalized too early")
|
||||||
|
}
|
||||||
|
|
||||||
|
sf.RecordSuccessfulPoll(Red)
|
||||||
|
|
||||||
|
if pref := sf.Preference(); !Red.Equals(pref) {
|
||||||
|
t.Fatalf("Wrong preference. Expected %s got %s", Red, pref)
|
||||||
|
} else if sf.Finalized() {
|
||||||
|
t.Fatalf("Finalized too early")
|
||||||
|
}
|
||||||
|
|
||||||
|
sf.RecordSuccessfulPoll(Red)
|
||||||
|
|
||||||
|
if pref := sf.Preference(); !Red.Equals(pref) {
|
||||||
|
t.Fatalf("Wrong preference. Expected %s got %s", Red, pref)
|
||||||
|
} else if !sf.Finalized() {
|
||||||
|
t.Fatalf("Should be finalized")
|
||||||
|
}
|
||||||
|
|
||||||
|
sf.RecordSuccessfulPoll(Blue)
|
||||||
|
|
||||||
|
if pref := sf.Preference(); !Red.Equals(pref) {
|
||||||
|
t.Fatalf("Wrong preference. Expected %s got %s", Red, pref)
|
||||||
|
} else if !sf.Finalized() {
|
||||||
|
t.Fatalf("Should be finalized")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestVirtuousNnarySnowflake(t *testing.T) {
|
||||||
|
betaVirtuous := 2
|
||||||
|
betaRogue := 3
|
||||||
|
|
||||||
|
sb := nnarySnowflake{}
|
||||||
|
sb.Initialize(betaVirtuous, betaRogue, Red)
|
||||||
|
|
||||||
|
if pref := sb.Preference(); !Red.Equals(pref) {
|
||||||
|
t.Fatalf("Wrong preference. Expected %s got %s", Red, pref)
|
||||||
|
} else if sb.Finalized() {
|
||||||
|
t.Fatalf("Finalized too early")
|
||||||
|
}
|
||||||
|
|
||||||
|
sb.RecordSuccessfulPoll(Red)
|
||||||
|
|
||||||
|
if pref := sb.Preference(); !Red.Equals(pref) {
|
||||||
|
t.Fatalf("Wrong preference. Expected %s got %s", Red, pref)
|
||||||
|
} else if sb.Finalized() {
|
||||||
|
t.Fatalf("Finalized too early")
|
||||||
|
}
|
||||||
|
|
||||||
|
sb.RecordSuccessfulPoll(Red)
|
||||||
|
|
||||||
|
if pref := sb.Preference(); !Red.Equals(pref) {
|
||||||
|
t.Fatalf("Wrong preference. Expected %s got %s", Red, pref)
|
||||||
|
} else if !sb.Finalized() {
|
||||||
|
t.Fatalf("Should be finalized")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestRogueNnarySnowflake(t *testing.T) {
|
||||||
|
betaVirtuous := 1
|
||||||
|
betaRogue := 2
|
||||||
|
|
||||||
|
sb := nnarySnowflake{}
|
||||||
|
sb.Initialize(betaVirtuous, betaRogue, Red)
|
||||||
|
if sb.rogue {
|
||||||
|
t.Fatalf("Shouldn't be rogue")
|
||||||
|
}
|
||||||
|
|
||||||
|
sb.Add(Red)
|
||||||
|
if sb.rogue {
|
||||||
|
t.Fatalf("Shouldn't be rogue")
|
||||||
|
}
|
||||||
|
|
||||||
|
sb.Add(Blue)
|
||||||
|
if !sb.rogue {
|
||||||
|
t.Fatalf("Should be rogue")
|
||||||
|
}
|
||||||
|
|
||||||
|
sb.Add(Red)
|
||||||
|
if !sb.rogue {
|
||||||
|
t.Fatalf("Should be rogue")
|
||||||
|
}
|
||||||
|
|
||||||
|
if pref := sb.Preference(); !Red.Equals(pref) {
|
||||||
|
t.Fatalf("Wrong preference. Expected %s got %s", Red, pref)
|
||||||
|
} else if sb.Finalized() {
|
||||||
|
t.Fatalf("Finalized too early")
|
||||||
|
}
|
||||||
|
|
||||||
|
sb.RecordSuccessfulPoll(Red)
|
||||||
|
|
||||||
|
if pref := sb.Preference(); !Red.Equals(pref) {
|
||||||
|
t.Fatalf("Wrong preference. Expected %s got %s", Red, pref)
|
||||||
|
} else if sb.Finalized() {
|
||||||
|
t.Fatalf("Finalized too early")
|
||||||
|
}
|
||||||
|
|
||||||
|
sb.RecordSuccessfulPoll(Red)
|
||||||
|
|
||||||
|
if pref := sb.Preference(); !Red.Equals(pref) {
|
||||||
|
t.Fatalf("Wrong preference. Expected %s got %s", Red, pref)
|
||||||
|
} else if !sb.Finalized() {
|
||||||
|
t.Fatalf("Should be finalized")
|
||||||
|
}
|
||||||
|
}
|
|
@ -9,11 +9,28 @@ import (
|
||||||
"github.com/prometheus/client_golang/prometheus"
|
"github.com/prometheus/client_golang/prometheus"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
errMsg = "__________ .___\n" +
|
||||||
|
"\\______ \\____________ __| _/__.__.\n" +
|
||||||
|
" | | _/\\_ __ \\__ \\ / __ < | |\n" +
|
||||||
|
" | | \\ | | \\// __ \\_/ /_/ |\\___ |\n" +
|
||||||
|
" |______ / |__| (____ /\\____ |/ ____|\n" +
|
||||||
|
" \\/ \\/ \\/\\/\n" +
|
||||||
|
"\n" +
|
||||||
|
"🏆 🏆 🏆 🏆 🏆 🏆\n" +
|
||||||
|
" ________ ________ ________________\n" +
|
||||||
|
" / _____/ \\_____ \\ / _ \\__ ___/\n" +
|
||||||
|
"/ \\ ___ / | \\ / /_\\ \\| |\n" +
|
||||||
|
"\\ \\_\\ \\/ | \\/ | \\ |\n" +
|
||||||
|
" \\______ /\\_______ /\\____|__ /____|\n" +
|
||||||
|
" \\/ \\/ \\/\n"
|
||||||
|
)
|
||||||
|
|
||||||
// Parameters required for snowball consensus
|
// Parameters required for snowball consensus
|
||||||
type Parameters struct {
|
type Parameters struct {
|
||||||
Namespace string
|
Namespace string
|
||||||
Metrics prometheus.Registerer
|
Metrics prometheus.Registerer
|
||||||
K, Alpha, BetaVirtuous, BetaRogue int
|
K, Alpha, BetaVirtuous, BetaRogue, ConcurrentRepolls int
|
||||||
}
|
}
|
||||||
|
|
||||||
// Valid returns nil if the parameters describe a valid initialization.
|
// Valid returns nil if the parameters describe a valid initialization.
|
||||||
|
@ -25,8 +42,14 @@ func (p Parameters) Valid() error {
|
||||||
return fmt.Errorf("K = %d, Alpha = %d: Fails the condition that: Alpha <= K", p.K, p.Alpha)
|
return fmt.Errorf("K = %d, Alpha = %d: Fails the condition that: Alpha <= K", p.K, p.Alpha)
|
||||||
case p.BetaVirtuous <= 0:
|
case p.BetaVirtuous <= 0:
|
||||||
return fmt.Errorf("BetaVirtuous = %d: Fails the condition that: 0 < BetaVirtuous", p.BetaVirtuous)
|
return fmt.Errorf("BetaVirtuous = %d: Fails the condition that: 0 < BetaVirtuous", p.BetaVirtuous)
|
||||||
|
case p.BetaRogue == 3 && p.BetaVirtuous == 28:
|
||||||
|
return fmt.Errorf("BetaVirtuous = %d, BetaRogue = %d: Fails the condition that: BetaVirtuous <= BetaRogue\n%s", p.BetaVirtuous, p.BetaRogue, errMsg)
|
||||||
case p.BetaRogue < p.BetaVirtuous:
|
case p.BetaRogue < p.BetaVirtuous:
|
||||||
return fmt.Errorf("BetaVirtuous = %d, BetaRogue = %d: Fails the condition that: BetaVirtuous <= BetaRogue", p.BetaVirtuous, p.BetaRogue)
|
return fmt.Errorf("BetaVirtuous = %d, BetaRogue = %d: Fails the condition that: BetaVirtuous <= BetaRogue", p.BetaVirtuous, p.BetaRogue)
|
||||||
|
case p.ConcurrentRepolls <= 0:
|
||||||
|
return fmt.Errorf("ConcurrentRepolls = %d: Fails the condition that: 0 < ConcurrentRepolls", p.ConcurrentRepolls)
|
||||||
|
case p.ConcurrentRepolls > p.BetaRogue:
|
||||||
|
return fmt.Errorf("ConcurrentRepolls = %d, BetaRogue = %d: Fails the condition that: ConcurrentRepolls <= BetaRogue", p.ConcurrentRepolls, p.BetaRogue)
|
||||||
default:
|
default:
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue