Skip to content

Instantly share code, notes, and snippets.

@yyforyongyu
Last active October 7, 2024 09:43
Show Gist options
  • Save yyforyongyu/fc82b46314d3ee7128dd8312182de785 to your computer and use it in GitHub Desktop.
Save yyforyongyu/fc82b46314d3ee7128dd8312182de785 to your computer and use it in GitHub Desktop.
Benchmark on `kvdb.Batch`
func TestBatchUpdate(t *testing.T) {
t.Parallel()
fullDB, err := MakeTestDB(t, OptionStoreFinalHtlcResolutions(true))
require.NoError(t, err, "unable to make test database")
cdb := fullDB.ChannelStateDB()
chanID := lnwire.ShortChannelID{
BlockHeight: 1,
TxIndex: 2,
TxPosition: 3,
}
const (
modulus = 10001
num = 100_000
)
var (
counter atomic.Uint32
numErr atomic.Uint32
)
addHtlc := func(htlcID uint64) error {
return kvdb.Batch(cdb.backend, func(tx kvdb.RwTx) error {
counter.Add(1)
bucket, err := fetchFinalHtlcsBucketRw(
tx, chanID,
)
if err != nil {
return err
}
if htlcID%modulus == 0 {
numErr.Add(1)
return fmt.Errorf("error from %d", htlcID)
}
return putFinalHtlc(bucket, htlcID, FinalHtlcInfo{
Settled: true,
Offchain: true,
})
})
}
errChan := make(chan error, num)
for i := uint64(0); i < num; i++ {
go func(i uint64) {
errChan <- addHtlc(i)
}(i)
}
for i := uint64(0); i < num; i++ {
select {
case err := <-errChan:
if err != nil {
// t.Log(err)
}
}
}
for i := uint64(0); i < num; i++ {
info, err := cdb.LookupFinalHtlc(chanID, i)
if i%modulus == 0 {
// Test unknown htlc lookup for existing channel.
require.ErrorIs(t, err, ErrHtlcUnknown)
} else {
require.NoError(t, err)
require.True(t, info.Settled)
require.True(t, info.Offchain)
}
}
t.Log("stats from NOT using updateErr")
t.Log("total records:", num)
t.Log("total errors:", num/modulus+1)
t.Log("batch updates:", counter.Load())
t.Log("updates with error:", numErr.Load())
}
func TestBatchUpdateErr(t *testing.T) {
t.Parallel()
fullDB, err := MakeTestDB(t, OptionStoreFinalHtlcResolutions(true))
require.NoError(t, err, "unable to make test database")
cdb := fullDB.ChannelStateDB()
chanID := lnwire.ShortChannelID{
BlockHeight: 1,
TxIndex: 2,
TxPosition: 3,
}
const (
modulus = 10001
num = 100_000
)
var (
counter atomic.Uint32
numErr atomic.Uint32
)
addHtlc := func(htlcID uint64) error {
var updateErr error
err := kvdb.Batch(cdb.backend, func(tx kvdb.RwTx) error {
counter.Add(1)
bucket, err := fetchFinalHtlcsBucketRw(
tx, chanID,
)
if err != nil {
return err
}
if htlcID%modulus == 0 {
numErr.Add(1)
updateErr = fmt.Errorf("error from %d", htlcID)
return nil
}
return putFinalHtlc(bucket, htlcID, FinalHtlcInfo{
Settled: true,
Offchain: true,
})
})
if err != nil {
return err
}
return updateErr
}
errChan := make(chan error, num)
for i := uint64(0); i < num; i++ {
go func(i uint64) {
errChan <- addHtlc(i)
}(i)
}
for i := uint64(0); i < num; i++ {
select {
case err := <-errChan:
if err != nil {
// t.Log(err)
}
}
}
for i := uint64(0); i < num; i++ {
info, err := cdb.LookupFinalHtlc(chanID, i)
if i%modulus == 0 {
// Test unknown htlc lookup for existing channel.
require.ErrorIs(t, err, ErrHtlcUnknown)
} else {
require.NoError(t, err)
require.True(t, info.Settled)
require.True(t, info.Offchain)
}
}
t.Log("stats from using updateErr")
t.Log("total records:", num)
t.Log("total errors:", num/modulus+1)
t.Log("batch updates:", counter.Load())
t.Log("updates with error:", numErr.Load())
}
@yyforyongyu
Copy link
Author

yyforyongyu commented Feb 8, 2023

To run it,

  1. copy the code into channeldb/channel_test.go.
  2. cd channeldb.
  3. run go test -v -run=TestBatchUpdate .

@yyforyongyu
Copy link
Author

yyforyongyu commented Feb 8, 2023

Test result,

=== RUN   TestBatchUpdate
=== PAUSE TestBatchUpdate
=== RUN   TestBatchUpdateErr
=== PAUSE TestBatchUpdateErr
=== CONT  TestBatchUpdate
=== CONT  TestBatchUpdateErr
    channel_test.go:1690: stats from using updateErr
    channel_test.go:1691: total records: 100000
    channel_test.go:1692: total errors: 10
    channel_test.go:1693: batch updates: 100000
    channel_test.go:1694: updates with error: 10
--- PASS: TestBatchUpdateErr (9.28s)
=== CONT  TestBatchUpdate
    channel_test.go:1598: stats from NOT using updateErr
    channel_test.go:1599: total records: 100000
    channel_test.go:1600: total errors: 10
    channel_test.go:1601: batch updates: 104537
    channel_test.go:1602: updates with error: 20
--- PASS: TestBatchUpdate (9.45s)
PASS

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment