Skip to content

Commit

Permalink
WIP: testing multithreaded solidification
Browse files Browse the repository at this point in the history
  • Loading branch information
karimodm committed Apr 4, 2022
1 parent 2299ade commit 3e7ae25
Show file tree
Hide file tree
Showing 7 changed files with 391 additions and 102 deletions.
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ require (
github.com/gin-gonic/gin v1.7.0
github.com/go-resty/resty/v2 v2.6.0
github.com/gorilla/websocket v1.5.0
github.com/iotaledger/hive.go v0.0.0-20220403215612-08d431c95225
github.com/iotaledger/hive.go v0.0.0-20220404122403-41e4f67ac4c1
github.com/labstack/echo v3.3.10+incompatible
github.com/labstack/gommon v0.3.0
github.com/libp2p/go-libp2p v0.15.0
Expand Down
6 changes: 6 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -539,6 +539,12 @@ github.com/iotaledger/hive.go v0.0.0-20220401233028-f652ea015d76 h1:cqo5VpUgSE/F
github.com/iotaledger/hive.go v0.0.0-20220401233028-f652ea015d76/go.mod h1:WAw2y5dTB4Z4YMjK98BL3OJJVcGj3fBgcHxoMCYLJac=
github.com/iotaledger/hive.go v0.0.0-20220403215612-08d431c95225 h1:HliGrzi7yC1lyeyXJTU9+1rK2i24ljA01ZVyU7CQn6A=
github.com/iotaledger/hive.go v0.0.0-20220403215612-08d431c95225/go.mod h1:WAw2y5dTB4Z4YMjK98BL3OJJVcGj3fBgcHxoMCYLJac=
github.com/iotaledger/hive.go v0.0.0-20220404105134-a01f4f4bd6f6 h1:SVJ8XWsAXHidRMCT616bAT3+0NuuM+cpfaYrdaNgJtQ=
github.com/iotaledger/hive.go v0.0.0-20220404105134-a01f4f4bd6f6/go.mod h1:WAw2y5dTB4Z4YMjK98BL3OJJVcGj3fBgcHxoMCYLJac=
github.com/iotaledger/hive.go v0.0.0-20220404120832-8df46debbc19 h1:gQ6IWUY64ZsafjDFMRmUXxFwlvddGmadmPlAN4/BE8U=
github.com/iotaledger/hive.go v0.0.0-20220404120832-8df46debbc19/go.mod h1:WAw2y5dTB4Z4YMjK98BL3OJJVcGj3fBgcHxoMCYLJac=
github.com/iotaledger/hive.go v0.0.0-20220404122403-41e4f67ac4c1 h1:N9voEMa7pfYoV055TzIyOEJkG2dVSx4mfX97vstPx3Y=
github.com/iotaledger/hive.go v0.0.0-20220404122403-41e4f67ac4c1/go.mod h1:WAw2y5dTB4Z4YMjK98BL3OJJVcGj3fBgcHxoMCYLJac=
github.com/ipfs/go-cid v0.0.1/go.mod h1:GHWU/WuQdMPmIosc4Yn1bcCT7dSeX4lBafM7iqUPQvM=
github.com/ipfs/go-cid v0.0.2/go.mod h1:GHWU/WuQdMPmIosc4Yn1bcCT7dSeX4lBafM7iqUPQvM=
github.com/ipfs/go-cid v0.0.3/go.mod h1:GHWU/WuQdMPmIosc4Yn1bcCT7dSeX4lBafM7iqUPQvM=
Expand Down
4 changes: 4 additions & 0 deletions packages/ledger/branchdag/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,10 @@ var MasterBranchID BranchID

const BranchIDLength = types.IdentifierLength

func init() {
MasterBranchID.RegisterAlias("MasterBranch")
}

// endregion ///////////////////////////////////////////////////////////////////////////////////////////////////////////

// region BranchIDs ////////////////////////////////////////////////////////////////////////////////////////////////////
Expand Down
1 change: 1 addition & 0 deletions packages/ledger/dataflow.go
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ func (d *dataFlow) checkTransaction() *dataflow.DataFlow[*dataFlowParams] {
func newDataFlowParams(tx *Transaction) (new *dataFlowParams) {
return &dataFlowParams{
Transaction: tx,
InputIDs: utxo.NewOutputIDs(),
}
}

Expand Down
309 changes: 309 additions & 0 deletions packages/ledger/ledger_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -375,3 +375,312 @@ func TestLedger_SetBranchConfirmed(t *testing.T) {
assert.Equal(t, branchdag.Rejected, testFramework.Ledger.BranchDAG.InclusionState(testFramework.BranchIDs("TXG", "TXH")))
}
}

func TestLedger_SolidifyMultiThreaded(t *testing.T) {
testFramework := NewTestFramework()

// Step 1: Bottom Layer
testFramework.CreateTransaction("G", 3, "Genesis")
testFramework.CreateTransaction("TXA", 1, "G.0")
testFramework.CreateTransaction("TXC", 1, "G.1")
testFramework.CreateTransaction("TXH", 1, "G.2")
// Step 2: Middle Layer
testFramework.CreateTransaction("TXE", 1, "TXA.0", "TXC.0")
// Step 4: Top Layer
testFramework.CreateTransaction("TXG", 1, "TXE.0")
// Step 5: TopTop Layer
testFramework.CreateTransaction("TXL", 1, "TXG.0", "TXH.0")
// Step 6: TopTopTOP Layer
testFramework.CreateTransaction("TXM", 1, "TXL.0")

// forks
//testFramework.CreateTransaction("TXD", 1, "G.1")
//testFramework.CreateTransaction("TXD", 1, "G.1")
//testFramework.CreateTransaction("TXI", 1, "G.2")
// Step 3: Top Layer
//testFramework.CreateTransaction("TXF", 1, "TXE.0")

// Issue first batch of Transactions
{
for _, txAlias := range []string{"G", "TXA", "TXH"} {
assert.NoError(t, testFramework.IssueTransaction(txAlias))
}

for _, txAlias := range []string{"TXE", "TXG", "TXL", "TXM"} {
assert.ErrorIs(t, testFramework.IssueTransaction(txAlias), ErrTransactionUnsolid)
}

testFramework.AssertBranchIDs(t, map[string][]string{
"G": {"MasterBranch"},
"TXA": {"MasterBranch"},
"TXH": {"MasterBranch"},
})

testFramework.AssertBooked(t, map[string]bool{
"G": true,
"TXA": true,
"TXE": false,
"TXH": true,
"TXG": false,
"TXL": false,
"TXM": false,
})
}

// A bunch of transactions should now become solid
{
assert.NoError(t, testFramework.IssueTransaction("TXC"))

testFramework.AssertBranchIDs(t, map[string][]string{
"G": {"MasterBranch"},
"TXA": {"MasterBranch"},
"TXH": {"MasterBranch"},
"TXE": {"MasterBranch"},
"TXG": {"MasterBranch"},
"TXL": {"MasterBranch"},
"TXM": {"MasterBranch"},
})

testFramework.AssertBooked(t, map[string]bool{
"G": true,
"TXA": true,
"TXE": true,
"TXH": true,
"TXG": true,
"TXL": true,
"TXM": true,
})
}

return

// Mark A as Confirmed
{
for _, txAlias := range []string{"G", "TXA", "TXB", "TXC", "TXD", "TXH", "TXI"} {
assert.NoError(t, testFramework.IssueTransaction(txAlias))
}
require.True(t, testFramework.Ledger.BranchDAG.SetBranchConfirmed(branchdag.NewBranchID(testFramework.Transaction("TXA").ID())))

testFramework.AssertBranchIDs(t, map[string][]string{
"G": {"MasterBranch"},
"TXA": {"TXA"},
"TXB": {"TXB"},
"TXC": {"TXC"},
"TXD": {"TXD"},
"TXH": {"TXH"},
"TXI": {"TXI"},
})

testFramework.AssertBranchDAG(t, map[string][]string{
"TXA": {"MasterBranch"},
"TXB": {"MasterBranch"},
"TXC": {"MasterBranch"},
"TXD": {"MasterBranch"},
"TXH": {"MasterBranch"},
"TXI": {"MasterBranch"},
})

assert.Equal(t, branchdag.Confirmed, testFramework.Ledger.BranchDAG.InclusionState(testFramework.BranchIDs("TXA")))
assert.Equal(t, branchdag.Rejected, testFramework.Ledger.BranchDAG.InclusionState(testFramework.BranchIDs("TXB")))
assert.Equal(t, branchdag.Pending, testFramework.Ledger.BranchDAG.InclusionState(testFramework.BranchIDs("TXC")))
assert.Equal(t, branchdag.Pending, testFramework.Ledger.BranchDAG.InclusionState(testFramework.BranchIDs("TXD")))
assert.Equal(t, branchdag.Pending, testFramework.Ledger.BranchDAG.InclusionState(testFramework.BranchIDs("TXH")))
assert.Equal(t, branchdag.Pending, testFramework.Ledger.BranchDAG.InclusionState(testFramework.BranchIDs("TXI")))
}

// When creating the middle layer the new transaction E should be booked only under its Pending parent C
{
assert.NoError(t, testFramework.IssueTransaction("TXE"))

testFramework.AssertBranchIDs(t, map[string][]string{
"G": {"MasterBranch"},
"TXA": {"TXA"},
"TXB": {"TXB"},
"TXC": {"TXC"},
"TXD": {"TXD"},
"TXH": {"TXH"},
"TXI": {"TXI"},
"TXE": {"TXC"},
})

testFramework.AssertBranchDAG(t, map[string][]string{
"TXA": {"MasterBranch"},
"TXB": {"MasterBranch"},
"TXC": {"MasterBranch"},
"TXD": {"MasterBranch"},
"TXH": {"MasterBranch"},
"TXI": {"MasterBranch"},
})

assert.Equal(t, branchdag.Confirmed, testFramework.Ledger.BranchDAG.InclusionState(testFramework.BranchIDs("TXA")))
assert.Equal(t, branchdag.Rejected, testFramework.Ledger.BranchDAG.InclusionState(testFramework.BranchIDs("TXB")))
assert.Equal(t, branchdag.Pending, testFramework.Ledger.BranchDAG.InclusionState(testFramework.BranchIDs("TXC")))
assert.Equal(t, branchdag.Pending, testFramework.Ledger.BranchDAG.InclusionState(testFramework.BranchIDs("TXD")))
assert.Equal(t, branchdag.Pending, testFramework.Ledger.BranchDAG.InclusionState(testFramework.BranchIDs("TXH")))
assert.Equal(t, branchdag.Pending, testFramework.Ledger.BranchDAG.InclusionState(testFramework.BranchIDs("TXI")))
}

// When creating the first transaction (F) of top layer it should be booked under the Pending parent C
{
for _, txAlias := range []string{"TXF"} {
assert.NoError(t, testFramework.IssueTransaction(txAlias))
}

testFramework.AssertBranchIDs(t, map[string][]string{
"G": {"MasterBranch"},
"TXA": {"TXA"},
"TXB": {"TXB"},
"TXC": {"TXC"},
"TXD": {"TXD"},
"TXH": {"TXH"},
"TXI": {"TXI"},
// Branches F & G are spawned by the fork of G
"TXF": {"TXC"},
})

testFramework.AssertBranchDAG(t, map[string][]string{
"TXA": {"MasterBranch"},
"TXB": {"MasterBranch"},
"TXC": {"MasterBranch"},
"TXD": {"MasterBranch"},
"TXH": {"MasterBranch"},
"TXI": {"MasterBranch"},
})

assert.Equal(t, branchdag.Confirmed, testFramework.Ledger.BranchDAG.InclusionState(testFramework.BranchIDs("TXA")))
assert.Equal(t, branchdag.Rejected, testFramework.Ledger.BranchDAG.InclusionState(testFramework.BranchIDs("TXB")))
assert.Equal(t, branchdag.Pending, testFramework.Ledger.BranchDAG.InclusionState(testFramework.BranchIDs("TXC")))
assert.Equal(t, branchdag.Pending, testFramework.Ledger.BranchDAG.InclusionState(testFramework.BranchIDs("TXD")))
assert.Equal(t, branchdag.Pending, testFramework.Ledger.BranchDAG.InclusionState(testFramework.BranchIDs("TXH")))
assert.Equal(t, branchdag.Pending, testFramework.Ledger.BranchDAG.InclusionState(testFramework.BranchIDs("TXI")))
}

// When creating the conflicting TX (G) of the top layer branches F & G are spawned by the fork of G
{
for _, txAlias := range []string{"TXG"} {
assert.NoError(t, testFramework.IssueTransaction(txAlias))
}

testFramework.AssertBranchIDs(t, map[string][]string{
"G": {"MasterBranch"},
"TXA": {"TXA"},
"TXB": {"TXB"},
"TXC": {"TXC"},
"TXD": {"TXD"},
"TXH": {"TXH"},
"TXI": {"TXI"},
// Branches F & G are spawned by the fork of G
"TXF": {"TXF"},
"TXG": {"TXG"},
})

testFramework.AssertBranchDAG(t, map[string][]string{
"TXA": {"MasterBranch"},
"TXB": {"MasterBranch"},
"TXC": {"MasterBranch"},
"TXD": {"MasterBranch"},
"TXH": {"MasterBranch"},
"TXI": {"MasterBranch"},
"TXF": {"TXC"},
"TXG": {"TXC"},
})

assert.Equal(t, branchdag.Confirmed, testFramework.Ledger.BranchDAG.InclusionState(testFramework.BranchIDs("TXA")))
assert.Equal(t, branchdag.Rejected, testFramework.Ledger.BranchDAG.InclusionState(testFramework.BranchIDs("TXB")))
assert.Equal(t, branchdag.Pending, testFramework.Ledger.BranchDAG.InclusionState(testFramework.BranchIDs("TXC")))
assert.Equal(t, branchdag.Pending, testFramework.Ledger.BranchDAG.InclusionState(testFramework.BranchIDs("TXD")))
assert.Equal(t, branchdag.Pending, testFramework.Ledger.BranchDAG.InclusionState(testFramework.BranchIDs("TXH")))
assert.Equal(t, branchdag.Pending, testFramework.Ledger.BranchDAG.InclusionState(testFramework.BranchIDs("TXI")))
assert.Equal(t, branchdag.Pending, testFramework.Ledger.BranchDAG.InclusionState(testFramework.BranchIDs("TXF")))
assert.Equal(t, branchdag.Pending, testFramework.Ledger.BranchDAG.InclusionState(testFramework.BranchIDs("TXG")))
}

require.True(t, testFramework.Ledger.BranchDAG.SetBranchConfirmed(branchdag.NewBranchID(testFramework.Transaction("TXD").ID())))

// TX L combines a child (G) of a Rejected branch (C) and a pending branch H, resulting in (G,H)
{
for _, txAlias := range []string{"TXL"} {
assert.NoError(t, testFramework.IssueTransaction(txAlias))
}

testFramework.AssertBranchIDs(t, map[string][]string{
"G": {"MasterBranch"},
"TXA": {"TXA"},
"TXB": {"TXB"},
"TXC": {"TXC"},
"TXD": {"TXD"},
"TXH": {"TXH"},
"TXI": {"TXI"},
// Branches F & G are spawned by the fork of G
"TXF": {"TXF"},
"TXG": {"TXG"},
"TXL": {"TXG", "TXH"},
})

testFramework.AssertBranchDAG(t, map[string][]string{
"TXA": {"MasterBranch"},
"TXB": {"MasterBranch"},
"TXC": {"MasterBranch"},
"TXD": {"MasterBranch"},
"TXH": {"MasterBranch"},
"TXI": {"MasterBranch"},
"TXF": {"TXC"},
"TXG": {"TXC"},
})

assert.Equal(t, branchdag.Confirmed, testFramework.Ledger.BranchDAG.InclusionState(testFramework.BranchIDs("TXA")))
assert.Equal(t, branchdag.Rejected, testFramework.Ledger.BranchDAG.InclusionState(testFramework.BranchIDs("TXB")))
assert.Equal(t, branchdag.Rejected, testFramework.Ledger.BranchDAG.InclusionState(testFramework.BranchIDs("TXC")))
assert.Equal(t, branchdag.Confirmed, testFramework.Ledger.BranchDAG.InclusionState(testFramework.BranchIDs("TXD")))
assert.Equal(t, branchdag.Pending, testFramework.Ledger.BranchDAG.InclusionState(testFramework.BranchIDs("TXH")))
assert.Equal(t, branchdag.Pending, testFramework.Ledger.BranchDAG.InclusionState(testFramework.BranchIDs("TXI")))
assert.Equal(t, branchdag.Rejected, testFramework.Ledger.BranchDAG.InclusionState(testFramework.BranchIDs("TXF")))
assert.Equal(t, branchdag.Rejected, testFramework.Ledger.BranchDAG.InclusionState(testFramework.BranchIDs("TXG")))
assert.Equal(t, branchdag.Rejected, testFramework.Ledger.BranchDAG.InclusionState(testFramework.BranchIDs("TXG", "TXH")))
}

require.True(t, testFramework.Ledger.BranchDAG.SetBranchConfirmed(branchdag.NewBranchID(testFramework.Transaction("TXH").ID())))

// The new TX M should be now booked under G, as branch H confirmed, just G because we don't propagate H further.
{
for _, txAlias := range []string{"TXM"} {
assert.NoError(t, testFramework.IssueTransaction(txAlias))
}

testFramework.AssertBranchIDs(t, map[string][]string{
"G": {"MasterBranch"},
"TXA": {"TXA"},
"TXB": {"TXB"},
"TXC": {"TXC"},
"TXD": {"TXD"},
"TXH": {"TXH"},
"TXI": {"TXI"},
// Branches F & G are spawned by the fork of G
"TXF": {"TXF"},
"TXG": {"TXG"},
"TXL": {"TXG", "TXH"},
"TXM": {"TXG"},
})

testFramework.AssertBranchDAG(t, map[string][]string{
"TXA": {"MasterBranch"},
"TXB": {"MasterBranch"},
"TXC": {"MasterBranch"},
"TXD": {"MasterBranch"},
"TXH": {"MasterBranch"},
"TXI": {"MasterBranch"},
"TXF": {"TXC"},
"TXG": {"TXC"},
})

assert.Equal(t, branchdag.Confirmed, testFramework.Ledger.BranchDAG.InclusionState(testFramework.BranchIDs("TXA")))
assert.Equal(t, branchdag.Rejected, testFramework.Ledger.BranchDAG.InclusionState(testFramework.BranchIDs("TXB")))
assert.Equal(t, branchdag.Rejected, testFramework.Ledger.BranchDAG.InclusionState(testFramework.BranchIDs("TXC")))
assert.Equal(t, branchdag.Confirmed, testFramework.Ledger.BranchDAG.InclusionState(testFramework.BranchIDs("TXD")))
assert.Equal(t, branchdag.Confirmed, testFramework.Ledger.BranchDAG.InclusionState(testFramework.BranchIDs("TXH")))
assert.Equal(t, branchdag.Rejected, testFramework.Ledger.BranchDAG.InclusionState(testFramework.BranchIDs("TXI")))
assert.Equal(t, branchdag.Rejected, testFramework.Ledger.BranchDAG.InclusionState(testFramework.BranchIDs("TXF")))
assert.Equal(t, branchdag.Rejected, testFramework.Ledger.BranchDAG.InclusionState(testFramework.BranchIDs("TXG")))
assert.Equal(t, branchdag.Rejected, testFramework.Ledger.BranchDAG.InclusionState(testFramework.BranchIDs("TXG", "TXH")))
}
}
Loading

0 comments on commit 3e7ae25

Please sign in to comment.