Skip to content

Commit 8612d2b

Browse files
committed
tapdb: add TestBindDanglingUpdatesToTransition test
1 parent 121f10f commit 8612d2b

1 file changed

Lines changed: 110 additions & 0 deletions

File tree

tapdb/supply_commit_test.go

Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1223,6 +1223,113 @@ func TestSupplyCommitInsertPendingUpdate(t *testing.T) {
12231223
assertEqualEvents(t, event3, deserializedDangling)
12241224
}
12251225

1226+
// TestBindDanglingUpdatesToTransition tests the logic for binding dangling
1227+
// updates to a new transition.
1228+
func TestBindDanglingUpdatesToTransition(t *testing.T) {
1229+
t.Parallel()
1230+
1231+
h := newSupplyCommitTestHarness(t)
1232+
1233+
// If no dangling updates exist, the method should be a no-op.
1234+
boundEvents, err := h.commitMachine.BindDanglingUpdatesToTransition(
1235+
h.ctx, h.assetSpec,
1236+
)
1237+
require.NoError(t, err)
1238+
require.Empty(t, boundEvents)
1239+
h.assertNoPendingTransition()
1240+
1241+
// To create dangling updates, we first need a state machine and a
1242+
// finalized transition.
1243+
updates1 := []supplycommit.SupplyUpdateEvent{h.randMintEvent()}
1244+
stateTransition1 := h.performSingleTransition(updates1)
1245+
h.assertTransitionApplied(stateTransition1)
1246+
1247+
// Now, with the machine in DefaultState, we'll manually insert some
1248+
// dangling events into the DB. This simulates events arriving while a
1249+
// transition was in flight and frozen.
1250+
danglingEvent1 := h.randBurnEvent()
1251+
danglingEvent2 := h.randIgnoreEvent()
1252+
danglingEventsToInsert := []supplycommit.SupplyUpdateEvent{
1253+
danglingEvent1, danglingEvent2,
1254+
}
1255+
1256+
// We use a custom transaction to short circuit some of the logic in the
1257+
// public API.
1258+
var writeTx SupplyCommitTxOptions
1259+
err = h.commitMachine.db.ExecTx(
1260+
h.ctx, &writeTx, func(db SupplyCommitStore) error {
1261+
for _, event := range danglingEventsToInsert {
1262+
var b bytes.Buffer
1263+
err := serializeSupplyUpdateEvent(&b, event)
1264+
require.NoError(t, err)
1265+
updateTypeID, err := updateTypeToInt(
1266+
event.SupplySubTreeType(),
1267+
)
1268+
require.NoError(t, err)
1269+
1270+
err = db.InsertSupplyUpdateEvent(
1271+
h.ctx, InsertSupplyUpdateEvent{
1272+
GroupKey: h.groupKeyBytes,
1273+
TransitionID: sql.NullInt64{},
1274+
UpdateTypeID: updateTypeID,
1275+
EventData: b.Bytes(),
1276+
},
1277+
)
1278+
require.NoError(t, err)
1279+
}
1280+
1281+
return nil
1282+
},
1283+
)
1284+
require.NoError(t, err)
1285+
1286+
// We should now that that updates are properly dangling.
1287+
require.Len(t, h.fetchDanglingUpdates(), 2)
1288+
1289+
// Now we'll bind the set of dangling updates, this should create a new
1290+
// state transition and associate the events with it.
1291+
boundEvents, err = h.commitMachine.BindDanglingUpdatesToTransition(
1292+
h.ctx, h.assetSpec,
1293+
)
1294+
require.NoError(t, err)
1295+
1296+
// Assert that the returned events match what we inserted. We'll sort
1297+
// first to ensure a deterministic comparison.
1298+
sorter := func(events []supplycommit.SupplyUpdateEvent) {
1299+
sort.SliceStable(events, func(i, j int) bool {
1300+
keyI := events[i].UniverseLeafKey().UniverseKey()
1301+
keyJ := events[j].UniverseLeafKey().UniverseKey()
1302+
return bytes.Compare(keyI[:], keyJ[:]) < 0
1303+
})
1304+
}
1305+
sorter(danglingEventsToInsert)
1306+
sorter(boundEvents)
1307+
require.Len(t, boundEvents, 2)
1308+
1309+
// The dangling events read out should now match what we inserted.
1310+
assertEqualEvents(t, danglingEventsToInsert[0], boundEvents[0])
1311+
assertEqualEvents(t, danglingEventsToInsert[1], boundEvents[1])
1312+
1313+
// A new state transition should have been created, and there should be
1314+
// no dangling updates.
1315+
dbTransition := h.assertPendingTransitionExists()
1316+
require.Empty(t, h.fetchDanglingUpdates())
1317+
1318+
// The state transition should also now include the set of dangling
1319+
// updates.
1320+
h.assertPendingUpdates(danglingEventsToInsert)
1321+
1322+
// The new transition's old_commitment_id should point to the one from
1323+
// the finalized transition.
1324+
stateMachine, err := h.fetchStateMachine()
1325+
require.NoError(t, err)
1326+
require.True(t, stateMachine.LatestCommitmentID.Valid)
1327+
require.Equal(
1328+
t, stateMachine.LatestCommitmentID,
1329+
dbTransition.OldCommitmentID,
1330+
)
1331+
}
1332+
12261333
// TestSupplyCommitInsertSignedCommitTx tests associating a signed commit tx
12271334
// with a transition.
12281335
func TestSupplyCommitInsertSignedCommitTx(t *testing.T) {
@@ -1819,10 +1926,13 @@ func encodeTx(tx *wire.MsgTx) ([]byte, error) {
18191926
// comparing the resulting bytes.
18201927
func assertEqualEvents(t *testing.T, expected, actual supplycommit.SupplyUpdateEvent) {
18211928
t.Helper()
1929+
18221930
var expectedBytes, actualBytes bytes.Buffer
18231931
err := serializeSupplyUpdateEvent(&expectedBytes, expected)
18241932
require.NoError(t, err)
1933+
18251934
err = serializeSupplyUpdateEvent(&actualBytes, actual)
18261935
require.NoError(t, err)
1936+
18271937
require.Equal(t, expectedBytes.String(), actualBytes.String())
18281938
}

0 commit comments

Comments
 (0)