Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

go/genesis: Fix genesis tests and registry sanity checks #2612

Merged
merged 3 commits into from
Jan 29, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .changelog/2589.internal.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
go/genesis: Fix genesis tests and registry sanity checks.
9 changes: 8 additions & 1 deletion go/common/grpc/policy/policy.go
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,14 @@ func (c *DynamicRuntimePolicyChecker) SetAccessPolicy(policy accessctl.Policy, r
c.accessPolicies[runtimeID] = policy

if c.watcher != nil {
c.watcher.PolicyUpdated(c.service, c.accessPolicies)
// Create a snapshot of the access policies map. While each policy is immutable, the set of
// all policies can be mutated by the dynamic runtime policy checker.
policies := make(map[common.Namespace]accessctl.Policy, len(c.accessPolicies))
for k, v := range c.accessPolicies {
policies[k] = v
}

c.watcher.PolicyUpdated(c.service, policies)
}
}

Expand Down
2 changes: 1 addition & 1 deletion go/consensus/tendermint/tests/evidence.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import (
"github.com/oasislabs/oasis-core/go/common/identity"
consensus "github.com/oasislabs/oasis-core/go/consensus/api"
tmcrypto "github.com/oasislabs/oasis-core/go/consensus/tendermint/crypto"
genesisTestHelpers "github.com/oasislabs/oasis-core/go/genesis/tests/helpers"
genesisTestHelpers "github.com/oasislabs/oasis-core/go/genesis/tests"
)

