Skip to content

Instantly share code, notes, and snippets.

@tomask-de
Created August 18, 2023 11:57
Show Gist options
  • Select an option

  • Save tomask-de/e430cf86b7c8abb2c05d1c951d7f8e7e to your computer and use it in GitHub Desktop.

Select an option

Save tomask-de/e430cf86b7c8abb2c05d1c951d7f8e7e to your computer and use it in GitHub Desktop.
tbtest 10k/1mio
package main
import (
"fmt"
"log"
"os"
"reflect"
"time"
tb "github.com/tigerbeetle/tigerbeetle-go"
tb_types "github.com/tigerbeetle/tigerbeetle-go/pkg/types"
)
func uint128(value string) tb_types.Uint128 {
x, err := tb_types.HexStringToUint128(value)
if err != nil {
panic(err)
}
return x
}
// Since we only require Go 1.17 we can't do this as a generic function
// even though that would be fine. So do the dynamic approach for now.
func assert(a, b interface{}, field string) {
if !reflect.DeepEqual(a, b) {
log.Fatalf("Expected %s to be [%+v (%T)], got: [%+v (%T)]", field, b, b, a, a)
}
}
func main() {
port := os.Getenv("TB_ADDRESS")
if port == "" {
port = "3000"
}
client, err := tb.NewClient(0, []string{port}, 32)
if err != nil {
log.Fatalf("Error creating client: %s", err)
}
defer client.Close()
BatchSize := 8191
// Create 10k accounts
accounts := make([]tb_types.Account, 0)
for i := 1; i <= 10000; i++ {
accounts = append(accounts, tb_types.Account{
ID: uint128(fmt.Sprintf("%d", i)),
Ledger: 1,
Code: 1,
})
}
start := time.Now()
var acctRes []tb_types.AccountEventResult
for i := 0; i <= len(accounts); i += BatchSize {
batch := BatchSize
if i+BatchSize > len(accounts) {
batch = len(accounts) - i
}
log.Printf("account-batch %d-%d", i, i+batch)
acctRes, err = client.CreateAccounts(accounts[i : i+batch])
if err != nil {
log.Fatalf("Error creating accounts: %s", err)
}
for _, err := range acctRes {
log.Fatalf("Error creating account %d: %s", err.Index, err.Result)
}
}
log.Printf("create %d accounts took: %s", len(accounts), time.Since(start))
accountsRes, err := client.CreateAccounts([]tb_types.Account{
{
ID: uint128("10001"),
Ledger: 1,
Code: 1,
},
})
if err != nil {
log.Printf("Error creating accounts: %s", err)
return
}
for _, err := range accountsRes {
log.Printf("Error creating account %d: %s", err.Index, err.Result)
return
}
log.Println("created debit account")
transfers := make([]tb_types.Transfer, 0)
j := 1
for i := 1; i <= 1000000; i++ {
if i%10000 == 0 {
j = 1
}
transfers = append(transfers, tb_types.Transfer{
ID: uint128(fmt.Sprintf("%d", i)),
DebitAccountID: uint128("10001"),
CreditAccountID: uint128(fmt.Sprintf("%d", j)),
Ledger: 1,
Code: 1,
Amount: 10,
})
j++
}
log.Printf("generated %d transfers", len(transfers))
start = time.Now()
var transferRes []tb_types.TransferEventResult
for i := 0; i < len(transfers); i += BatchSize {
batch := BatchSize
if i+BatchSize > len(transfers) {
batch = len(transfers) - i
}
log.Printf("transfer-batch %d-%d", i, i+batch)
transferRes, err = client.CreateTransfers(transfers[i : i+batch])
// error handling omitted
if err != nil {
log.Fatalf("Error creating transfers: %s", err)
}
for _, err := range transferRes {
log.Printf("Error creating transfer %d: %s", err.Index, err.Result)
return
}
}
log.Printf("book 1mio transfers took: %s", time.Since(start))
// Check the sums for one custom and the counter account
accounts, err = client.LookupAccounts([]tb_types.Uint128{uint128("10001"), uint128("2")})
if err != nil {
log.Fatalf("Could not fetch accounts: %s", err)
}
assert(len(accounts), 2, "accounts")
for _, account := range accounts {
if account.ID == uint128("10001") {
assert(account.DebitsPosted, uint64(10000000), "account 10001 debits")
assert(account.CreditsPosted, uint64(0), "account 10001 credits")
} else if account.ID == uint128("2") {
assert(account.DebitsPosted, uint64(0), "account 2 debits")
assert(account.CreditsPosted, uint64(1000), "account 2 credits")
} else {
log.Fatalf("Unexpected account")
}
}
fmt.Println("ok")
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment