wtdb+wtclient: segregate session-key-index reservations by blob-type
This commit introduces a change in the key format used to reserve/lookup session-key-indexes. Currently the reservations are stored under the tower id, however this creates issues when multiple clients are using the same database since only one reservation is permitted per tower. We fix this by appending the blob type to the session-key-index locator. This allows multiple clients to reserve keys for the same tower, but still limits each client to one outstanding reservation. The changes are made in a way such that we fall back to the legacy format if the a reservation under the new format is not found, but only if the blob type matches blob.TypeAltruistCommit, which is so far the only actively deployed blob type.
This commit is contained in:
5 files changed
+161
-39
No files matched your search
@@ -60,10 +60,12 @@ func (h *clientDBHarness) listSessions(id *wtdb.TowerID) map[wtdb.SessionID]*wtd
|
||||
return sessions
|
||||
}
|
||||
|
||||
func (h *clientDBHarness) nextKeyIndex(id wtdb.TowerID, expErr error) uint32 {
|
||||
func (h *clientDBHarness) nextKeyIndex(id wtdb.TowerID, blobType blob.Type,
|
||||
expErr error) uint32 {
|
||||
|
||||
h.t.Helper()
|
||||
|
||||
index, err := h.db.NextSessionKeyIndex(id)
|
||||
index, err := h.db.NextSessionKeyIndex(id, blobType)
|
||||
if err != expErr {
|
||||
h.t.Fatalf("expected next session key index error: %v, got: %v",
|
||||
expErr, err)
|
||||
@@ -227,11 +229,16 @@ func (h *clientDBHarness) ackUpdate(id *wtdb.SessionID, seqNum uint16,
|
||||
// - client sessions cannot be created with an incorrect session key index .
|
||||
// - inserting duplicate sessions fails.
|
||||
func testCreateClientSession(h *clientDBHarness) {
|
||||
const blobType = blob.TypeAltruistCommit
|
||||
|
||||
// Create a test client session to insert.
|
||||
session := &wtdb.ClientSession{
|
||||
ClientSessionBody: wtdb.ClientSessionBody{
|
||||
TowerID: wtdb.TowerID(3),
|
||||
Policy: wtpolicy.Policy{
|
||||
TxPolicy: wtpolicy.TxPolicy{
|
||||
BlobType: blobType,
|
||||
},
|
||||
MaxUpdates: 100,
|
||||
},
|
||||
RewardPkScript: []byte{0x01, 0x02, 0x03},
|
||||
@@ -250,7 +257,7 @@ func testCreateClientSession(h *clientDBHarness) {
|
||||
h.insertSession(session, wtdb.ErrNoReservedKeyIndex)
|
||||
|
||||
// Now, reserve a session key for this tower.
|
||||
keyIndex := h.nextKeyIndex(session.TowerID, nil)
|
||||
keyIndex := h.nextKeyIndex(session.TowerID, blobType, nil)
|
||||
|
||||
// The client session hasn't been updated with the reserved key index
|
||||
// (since it's still zero). Inserting should fail due to the mismatch.
|
||||
@@ -259,7 +266,7 @@ func testCreateClientSession(h *clientDBHarness) {
|
||||
// Reserve another key for the same index. Since no session has been
|
||||
// successfully created, it should return the same index to maintain
|
||||
// idempotency across restarts.
|
||||
keyIndex2 := h.nextKeyIndex(session.TowerID, nil)
|
||||
keyIndex2 := h.nextKeyIndex(session.TowerID, blobType, nil)
|
||||
if keyIndex != keyIndex2 {
|
||||
h.t.Fatalf("next key index should be idempotent: want: %v, "+
|
||||
"got %v", keyIndex, keyIndex2)
|
||||
@@ -281,7 +288,7 @@ func testCreateClientSession(h *clientDBHarness) {
|
||||
|
||||
// Finally, assert that reserving another key index succeeds with a
|
||||
// different key index, now that the first one has been finalized.
|
||||
keyIndex3 := h.nextKeyIndex(session.TowerID, nil)
|
||||
keyIndex3 := h.nextKeyIndex(session.TowerID, blobType, nil)
|
||||
if keyIndex == keyIndex3 {
|
||||
h.t.Fatalf("key index still reserved after creating session")
|
||||
}
|
||||
@@ -293,18 +300,22 @@ func testFilterClientSessions(h *clientDBHarness) {
|
||||
// We'll create three client sessions, the first two belonging to one
|
||||
// tower, and the last belonging to another one.
|
||||
const numSessions = 3
|
||||
const blobType = blob.TypeAltruistCommit
|
||||
towerSessions := make(map[wtdb.TowerID][]wtdb.SessionID)
|
||||
for i := 0; i < numSessions; i++ {
|
||||
towerID := wtdb.TowerID(1)
|
||||
if i == numSessions-1 {
|
||||
towerID = wtdb.TowerID(2)
|
||||
}
|
||||
keyIndex := h.nextKeyIndex(towerID, nil)
|
||||
keyIndex := h.nextKeyIndex(towerID, blobType, nil)
|
||||
sessionID := wtdb.SessionID([33]byte{byte(i)})
|
||||
h.insertSession(&wtdb.ClientSession{
|
||||
ClientSessionBody: wtdb.ClientSessionBody{
|
||||
TowerID: towerID,
|
||||
Policy: wtpolicy.Policy{
|
||||
TxPolicy: wtpolicy.TxPolicy{
|
||||
BlobType: blobType,
|
||||
},
|
||||
MaxUpdates: 100,
|
||||
},
|
||||
RewardPkScript: []byte{0x01, 0x02, 0x03},
|
||||
@@ -458,14 +469,18 @@ func testRemoveTower(h *clientDBHarness) {
|
||||
Address: addr1,
|
||||
}, nil)
|
||||
|
||||
const blobType = blob.TypeAltruistCommit
|
||||
session := &wtdb.ClientSession{
|
||||
ClientSessionBody: wtdb.ClientSessionBody{
|
||||
TowerID: tower.ID,
|
||||
Policy: wtpolicy.Policy{
|
||||
TxPolicy: wtpolicy.TxPolicy{
|
||||
BlobType: blobType,
|
||||
},
|
||||
MaxUpdates: 100,
|
||||
},
|
||||
RewardPkScript: []byte{0x01, 0x02, 0x03},
|
||||
KeyIndex: h.nextKeyIndex(tower.ID, nil),
|
||||
KeyIndex: h.nextKeyIndex(tower.ID, blobType, nil),
|
||||
},
|
||||
ID: wtdb.SessionID([33]byte{0x01}),
|
||||
}
|
||||
@@ -525,10 +540,14 @@ func testChanSummaries(h *clientDBHarness) {
|
||||
|
||||
// testCommitUpdate tests the behavior of CommitUpdate, ensuring that they can
|
||||
func testCommitUpdate(h *clientDBHarness) {
|
||||
const blobType = blob.TypeAltruistCommit
|
||||
session := &wtdb.ClientSession{
|
||||
ClientSessionBody: wtdb.ClientSessionBody{
|
||||
TowerID: wtdb.TowerID(3),
|
||||
Policy: wtpolicy.Policy{
|
||||
TxPolicy: wtpolicy.TxPolicy{
|
||||
BlobType: blobType,
|
||||
},
|
||||
MaxUpdates: 100,
|
||||
},
|
||||
RewardPkScript: []byte{0x01, 0x02, 0x03},
|
||||
@@ -542,7 +561,7 @@ func testCommitUpdate(h *clientDBHarness) {
|
||||
h.commitUpdate(&session.ID, update1, wtdb.ErrClientSessionNotFound)
|
||||
|
||||
// Reserve a session key index and insert the session.
|
||||
session.KeyIndex = h.nextKeyIndex(session.TowerID, nil)
|
||||
session.KeyIndex = h.nextKeyIndex(session.TowerID, blobType, nil)
|
||||
h.insertSession(session, nil)
|
||||
|
||||
// Now, try to commit the update that failed initially which should
|
||||
@@ -620,11 +639,16 @@ func testCommitUpdate(h *clientDBHarness) {
|
||||
|
||||
// testAckUpdate asserts the behavior of AckUpdate.
|
||||
func testAckUpdate(h *clientDBHarness) {
|
||||
const blobType = blob.TypeAltruistCommit
|
||||
|
||||
// Create a new session that the updates in this will be tied to.
|
||||
session := &wtdb.ClientSession{
|
||||
ClientSessionBody: wtdb.ClientSessionBody{
|
||||
TowerID: wtdb.TowerID(3),
|
||||
Policy: wtpolicy.Policy{
|
||||
TxPolicy: wtpolicy.TxPolicy{
|
||||
BlobType: blobType,
|
||||
},
|
||||
MaxUpdates: 100,
|
||||
},
|
||||
RewardPkScript: []byte{0x01, 0x02, 0x03},
|
||||
@@ -637,7 +661,7 @@ func testAckUpdate(h *clientDBHarness) {
|
||||
h.ackUpdate(&session.ID, 1, 0, wtdb.ErrClientSessionNotFound)
|
||||
|
||||
// Reserve a session key and insert the client session.
|
||||
session.KeyIndex = h.nextKeyIndex(session.TowerID, nil)
|
||||
session.KeyIndex = h.nextKeyIndex(session.TowerID, blobType, nil)
|
||||
h.insertSession(session, nil)
|
||||
|
||||
// Now, try to ack update 1. This should fail since update 1 was never
|
||||
|
||||
Reference in new issue
Block a user