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

fix(proposals): Incremental proposal key for zero proposals (#8005) #8567

Merged
merged 24 commits into from
Feb 8, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
62cef52
fix(proposals): Incremental proposal key for zero proposals (#8005)
all-seeing-code Sep 2, 2021
c697086
fix: fixing audit logs for websocket connections (#8048) (#8053) (#8627)
all-seeing-code Jan 24, 2023
84dbff5
fix(restore): consider the banned namespaces while bumping (#7839) (#…
mangalaman93 Jan 25, 2023
d5c5ffd
fix(sec): CVE-2022-41721 (#8633)
skrdgraph Jan 28, 2023
f92c578
fix(sec): CVE & OS Patching (#8634)
skrdgraph Jan 30, 2023
651d888
fix(backup): create directory before writing backup (#8638)
mangalaman93 Jan 30, 2023
3239462
temp commit
all-seeing-code Jan 31, 2023
752def6
chore(ci): update readme (#8632)
joshua-goldstein Jan 30, 2023
5148c95
fix(mutation): validate mutation before applying it (#8623)
mangalaman93 Jan 31, 2023
9aa7b9a
fix(groot): do not upsert groot for all namespaces on restart (#8561)
mangalaman93 Feb 1, 2023
e32548c
remove comments
all-seeing-code Feb 2, 2023
9a8a598
fix(tests): Added Backup/Restore test for NFS. (#8551)
shivaji-dgraph Feb 1, 2023
ff8fe2a
fix(restore): Set kv version to restoreTs for all keys (#7930) (#8563)
mangalaman93 Feb 2, 2023
65eb7a7
fix(probe): do not contend for lock in lazy load (#8037) (#8041) (#8566)
mangalaman93 Feb 2, 2023
2ae33e2
Add a test that after snapshot is applied, GraphQL schema is refreshe…
shivaji-dgraph Feb 2, 2023
b70d235
bug(core): Fixed infinite loop in CommitToDisk (#8614)
harshil-goel Feb 2, 2023
7443a10
Store namespace in predicate as a hex separated by a hyphen to preven…
harshil-goel Feb 3, 2023
1558efd
fix(proposalKey): Proposal key initialisation with correct byte order…
all-seeing-code Feb 6, 2023
cd759d7
wrap the functions
all-seeing-code Feb 7, 2023
6499c3f
fix(build): Update dockerfile to use cache busting and reduce image s…
all-seeing-code Feb 7, 2023
5573b56
fix test failures
all-seeing-code Feb 7, 2023
365cca5
fix imports
all-seeing-code Feb 7, 2023
3246cbd
chore(deps): update min go build version (#8423)
joshua-goldstein Feb 7, 2023
af9398f
Merge branch 'main' into anurag/cherry-pick-proposal-fix
all-seeing-code Feb 8, 2023
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
17 changes: 16 additions & 1 deletion dgraph/cmd/zero/raft.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import (
"sort"
"strings"
"sync"
"sync/atomic"
"time"

farm "github.com/dgryski/go-farm"
Expand All @@ -48,6 +49,8 @@ const (
raftDefaults = "idx=1; learner=false;"
)

var proposalKey uint64

type node struct {
*conn.Node
server *Server
Expand Down Expand Up @@ -81,8 +84,19 @@ func (n *node) AmLeader() bool {
return time.Since(n.lastQuorum) <= 5*time.Second
}

// {2 bytes Node ID} {4 bytes for random} {2 bytes zero}
func (n *node) initProposalKey(id uint64) error {
x.AssertTrue(id != 0)
var err error
proposalKey, err = x.ProposalKey(n.Id)
all-seeing-code marked this conversation as resolved.
Show resolved Hide resolved
if err != nil {
return err
}
return nil
}

func (n *node) uniqueKey() uint64 {
return uint64(n.Id)<<32 | uint64(n.Rand.Uint32())
return atomic.AddUint64(&proposalKey, 1)
}

var errInternalRetry = errors.New("Retry Raft proposal internally")
Expand Down Expand Up @@ -626,6 +640,7 @@ func (n *node) checkForCIDInEntries() (bool, error) {
}

func (n *node) initAndStartNode() error {
x.Check(n.initProposalKey(n.Id))
_, restart, err := n.PastLife()
x.Check(err)

Expand Down
26 changes: 26 additions & 0 deletions dgraph/cmd/zero/zero_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,10 @@ import (
"github.com/stretchr/testify/require"
all-seeing-code marked this conversation as resolved.
Show resolved Hide resolved
"google.golang.org/grpc"

"github.com/dgraph-io/dgraph/conn"
"github.com/dgraph-io/dgraph/protos/pb"
"github.com/dgraph-io/dgraph/testutil"
"github.com/dgraph-io/ristretto/z"
)

func TestRemoveNode(t *testing.T) {
Expand Down Expand Up @@ -84,3 +86,27 @@ func TestIdBump(t *testing.T) {
_, err = zc.AssignIds(ctx, &pb.Num{Val: 10, Type: pb.Num_UID, Bump: true})
require.Contains(t, err.Error(), "Nothing to be leased")
}

func TestProposalKey(t *testing.T) {

id := uint64(2)
node := &node{Node: &conn.Node{Id: id}, ctx: context.Background(), closer: z.NewCloser(1)}
node.initProposalKey(node.Id)

pkey := proposalKey
nodeIdFromKey := proposalKey >> 48
require.Equal(t, id, nodeIdFromKey, "id extracted from proposal key is not equal to initial value")

valueOf48thBit := int(pkey & (1 << 48))
require.Equal(t, 0, valueOf48thBit, "48th bit is not set to zero on initialisation")

node.uniqueKey()
require.Equal(t, pkey+1, proposalKey, "proposal key should increment by 1 at each call of unique key")

uniqueKeys := make(map[uint64]struct{})
for i := 0; i < 10; i++ {
node.uniqueKey()
uniqueKeys[proposalKey] = struct{}{}
}
require.Equal(t, len(uniqueKeys), 10, "each iteration should create unique key")
}
2 changes: 1 addition & 1 deletion worker/draft.go
Original file line number Diff line number Diff line change
Expand Up @@ -1756,7 +1756,7 @@ func (n *node) retryUntilSuccess(fn func() error, pause time.Duration) {

// InitAndStartNode gets called after having at least one membership sync with the cluster.
func (n *node) InitAndStartNode() {
initProposalKey(n.Id)
x.Check(initProposalKey(n.Id))
_, restart, err := n.PastLife()
x.Check(err)

Expand Down
10 changes: 7 additions & 3 deletions worker/proposal.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,6 @@ import (
"github.com/dgraph-io/dgraph/protos/pb"
"github.com/dgraph-io/dgraph/schema"
"github.com/dgraph-io/dgraph/x"
"github.com/dgraph-io/ristretto/z"
)

const baseTimeout time.Duration = 4 * time.Second
Expand Down Expand Up @@ -111,9 +110,14 @@ func (rl *rateLimiter) decr(retry int) {
var proposalKey uint64

// {2 bytes Node ID} {4 bytes for random} {2 bytes zero}
func initProposalKey(id uint64) {
func initProposalKey(id uint64) error {
x.AssertTrue(id != 0)
proposalKey = uint64(groups().Node.Id)<<48 | uint64(z.FastRand())<<16
var err error
proposalKey, err = x.ProposalKey(groups().Node.Id)
if err != nil {
return err
}
return nil
}

// uniqueKey is meant to be unique across all the replicas.
Expand Down
17 changes: 17 additions & 0 deletions x/x.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,9 @@ import (
"bytes"
builtinGzip "compress/gzip"
"context"
cr "crypto/rand"
"crypto/tls"
"encoding/binary"
"encoding/json"
"fmt"
"io"
Expand Down Expand Up @@ -644,6 +646,21 @@ func RetryUntilSuccess(maxRetries int, waitAfterFailure time.Duration,
return err
}

// {2 bytes Node ID} {4 bytes for random} {2 bytes zero}
func ProposalKey(id uint64) (uint64, error) {
random4Bytes := make([]byte, 4)
if _, err := cr.Read(random4Bytes); err != nil {
return 0, err
}
proposalKey := id<<48 | uint64(binary.BigEndian.Uint32(random4Bytes))<<16
// We want to avoid spillage to node id in case of overflow. For instance, if the
// random bytes end up being [xx,xx, 255, 255, 255, 255, 0 , 0] (xx, xx being the node id)
// we would spill to node id after 65535 calls to unique key.
// So by setting 48th bit to 0 we ensure that we never spill out to node ids.
proposalKey &= ^(uint64(1) << 47)
return proposalKey, nil
}

// HasString returns whether the slice contains the given string.
func HasString(a []string, b string) bool {
for _, k := range a {
Expand Down