Merge branch 'master' into custom-genesis

This commit is contained in:
Stephen Buttolph 2020-03-27 12:11:19 -04:00 committed by GitHub
commit 10779d168d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 243 additions and 59 deletions

3
.gitignore vendored
View File

@ -18,6 +18,9 @@ awscpu
# Output of the go coverage tool, specifically when used with LiteIDE
*.out
# ignore GoLand metafiles directory
.idea/
*logs/
.vscode*

View File

@ -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`.
- Check the built image by `docker image ls`, you should see some image tagged
`gecko-xxxxxxxx`, where `xxxxxxxx` is the commit id of the Gecko source it was built from.
- Test Gecko by `docker run -ti -p 9651:9651 gecko-xxxxxxxx /gecko/build/ava
- Test Gecko by `docker run -ti -p 9650:9650 -p 9651:9651 gecko-xxxxxxxx /gecko/build/ava
--public-ip=127.0.0.1 --snow-sample-size=1 --snow-quorum-size=1 --staking-tls-enabled=false`. (For a production deployment,
you may want to extend the docker image with required credentials for
staking and TLS.)

View File

@ -391,7 +391,7 @@ func (m *manager) createAvalancheChain(
Context: ctx,
Validators: validators,
Beacons: beacons,
Alpha: (beacons.Len() + 1) / 2,
Alpha: beacons.Len()/2 + 1, // must be > 50%
Sender: &sender,
},
VtxBlocked: vtxBlocker,
@ -471,7 +471,7 @@ func (m *manager) createSnowmanChain(
Context: ctx,
Validators: validators,
Beacons: beacons,
Alpha: (beacons.Len() + 1) / 2,
Alpha: beacons.Len()/2 + 1, // must be > 50%
Sender: &sender,
},
Blocked: blocked,

View File