// MakeDoubleSignEvidence creates consensus evidence of double signing.
Expand Down
2 changes: 1 addition & 1 deletion go/consensus/tendermint/tests/genesis/genesis.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import (
"github.com/oasislabs/oasis-core/go/consensus/tendermint/service"
epochtime "github.com/oasislabs/oasis-core/go/epochtime/api"
genesis "github.com/oasislabs/oasis-core/go/genesis/api"
genesisTestHelpers "github.com/oasislabs/oasis-core/go/genesis/tests/helpers"
genesisTestHelpers "github.com/oasislabs/oasis-core/go/genesis/tests"
registry "github.com/oasislabs/oasis-core/go/registry/api"
roothash "github.com/oasislabs/oasis-core/go/roothash/api"
scheduler "github.com/oasislabs/oasis-core/go/scheduler/api"
Expand Down
145 changes: 108 additions & 37 deletions go/genesis/tests/tester.go → go/genesis/genesis_test.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package tests
package genesis

import (
"crypto/ed25519"
"encoding/hex"
"math"
"testing"
Expand All @@ -20,7 +21,7 @@ import (
tendermint "github.com/oasislabs/oasis-core/go/consensus/tendermint/api"
epochtime "github.com/oasislabs/oasis-core/go/epochtime/api"
genesis "github.com/oasislabs/oasis-core/go/genesis/api"
genesisTestHelpers "github.com/oasislabs/oasis-core/go/genesis/tests/helpers"
genesisTestHelpers "github.com/oasislabs/oasis-core/go/genesis/tests"
keymanager "github.com/oasislabs/oasis-core/go/keymanager/api"
cmdFlags "github.com/oasislabs/oasis-core/go/oasis-node/cmd/common/flags"
registry "github.com/oasislabs/oasis-core/go/registry/api"
Expand All @@ -45,9 +46,10 @@ var testDoc = &genesis.Document{
},
Registry: registry.Genesis{
Parameters: registry.ConsensusParameters{
DebugAllowUnroutableAddresses: true,
DebugAllowRuntimeRegistration: true,
DebugBypassStake: true,
DebugAllowUnroutableAddresses: true,
DebugAllowRuntimeRegistration: true,
DebugBypassStake: true,
DebugAllowEntitySignedNodeRegistration: true,
},
},
Scheduler: scheduler.Genesis{
Expand Down Expand Up @@ -85,11 +87,9 @@ func signRuntimeOrDie(signer signature.Signer, rt *registry.Runtime) *registry.S
return signedRuntime
}

func signNodeOrDie(signer signature.Signer, n *node.Node) *node.MultiSignedNode {
func signNodeOrDie(signers []signature.Signer, n *node.Node) *node.MultiSignedNode {
signedNode, err := node.MultiSignNode(
[]signature.Signer{
signer,
},
signers,
registry.RegisterGenesisNodeSignatureContext,
n,
)
Expand Down Expand Up @@ -130,7 +130,7 @@ func TestGenesisChainContext(t *testing.T) {
// on each run.
stableDoc.Staking = staking.Genesis{}

require.Equal(t, "daba5eed9f82d37c76384f9f185dc0bfff60eb57a33b7d8955e265244e0a0a51", stableDoc.ChainContext())
require.Equal(t, "7670bb121628f48b2b87ef61ac79671684b0255f86323a4583d3bed5500bb31b", stableDoc.ChainContext())
}

func TestGenesisSanityCheck(t *testing.T) {
Expand All @@ -140,12 +140,15 @@ func TestGenesisSanityCheck(t *testing.T) {
// First, set up a few things we'll need in the tests below.
signer := memorySigner.NewTestSigner("genesis sanity checks signer")
signer2 := memorySigner.NewTestSigner("another genesis sanity checks signer")
nodeSigner := memorySigner.NewTestSigner("node genesis sanity checks signer")
nodeConsensusSigner := memorySigner.NewTestSigner("node consensus genesis sanity checks signer")
nodeP2PSigner := memorySigner.NewTestSigner("node P2P genesis sanity checks signer")
validPK := signer.Public()
var validNS common.Namespace
_ = validNS.UnmarshalBinary(validPK[:])

invalidPK := hex2pk("c7176a703d4dd84fba3c0b760d10670f2a2053fa2c39ccc64ec7fd7792ac037a")
invalidNS := hex2ns("c7176a703d4dd84fba3c0b760d10670f2a2053fa2c39ccc64ec7fd7792ac037a", true)
unknownPK := memorySigner.NewTestSigner("unknown genesis sanity checks signer").Public()

signature.BuildPublicKeyBlacklist(true)

Expand All @@ -162,10 +165,17 @@ func TestGenesisSanityCheck(t *testing.T) {
}
signedTestEntity := signEntityOrDie(signer, testEntity)

kmRuntimeID := hex2ns("0000000000000000000000000000000000000000000000000000000000000000", false)
kmRuntimeID := hex2ns("4000000000000000ffffffffffffffffffffffffffffffffffffffffffffffff", false)
testKMRuntime := &registry.Runtime{
ID: kmRuntimeID,
Kind: registry.KindKeyManager,
AdmissionPolicy: registry.RuntimeAdmissionPolicy{
EntityWhitelist: &registry.EntityWhitelistRuntimeAdmissionPolicy{
Entities: map[signature.PublicKey]bool{
validPK: true,
},
},
},
}
signedTestKMRuntime := signRuntimeOrDie(signer, testKMRuntime)

Expand All @@ -183,31 +193,62 @@ func TestGenesisSanityCheck(t *testing.T) {
RoundTimeout: 1 * time.Second,
},
TxnScheduler: registry.TxnSchedulerParameters{
GroupSize: 1,
Algorithm: "batching",
BatchFlushTimeout: 1 * time.Second,
MaxBatchSize: 1,
MaxBatchSizeBytes: 1,
},
Storage: registry.StorageParameters{
GroupSize: 1,
},
AdmissionPolicy: registry.RuntimeAdmissionPolicy{
AnyNode: &registry.AnyNodeRuntimeAdmissionPolicy{},
},
}
signedTestRuntime := signRuntimeOrDie(signer, testRuntime)

testNodeID := hex2pk("0000000000000000000000000000000000000000000000000000000000000010")
dummyCert, err := tls.Generate("genesis sanity check dummy cert")
if err != nil {
panic(err)
}
var testConsensusAddress node.ConsensusAddress
_ = testConsensusAddress.UnmarshalText([]byte("f29bb9979109fc2512b2ae8ed14531c459cdeb2cb73077440115b6c955a359f1@127.0.0.1:1234"))
var testAddress node.Address
_ = testAddress.UnmarshalText([]byte("127.0.0.1:1234"))
testNode := &node.Node{
ID: testNodeID,
ID: nodeSigner.Public(),
EntityID: testEntity.ID,
Expiration: 10,
Roles: node.RoleValidator,
Committee: node.CommitteeInfo{
Certificate: dummyCert.Certificate[0],
Addresses: []node.CommitteeAddress{
{Certificate: dummyCert.Certificate[0], Address: testAddress},
},
},
P2P: node.P2PInfo{
ID: nodeP2PSigner.Public(),
Addresses: []node.Address{testAddress},
},
Consensus: node.ConsensusInfo{
ID: testNodeID,
ID: nodeConsensusSigner.Public(),
Addresses: []node.ConsensusAddress{testConsensusAddress},
},
}
signedTestNode := signNodeOrDie(signer, testNode)
nodeTLSSigner := memorySigner.NewFromRuntime(dummyCert.PrivateKey.(ed25519.PrivateKey))
nodeSigners := []signature.Signer{
nodeSigner,
nodeP2PSigner,
nodeTLSSigner,
nodeConsensusSigner,
}
signedTestNode := signNodeOrDie(nodeSigners, testNode)
entitySignedTestNode := signNodeOrDie(append([]signature.Signer{signer}, nodeSigners...), testNode)

testDocCopy := *testDoc
testDoc := &testDocCopy
testDoc.Registry.Parameters.KeyManagerOperator = signer.Public()

// Test genesis document should pass sanity check.
require.NoError(testDoc.SanityCheck(), "test genesis document should be valid")
Expand All @@ -231,10 +272,6 @@ func TestGenesisSanityCheck(t *testing.T) {
require.Error(d.SanityCheck(), "halt epoch in the past should be invalid")

// Test consensus genesis checks.
d = *testDoc
d.Consensus.Backend = "asdf"
require.Error(d.SanityCheck(), "invalid consensus backend should be rejected")

d = *testDoc
d.Consensus.Parameters.TimeoutCommit = 0
d.Consensus.Parameters.SkipTimeoutCommit = false
Expand All @@ -260,11 +297,22 @@ func TestGenesisSanityCheck(t *testing.T) {
d.KeyManager = keymanager.Genesis{
Statuses: []*keymanager.Status{
{
ID: invalidNS,
ID: testRuntimeID,
},
},
}
require.Error(d.SanityCheck(), "invalid keymanager ID should be rejected")
require.Error(d.SanityCheck(), "invalid keymanager runtime should be rejected")

d = *testDoc
d.KeyManager = keymanager.Genesis{
Statuses: []*keymanager.Status{
{
ID: validNS,
Nodes: []signature.PublicKey{invalidPK},
},
},
}
require.Error(d.SanityCheck(), "invalid keymanager node should be rejected")

// Test roothash genesis checks.
// First we define a helper function for calling the SanityCheck() on RuntimeStates.
Expand Down Expand Up @@ -409,7 +457,7 @@ func TestGenesisSanityCheck(t *testing.T) {

d = *testDoc
te = *testEntity
te.Nodes = []signature.PublicKey{invalidPK}
te.Nodes = []signature.PublicKey{unknownPK}
te.AllowEntitySignedNodes = false
signedEntityWithBrokenNode := signEntityOrDie(signer, &te)
d.Registry.Entities = []*entity.SignedEntity{signedEntityWithBrokenNode}
Expand All @@ -419,18 +467,18 @@ func TestGenesisSanityCheck(t *testing.T) {

d = *testDoc
te = *testEntity
te.Nodes = []signature.PublicKey{invalidPK}
te.Nodes = []signature.PublicKey{unknownPK}
te.AllowEntitySignedNodes = true
signedEntityWithBrokenNode = signEntityOrDie(signer, &te)
d.Registry.Entities = []*entity.SignedEntity{signedEntityWithBrokenNode}
d.Registry.Runtimes = []*registry.SignedRuntime{}
d.Registry.Nodes = []*node.MultiSignedNode{signedTestNode}
d.Registry.Nodes = []*node.MultiSignedNode{entitySignedTestNode}
require.NoError(d.SanityCheck(), "node not listed among controlling entity's nodes should still be accepted if the entity allows entity-signed nodes")

d = *testDoc
tn := *testNode
tn.EntityID = invalidPK
signedBrokenTestNode := signNodeOrDie(signer, &tn)
tn.EntityID = unknownPK
signedBrokenTestNode := signNodeOrDie(nodeSigners, &tn)
d.Registry.Entities = []*entity.SignedEntity{signedEntityWithTestNode}
d.Registry.Runtimes = []*registry.SignedRuntime{signedTestKMRuntime}
d.Registry.Nodes = []*node.MultiSignedNode{signedBrokenTestNode}
Expand All @@ -456,16 +504,25 @@ func TestGenesisSanityCheck(t *testing.T) {
d = *testDoc
tn = *testNode
tn.Roles = 1<<16 | 1<<17
signedBrokenTestNode = signNodeOrDie(signer, &tn)
signedBrokenTestNode = signNodeOrDie(nodeSigners, &tn)
d.Registry.Entities = []*entity.SignedEntity{signedEntityWithTestNode}
d.Registry.Runtimes = []*registry.SignedRuntime{signedTestKMRuntime}
d.Registry.Nodes = []*node.MultiSignedNode{signedBrokenTestNode}
require.Error(d.SanityCheck(), "node with any reserved role bits set should be rejected")

d = *testDoc
tn = *testNode
tn.Roles = 0
signedBrokenTestNode = signNodeOrDie(nodeSigners, &tn)
d.Registry.Entities = []*entity.SignedEntity{signedEntityWithTestNode}
d.Registry.Runtimes = []*registry.SignedRuntime{signedTestKMRuntime}
d.Registry.Nodes = []*node.MultiSignedNode{signedBrokenTestNode}
require.Error(d.SanityCheck(), "node without any role bits set should be rejected")

d = *testDoc
tn = *testNode
tn.Committee.Certificate = []byte{1, 2, 3}
signedBrokenTestNode = signNodeOrDie(signer, &tn)
signedBrokenTestNode = signNodeOrDie(nodeSigners, &tn)
d.Registry.Entities = []*entity.SignedEntity{signedEntityWithTestNode}
d.Registry.Runtimes = []*registry.SignedRuntime{signedTestKMRuntime}
d.Registry.Nodes = []*node.MultiSignedNode{signedBrokenTestNode}
Expand All @@ -474,7 +531,7 @@ func TestGenesisSanityCheck(t *testing.T) {
d = *testDoc
tn = *testNode
tn.Consensus.ID = invalidPK
signedBrokenTestNode = signNodeOrDie(signer, &tn)
signedBrokenTestNode = signNodeOrDie(nodeSigners, &tn)
d.Registry.Entities = []*entity.SignedEntity{signedEntityWithTestNode}
d.Registry.Runtimes = []*registry.SignedRuntime{signedTestKMRuntime}
d.Registry.Nodes = []*node.MultiSignedNode{signedBrokenTestNode}
Expand All @@ -483,7 +540,7 @@ func TestGenesisSanityCheck(t *testing.T) {
d = *testDoc
tn = *testNode
tn.Roles = node.RoleComputeWorker
signedBrokenTestNode = signNodeOrDie(signer, &tn)
signedBrokenTestNode = signNodeOrDie(nodeSigners, &tn)
d.Registry.Entities = []*entity.SignedEntity{signedEntityWithTestNode}
d.Registry.Runtimes = []*registry.SignedRuntime{signedTestKMRuntime}
d.Registry.Nodes = []*node.MultiSignedNode{signedBrokenTestNode}
Expand All @@ -492,7 +549,7 @@ func TestGenesisSanityCheck(t *testing.T) {
d = *testDoc
tn = *testNode
tn.Roles = node.RoleKeyManager
signedBrokenTestNode = signNodeOrDie(signer, &tn)
signedBrokenTestNode = signNodeOrDie(nodeSigners, &tn)
d.Registry.Entities = []*entity.SignedEntity{signedEntityWithTestNode}
d.Registry.Runtimes = []*registry.SignedRuntime{signedTestKMRuntime}
d.Registry.Nodes = []*node.MultiSignedNode{signedBrokenTestNode}
Expand All @@ -506,7 +563,7 @@ func TestGenesisSanityCheck(t *testing.T) {
ID: testKMRuntime.ID,
},
}
signedKMTestNode := signNodeOrDie(signer, &tn)
signedKMTestNode := signNodeOrDie(nodeSigners, &tn)
d.Registry.Entities = []*entity.SignedEntity{signedEntityWithTestNode}
d.Registry.Runtimes = []*registry.SignedRuntime{signedTestKMRuntime}
d.Registry.Nodes = []*node.MultiSignedNode{signedKMTestNode}
Expand All @@ -520,7 +577,7 @@ func TestGenesisSanityCheck(t *testing.T) {
ID: testRuntime.ID,
},
}
signedBrokenTestNode = signNodeOrDie(signer, &tn)
signedBrokenTestNode = signNodeOrDie(nodeSigners, &tn)
d.Registry.Entities = []*entity.SignedEntity{signedEntityWithTestNode}
d.Registry.Runtimes = []*registry.SignedRuntime{signedTestKMRuntime}
d.Registry.Nodes = []*node.MultiSignedNode{signedBrokenTestNode}
Expand All @@ -534,7 +591,7 @@ func TestGenesisSanityCheck(t *testing.T) {
ID: testRuntime.ID,
},
}
signedBrokenTestNode = signNodeOrDie(signer, &tn)
signedBrokenTestNode = signNodeOrDie(nodeSigners, &tn)
d.Registry.Entities = []*entity.SignedEntity{signedEntityWithTestNode}
d.Registry.Runtimes = []*registry.SignedRuntime{signedTestKMRuntime, signedTestRuntime}
d.Registry.Nodes = []*node.MultiSignedNode{signedBrokenTestNode}
Expand All @@ -548,7 +605,7 @@ func TestGenesisSanityCheck(t *testing.T) {
ID: testKMRuntime.ID,
},
}
signedBrokenTestNode = signNodeOrDie(signer, &tn)
signedBrokenTestNode = signNodeOrDie(nodeSigners, &tn)
d.Registry.Entities = []*entity.SignedEntity{signedEntityWithTestNode}
d.Registry.Runtimes = []*registry.SignedRuntime{signedTestKMRuntime, signedTestRuntime}
d.Registry.Nodes = []*node.MultiSignedNode{signedBrokenTestNode}
Expand All @@ -562,12 +619,26 @@ func TestGenesisSanityCheck(t *testing.T) {
ID: testRuntime.ID,
},
}
signedComputeTestNode := signNodeOrDie(signer, &tn)
signedComputeTestNode := signNodeOrDie(nodeSigners, &tn)
d.Registry.Entities = []*entity.SignedEntity{signedEntityWithTestNode}
d.Registry.Runtimes = []*registry.SignedRuntime{signedTestKMRuntime, signedTestRuntime}
d.Registry.Nodes = []*node.MultiSignedNode{signedComputeTestNode}
require.NoError(d.SanityCheck(), "compute node with compute runtime should pass")

d = *testDoc
tn = *testNode
tn.Roles = node.RoleStorageWorker
tn.Runtimes = []*node.Runtime{
&node.Runtime{
ID: testRuntime.ID,
},
}
signedStorageTestNode := signNodeOrDie(nodeSigners, &tn)
d.Registry.Entities = []*entity.SignedEntity{signedEntityWithTestNode}
d.Registry.Runtimes = []*registry.SignedRuntime{signedTestKMRuntime, signedTestRuntime}
d.Registry.Nodes = []*node.MultiSignedNode{signedStorageTestNode}
require.NoError(d.SanityCheck(), "storage node with compute runtime should pass")

// Test staking genesis checks.
// NOTE: There doesn't seem to be a way to generate invalid Quantities, so
// we're just going to test the code that checks if things add up.
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// Package helpers contains genesis test helpers.
package helpers
// Package tests contains genesis test helpers.
package tests

import (
"github.com/oasislabs/oasis-core/go/common/crypto/hash"
Expand Down
Loading