@ -8,6 +8,7 @@ import (
"flag"
"fmt"
"net"
"os"
"path"
"strings"
@ -44,64 +45,76 @@ func init() {
loggingConfig, err := logging.DefaultConfig()
errs.Add(err)
fs := flag.NewFlagSet("gecko", flag.ContinueOnError)
// NetworkID:
networkName := flag.String("network-id", genesis.LocalName, "Network ID this node will connect to")
networkName := fs.String("network-id", genesis.LocalName, "Network ID this node will connect to")
// Ava fees:
flag.Uint64Var(&Config.AvaTxFee, "ava-tx-fee", 0, "Ava transaction fee, in $nAva")
fs.Uint64Var(&Config.AvaTxFee, "ava-tx-fee", 0, "Ava transaction fee, in $nAva")
// Assertions:
flag.BoolVar(&loggingConfig.Assertions, "assertions-enabled", true, "Turn on assertion execution")
fs.BoolVar(&loggingConfig.Assertions, "assertions-enabled", true, "Turn on assertion execution")
// Crypto:
flag.BoolVar(&Config.EnableCrypto, "signature-verification-enabled", true, "Turn on signature verification")
fs.BoolVar(&Config.EnableCrypto, "signature-verification-enabled", true, "Turn on signature verification")
// Database:
db := flag.Bool("db-enabled", true, "Turn on persistent storage")
dbDir := flag.String("db-dir", "db", "Database directory for Ava state")
db := fs.Bool("db-enabled", true, "Turn on persistent storage")
dbDir := fs.String("db-dir", "db", "Database directory for Ava state")
// IP:
consensusIP := flag.String("public-ip", "", "Public IP of this node")
consensusIP := fs.String("public-ip", "", "Public IP of this node")
// HTTP Server:
httpPort := flag.Uint("http-port", 9650, "Port of the HTTP server")
flag.BoolVar(&Config.EnableHTTPS, "http-tls-enabled", false, "Upgrade the HTTP server to HTTPs")
flag.StringVar(&Config.HTTPSKeyFile, "http-tls-key-file", "", "TLS private key file for the HTTPs server")
flag.StringVar(&Config.HTTPSCertFile, "http-tls-cert-file", "", "TLS certificate file for the HTTPs server")
httpPort := fs.Uint("http-port", 9650, "Port of the HTTP server")
fs.BoolVar(&Config.EnableHTTPS, "http-tls-enabled", false, "Upgrade the HTTP server to HTTPs")
fs.StringVar(&Config.HTTPSKeyFile, "http-tls-key-file", "", "TLS private key file for the HTTPs server")
fs.StringVar(&Config.HTTPSCertFile, "http-tls-cert-file", "", "TLS certificate file for the HTTPs server")
// Bootstrapping:
bootstrapIPs := flag.String("bootstrap-ips", "", "Comma separated list of bootstrap peer ips to connect to. Example: 127.0.0.1:9630,127.0.0.1:9631")
bootstrapIDs := flag.String("bootstrap-ids", "", "Comma separated list of bootstrap peer ids to connect to. Example: JR4dVmy6ffUGAKCBDkyCbeZbyHQBeDsET,8CrVPQZ4VSqgL8zTdvL14G8HqAfrBr4z")
bootstrapIPs := fs.String("bootstrap-ips", "", "Comma separated list of bootstrap peer ips to connect to. Example: 127.0.0.1:9630,127.0.0.1:9631")
bootstrapIDs := fs.String("bootstrap-ids", "", "Comma separated list of bootstrap peer ids to connect to. Example: JR4dVmy6ffUGAKCBDkyCbeZbyHQBeDsET,8CrVPQZ4VSqgL8zTdvL14G8HqAfrBr4z")
// Staking:
consensusPort := flag.Uint("staking-port", 9651, "Port of the consensus server")
flag.BoolVar(&Config.EnableStaking, "staking-tls-enabled", true, "Require TLS to authenticate staking connections")
flag.StringVar(&Config.StakingKeyFile, "staking-tls-key-file", "", "TLS private key file for staking connections")
flag.StringVar(&Config.StakingCertFile, "staking-tls-cert-file", "", "TLS certificate file for staking connections")
consensusPort := fs.Uint("staking-port", 9651, "Port of the consensus server")
fs.BoolVar(&Config.EnableStaking, "staking-tls-enabled", true, "Require TLS to authenticate staking connections")
fs.StringVar(&Config.StakingKeyFile, "staking-tls-key-file", "", "TLS private key file for staking connections")
fs.StringVar(&Config.StakingCertFile, "staking-tls-cert-file", "", "TLS certificate file for staking connections")
// Logging:
logsDir := flag.String("log-dir", "", "Logging directory for Ava")
logLevel := flag.String("log-level", "info", "The log level. Should be one of {verbo, debug, info, warn, error, fatal, off}")
logDisplayLevel := flag.String("log-display-level", "", "The log display level. If left blank, will inherit the value of log-level. Otherwise, should be one of {verbo, debug, info, warn, error, fatal, off}")
logsDir := fs.String("log-dir", "", "Logging directory for Ava")
logLevel := fs.String("log-level", "info", "The log level. Should be one of {verbo, debug, info, warn, error, fatal, off}")
logDisplayLevel := fs.String("log-display-level", "", "The log display level. If left blank, will inherit the value of log-level. Otherwise, should be one of {verbo, debug, info, warn, error, fatal, off}")
flag.IntVar(&Config.ConsensusParams.K, "snow-sample-size", 20, "Number of nodes to query for each network poll")
flag.IntVar(&Config.ConsensusParams.Alpha, "snow-quorum-size", 18, "Alpha value to use for required number positive results")
flag.IntVar(&Config.ConsensusParams.BetaVirtuous, "snow-virtuous-commit-threshold", 20, "Beta value to use for virtuous transactions")
flag.IntVar(&Config.ConsensusParams.BetaRogue, "snow-rogue-commit-threshold", 30, "Beta value to use for rogue transactions")
flag.IntVar(&Config.ConsensusParams.Parents, "snow-avalanche-num-parents", 5, "Number of vertexes for reference from each new vertex")
flag.IntVar(&Config.ConsensusParams.BatchSize, "snow-avalanche-batch-size", 30, "Number of operations to batch in each new vertex")
fs.IntVar(&Config.ConsensusParams.K, "snow-sample-size", 20, "Number of nodes to query for each network poll")
fs.IntVar(&Config.ConsensusParams.Alpha, "snow-quorum-size", 18, "Alpha value to use for required number positive results")
fs.IntVar(&Config.ConsensusParams.BetaVirtuous, "snow-virtuous-commit-threshold", 20, "Beta value to use for virtuous transactions")
fs.IntVar(&Config.ConsensusParams.BetaRogue, "snow-rogue-commit-threshold", 30, "Beta value to use for rogue transactions")
fs.IntVar(&Config.ConsensusParams.Parents, "snow-avalanche-num-parents", 5, "Number of vertexes for reference from each new vertex")
fs.IntVar(&Config.ConsensusParams.BatchSize, "snow-avalanche-batch-size", 30, "Number of operations to batch in each new vertex")
// Enable/Disable APIs:
flag.BoolVar(&Config.AdminAPIEnabled, "api-admin-enabled", true, "If true, this node exposes the Admin API")
flag.BoolVar(&Config.KeystoreAPIEnabled, "api-keystore-enabled", true, "If true, this node exposes the Keystore API")
flag.BoolVar(&Config.MetricsAPIEnabled, "api-metrics-enabled", true, "If true, this node exposes the Metrics API")
flag.BoolVar(&Config.IPCEnabled, "api-ipcs-enabled", false, "If true, IPCs can be opened")
fs.BoolVar(&Config.AdminAPIEnabled, "api-admin-enabled", true, "If true, this node exposes the Admin API")
fs.BoolVar(&Config.KeystoreAPIEnabled, "api-keystore-enabled", true, "If true, this node exposes the Keystore API")
fs.BoolVar(&Config.MetricsAPIEnabled, "api-metrics-enabled", true, "If true, this node exposes the Metrics API")
fs.BoolVar(&Config.IPCEnabled, "api-ipcs-enabled", false, "If true, IPCs can be opened")
// Throughput Server
throughputPort := flag.Uint("xput-server-port", 9652, "Port of the deprecated throughput test server")
flag.BoolVar(&Config.ThroughputServerEnabled, "xput-server-enabled", false, "If true, throughput test server is created")
throughputPort := fs.Uint("xput-server-port", 9652, "Port of the deprecated throughput test server")
fs.BoolVar(&Config.ThroughputServerEnabled, "xput-server-enabled", false, "If true, throughput test server is created")
flag.Parse()
ferr := fs.Parse(os.Args[1:])
if ferr == flag.ErrHelp {
// display usage/help text and exit successfully
os.Exit(0)
}
if ferr != nil {
// other type of error occurred when parsing args
os.Exit(2)
}
networkID, err := genesis.NetworkID(*networkName)
errs.Add(err)

View File

@ -119,7 +119,7 @@ func (b *bootstrapper) fetch(vtxID ids.ID) {
b.sendRequest(vtxID)
return
}
b.addVertex(vtx)
b.storeVertex(vtx)
}
func (b *bootstrapper) sendRequest(vtxID ids.ID) {
@ -138,6 +138,14 @@ func (b *bootstrapper) sendRequest(vtxID ids.ID) {
}
func (b *bootstrapper) addVertex(vtx avalanche.Vertex) {
b.storeVertex(vtx)
if numPending := b.pending.Len(); numPending == 0 {
b.finish()
}
}
func (b *bootstrapper) storeVertex(vtx avalanche.Vertex) {
vts := []avalanche.Vertex{vtx}
for len(vts) > 0 {
@ -181,9 +189,6 @@ func (b *bootstrapper) addVertex(vtx avalanche.Vertex) {
numPending := b.pending.Len()
b.numPendingRequests.Set(float64(numPending))
if numPending == 0 {
b.finish()
}
}
func (b *bootstrapper) finish() {

View File

@ -957,3 +957,53 @@ func TestBootstrapperFilterAccepted(t *testing.T) {
t.Fatalf("Vtx shouldn't be accepted")
}
}
func TestBootstrapperPartialFetch(t *testing.T) {
config, _, sender, state, _ := newConfig(t)
vtxID0 := ids.Empty.Prefix(0)
vtxID1 := ids.Empty.Prefix(1)
vtxBytes0 := []byte{0}
vtx0 := &Vtx{
id: vtxID0,
height: 0,
status: choices.Processing,
bytes: vtxBytes0,
}
bs := bootstrapper{}
bs.metrics.Initialize(config.Context.Log, fmt.Sprintf("gecko_%s", config.Context.ChainID), prometheus.NewRegistry())
bs.Initialize(config)
acceptedIDs := ids.Set{}
acceptedIDs.Add(
vtxID0,
vtxID1,
)
state.getVertex = func(vtxID ids.ID) (avalanche.Vertex, error) {
switch {
case vtxID.Equals(vtxID0):
return vtx0, nil
case vtxID.Equals(vtxID1):
return nil, errUnknownVertex
default:
t.Fatal(errUnknownVertex)
panic(errUnknownVertex)
}
}
sender.CantGet = false
bs.ForceAccepted(acceptedIDs)
if bs.finished {
t.Fatalf("should have requested a vertex")
}
if bs.pending.Len() != 1 {
t.Fatalf("wrong number pending")
}
}

View File

@ -113,7 +113,7 @@ func (b *bootstrapper) fetch(blkID ids.ID) {
b.sendRequest(blkID)
return
}
b.addBlock(blk)
b.storeBlock(blk)
}
func (b *bootstrapper) sendRequest(blkID ids.ID) {
@ -132,6 +132,14 @@ func (b *bootstrapper) sendRequest(blkID ids.ID) {
}
func (b *bootstrapper) addBlock(blk snowman.Block) {
b.storeBlock(blk)
if numPending := b.pending.Len(); numPending == 0 {
b.finish()
}
}
func (b *bootstrapper) storeBlock(blk snowman.Block) {
status := blk.Status()
blkID := blk.ID()
for status == choices.Processing {
@ -161,9 +169,6 @@ func (b *bootstrapper) addBlock(blk snowman.Block) {
numPending := b.pending.Len()
b.numPendingRequests.Set(float64(numPending))
if numPending == 0 {
b.finish()
}
}
func (b *bootstrapper) finish() {

View File

@ -425,3 +425,54 @@ func TestBootstrapperFilterAccepted(t *testing.T) {
t.Fatalf("Blk shouldn't be accepted")
}
}
func TestBootstrapperPartialFetch(t *testing.T) {
config, _, sender, vm := newConfig(t)
blkID0 := ids.Empty.Prefix(0)
blkID1 := ids.Empty.Prefix(1)
blkBytes0 := []byte{0}
blk0 := &Blk{
id: blkID0,
height: 0,
status: choices.Accepted,
bytes: blkBytes0,
}
bs := bootstrapper{}
bs.metrics.Initialize(config.Context.Log, fmt.Sprintf("gecko_%s", config.Context.ChainID), prometheus.NewRegistry())
bs.Initialize(config)
acceptedIDs := ids.Set{}
acceptedIDs.Add(
blkID0,
blkID1,
)
vm.GetBlockF = func(blkID ids.ID) (snowman.Block, error) {
switch {
case blkID.Equals(blkID0):
return blk0, nil
case blkID.Equals(blkID1):
return nil, errUnknownBlock
default:
t.Fatal(errUnknownBlock)
panic(errUnknownBlock)
}
}
sender.CantGet = false
bs.onFinished = func() {}
bs.ForceAccepted(acceptedIDs)
if bs.finished {
t.Fatalf("should have requested a block")
}
if bs.pending.Len() != 1 {
t.Fatalf("wrong number pending")
}
}

View File

@ -324,6 +324,11 @@ func (c codec) unmarshal(p *wrappers.Packer, field reflect.Value) error {
if !ok {
return errUnmarshalUnregisteredType
}
// Ensure struct actually does implement the interface
fieldType := field.Type()
if !typ.Implements(fieldType) {
return fmt.Errorf("%s does not implement interface %s", typ, fieldType)
}
concreteInstancePtr := reflect.New(typ) // instance of the proper type
// Unmarshal into the struct
if err := c.unmarshal(p, concreteInstancePtr.Elem()); err != nil {

View File

@ -538,3 +538,42 @@ func TestTooLargeUnmarshal(t *testing.T) {
t.Fatalf("Should have errored due to too many bytes provided")
}
}
type outerInterface interface {
ToInt() int
}
type outer struct {
Interface outerInterface `serialize:"true"`
}
type innerInterface struct{}
func (it *innerInterface) ToInt() int {
return 0
}
type innerNoInterface struct{}
// Ensure deserializing structs into the wrong interface errors gracefully
func TestUnmarshalInvalidInterface(t *testing.T) {
codec := NewDefault()
codec.RegisterType(&innerInterface{})
codec.RegisterType(&innerNoInterface{})
{
bytes := []byte{0, 0, 0, 0}
s := outer{}
if err := codec.Unmarshal(bytes, &s); err != nil {
t.Fatal(err)
}
}
{
bytes := []byte{0, 0, 0, 1}
s := outer{}
if err := codec.Unmarshal(bytes, &s); err == nil {
t.Fatalf("should have errored")
}
}
}

View File

@ -6,6 +6,7 @@ package main
import (
"flag"
"fmt"
"os"
stdnet "net"
@ -28,35 +29,47 @@ func init() {
loggingConfig, err := logging.DefaultConfig()
errs.Add(err)
fs := flag.NewFlagSet("xputtest", flag.ContinueOnError)
// NetworkID:
networkName := flag.String("network-id", genesis.LocalName, "Network ID this node will connect to")
networkName := fs.String("network-id", genesis.LocalName, "Network ID this node will connect to")
// Ava fees:
flag.Uint64Var(&config.AvaTxFee, "ava-tx-fee", 0, "Ava transaction fee, in $nAva")
fs.Uint64Var(&config.AvaTxFee, "ava-tx-fee", 0, "Ava transaction fee, in $nAva")
// Assertions:
flag.BoolVar(&loggingConfig.Assertions, "assertions-enabled", true, "Turn on assertion execution")
fs.BoolVar(&loggingConfig.Assertions, "assertions-enabled", true, "Turn on assertion execution")
// Crypto:
flag.BoolVar(&config.EnableCrypto, "signature-verification-enabled", true, "Turn on signature verification")
fs.BoolVar(&config.EnableCrypto, "signature-verification-enabled", true, "Turn on signature verification")
// Remote Server:
ip := flag.String("ip", "127.0.0.1", "IP address of the remote server socket")
port := flag.Uint("port", 9652, "Port of the remote server socket")
ip := fs.String("ip", "127.0.0.1", "IP address of the remote server socket")
port := fs.Uint("port", 9652, "Port of the remote server socket")
// Logging:
logsDir := flag.String("log-dir", "", "Logging directory for Ava")
logLevel := flag.String("log-level", "info", "The log level. Should be one of {all, debug, info, warn, error, fatal, off}")
logsDir := fs.String("log-dir", "", "Logging directory for Ava")
logLevel := fs.String("log-level", "info", "The log level. Should be one of {all, debug, info, warn, error, fatal, off}")
// Test Variables:
spchain := flag.Bool("sp-chain", false, "Execute simple payment chain transactions")
spdag := flag.Bool("sp-dag", false, "Execute simple payment dag transactions")
avm := flag.Bool("avm", false, "Execute avm transactions")
flag.IntVar(&config.Key, "key", 0, "Index of the genesis key list to use")
flag.IntVar(&config.NumTxs, "num-txs", 25000, "Total number of transaction to issue")
flag.IntVar(&config.MaxOutstandingTxs, "max-outstanding", 1000, "Maximum number of transactions to leave outstanding")
spchain := fs.Bool("sp-chain", false, "Execute simple payment chain transactions")
spdag := fs.Bool("sp-dag", false, "Execute simple payment dag transactions")
avm := fs.Bool("avm", false, "Execute avm transactions")
fs.IntVar(&config.Key, "key", 0, "Index of the genesis key list to use")
fs.IntVar(&config.NumTxs, "num-txs", 25000, "Total number of transaction to issue")
fs.IntVar(&config.MaxOutstandingTxs, "max-outstanding", 1000, "Maximum number of transactions to leave outstanding")
flag.Parse()
ferr := fs.Parse(os.Args[1:])
if ferr == flag.ErrHelp {
// display usage/help text and exit successfully
os.Exit(0)
}
if ferr != nil {
// other type of error occurred when parsing args
os.Exit(2)
}
networkID, err := genesis.NetworkID(*networkName)
errs.Add(err)