Skip to content

Commit

Permalink
squashme
Browse files Browse the repository at this point in the history
  • Loading branch information
ClaytonNorthey92 committed Jan 14, 2025
1 parent d6778c2 commit 1cd1bbd
Show file tree
Hide file tree
Showing 4 changed files with 149 additions and 519 deletions.
3 changes: 2 additions & 1 deletion database/bfgd/database.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,10 @@ type Database interface {

// Btc block table
BtcBlockInsert(ctx context.Context, bb *BtcBlock) error
BtcBlockReplace(ctx context.Context, btcBlock *BtcBlock) (int64, error)
BtcBlockByHash(ctx context.Context, hash [32]byte) (*BtcBlock, error)
BtcBlockHeightByHash(ctx context.Context, hash [32]byte) (uint64, error)
BtcBlocksHeightsWithNoChildren(ctx context.Context) ([]uint64, error)
BtcBlockByHeight(ctx context.Context, height uint32) (*BtcBlock, error)

// Pop data
PopBasisByL2KeystoneAbrevHash(ctx context.Context, aHash [32]byte, excludeUnconfirmed bool, page uint32) ([]PopBasis, error)
Expand Down
365 changes: 1 addition & 364 deletions database/bfgd/database_ext_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ func createTestDB(ctx context.Context, t *testing.T) (bfgd.Database, *sql.DB, fu
t.Fatalf("Failed to connect to database: %v", err)
}

dbn := mathrand.IntN(9999)
dbn := mathrand.IntN(999999999)
dbName := fmt.Sprintf("%v_%d", testDBPrefix, dbn)

t.Logf("Creating test database %v", dbName)
Expand Down Expand Up @@ -1408,207 +1408,6 @@ func TestPopBasisUpdateOneExistsWithNullBTCFields(t *testing.T) {
}
}

func TestBtcBlockGetCanonicalChain(t *testing.T) {
type testTableItem struct {
name string
onChainCount int
offChainCount int
}

testTable := []testTableItem{
{
name: "2 on, 1 off",
onChainCount: 2,
offChainCount: 1,
},
{
name: "1 on, 2 off",
onChainCount: 1,
offChainCount: 2,
},
{
name: "100 on, 99 off",
onChainCount: 100,
offChainCount: 99,
},
}

for _, tti := range testTable {
t.Run(tti.name, func(t *testing.T) {
ctx, cancel := defaultTestContext()
defer cancel()

db, sdb, cleanup := createTestDB(ctx, t)
defer func() {
db.Close()
sdb.Close()
cleanup()
}()

height := 1
l2BlockNumber := uint32(9999)

onChainBlocks := []bfgd.BtcBlock{}

// create off-chain blocks
offChainBlocks := createBtcBlocksAtStartingHeight(ctx, t, db, tti.offChainCount, false, height, []byte{}, l2BlockNumber)
if len(offChainBlocks) != tti.offChainCount {
t.Fatalf("created an incorrect number of on-chain blocks %d",
len(offChainBlocks),
)
}

height += 10000
l2BlockNumber += 1000
// create on-chain blocks
onChainBlocks = createBtcBlocksAtStartingHeight(ctx, t, db, tti.onChainCount, true, height, []byte{}, l2BlockNumber)

limit := tti.onChainCount

bfs, err := db.L2BTCFinalityMostRecent(ctx, uint32(limit))
if err != nil {
t.Fatal(err)
}

if len(bfs) > limit {
t.Fatalf("bfs too long %d", len(bfs))
}

slices.Reverse(onChainBlocks)

for i, block := range onChainBlocks {
if i == limit {
break
}
found := false
for k, v := range bfs {
if slices.Equal(block.Hash, v.BTCPubHeaderHash) == true {
t.Logf("found hash in result set: %s", block.Hash)
found = true
if k < len(bfs)-1 {
t.Logf("next has is %s", bfs[k+1].BTCPubHeaderHash)
}
}
}
if found == false {
t.Fatalf("could not find hash in result set: %s", block.Hash)
}
}

for _, block := range offChainBlocks {
found := false
for _, v := range bfs {
if slices.Equal(block.Hash, v.BTCPubHeaderHash) == true {
t.Logf("found hash in result set: %s", block.Hash)
found = true
}
}
if found == true {
t.Fatalf("hash should not have been included in result set: %s", block.Hash)
}
}
})
}
}

func TestBtcBlockGetCanonicalChainWithForks(t *testing.T) {
type testTableItem struct {
name string
chainPattern []int
unconfirmedIndices []bool
}

testTable := []testTableItem{
{
name: "fork at tip",
chainPattern: []int{1, 1, 2},
unconfirmedIndices: []bool{false, false, false, false},
},
{
name: "fork in middle",
chainPattern: []int{1, 2, 1},
unconfirmedIndices: []bool{false, false, false, false},
},
{
name: "fork in beginning",
chainPattern: []int{2, 1, 1},
unconfirmedIndices: []bool{false, false, false, false},
},
{
name: "fork in beginning with break",
chainPattern: []int{2, 1, 1, 1},
unconfirmedIndices: []bool{false, false, true, false},
},
{
name: "fork in beginning with multiple breaks",
chainPattern: []int{2, 1, 1, 1, 1},
unconfirmedIndices: []bool{false, true, false, true, false},
},
}

for _, tti := range testTable {
t.Run(tti.name, func(t *testing.T) {
ctx, cancel := defaultTestContext()
defer cancel()

db, sdb, cleanup := createTestDB(ctx, t)
defer func() {
db.Close()
sdb.Close()
cleanup()
}()

height := 1

onChainBlocks := []bfgd.BtcBlock{}

l2BlockNumber := uint32(1000)
lastHash := []byte{}
for i, blockCountAtHeight := range tti.chainPattern {
onChainBlocksTmp := createBtcBlocksAtStaticHeight(ctx, t, db, blockCountAtHeight, true, height, lastHash, l2BlockNumber)
l2BlockNumber++
height++
lastHash = onChainBlocksTmp[0].Hash

if (blockCountAtHeight > 1 && i == len(tti.chainPattern)-1) == false {
onChainBlocks = append(onChainBlocks, onChainBlocksTmp[0])
}
}

rows, err := sdb.QueryContext(ctx, `
SELECT hash FROM btc_blocks_can ORDER BY height DESC
`)
if err != nil {
t.Fatal(err)
}

defer rows.Close()

hashes := []database.ByteArray{}

for rows.Next() {
var hash database.ByteArray
if err := rows.Scan(&hash); err != nil {
t.Fatal(err)
}
hashes = append(hashes, hash)
}

if len(onChainBlocks) != len(hashes) {
t.Fatalf("length of onChainBlocks and pbs differs %d != %d", len(onChainBlocks), len(hashes))
}

slices.Reverse(onChainBlocks)

for i := range onChainBlocks {
if slices.Equal(onChainBlocks[i].Hash, hashes[i]) == false {
t.Fatalf("hash mismatch: %s != %s", onChainBlocks[i].Hash, hashes[i])
}
}
})
}
}

func TestPublications(t *testing.T) {
type testTableItem struct {
name string
Expand Down Expand Up @@ -1752,168 +1551,6 @@ func TestL2BtcFinalitiesByL2KeystoneNotPublishedHeight(t *testing.T) {
}
}

func TestBtcHeightsNoChildren(t *testing.T) {
type testTableItem struct {
name string
numberToCreateWithChildren int
numberToCreateWithNoChildren int
overlapCount int
}

testTable := []testTableItem{
{
name: "0",
numberToCreateWithNoChildren: 0,
numberToCreateWithChildren: 43,
},
{
name: "less than 100",
numberToCreateWithNoChildren: 76,
numberToCreateWithChildren: 4,
},
{
name: "more than 100",
numberToCreateWithNoChildren: 126,
numberToCreateWithChildren: 333,
},
{
name: "more than 100 and overlap",
numberToCreateWithNoChildren: 126,
numberToCreateWithChildren: 333,
overlapCount: 98,
},
}

createBlocksWithNoChildren := func(ctx context.Context, count int, db bfgd.Database) []int64 {
heights := make([]int64, count)
for i := range count {
height := mathrand.Int64()
hash := make([]byte, 32)
if _, err := rand.Read(hash); err != nil {
t.Fatal(err)
}
header := make([]byte, 80)
if _, err := rand.Read(header); err != nil {
t.Fatal(err)
}

btcBlock := bfgd.BtcBlock{
Height: uint64(height),
Hash: hash,
Header: header,
}

if err := db.BtcBlockInsert(ctx, &btcBlock); err != nil {
t.Fatal(err)
}

heights[i] = height
}

return heights
}

createBlocksWithChildren := func(ctx context.Context, count int, db bfgd.Database, avoidHeights []int64, overlapHeights []int64) []int64 {
var prevHash []byte
overlapHeightI := 0
heights := make([]int64, count)
for i := range count {
var height int64
for {
if overlapHeightI < len(overlapHeights) {
height = overlapHeights[overlapHeightI]
overlapHeightI++
break
}

height = mathrand.Int64()
if !slices.Contains(avoidHeights, height) {
break
}
}
hash := make([]byte, 32)
if _, err := rand.Read(hash); err != nil {
t.Fatal(err)
}
header := make([]byte, 80)
if _, err := rand.Read(header); err != nil {
t.Fatal(err)
}

if len(prevHash) > 0 {
for k := range 32 {
header[k+4] = prevHash[k]
}
}

btcBlock := bfgd.BtcBlock{
Height: uint64(height),
Hash: hash,
Header: header,
}

if err := db.BtcBlockInsert(ctx, &btcBlock); err != nil {
t.Fatal(err)
}
prevHash = hash
heights[i] = height
}
return heights
}

for _, tti := range testTable {
t.Run(tti.name, func(t *testing.T) {
ctx, cancel := defaultTestContext()
defer cancel()

db, sdb, cleanup := createTestDB(ctx, t)
defer func() {
db.Close()
sdb.Close()
cleanup()
}()

var overlapHeights []int64
noChildrenHeights := createBlocksWithNoChildren(ctx, tti.numberToCreateWithNoChildren, db)

childrenHeights := createBlocksWithChildren(ctx, tti.numberToCreateWithChildren, db, nil, overlapHeights)

if tti.overlapCount > 0 {
overlapHeights = noChildrenHeights[:tti.overlapCount]
oldChildrenHeights := childrenHeights
for _, o := range oldChildrenHeights {
if !slices.Contains(overlapHeights, o) {
childrenHeights = append(childrenHeights, o)
}
}
}

heights, err := db.BtcBlocksHeightsWithNoChildren(ctx)
if err != nil {
t.Fatal(err)
}

toCmp := make([]uint64, len(noChildrenHeights)+1)
for i, c := range noChildrenHeights {
toCmp[i] = uint64(c)
}
toCmp[len(toCmp)-1] = uint64(childrenHeights[len(childrenHeights)-1])

slices.Sort(heights)
slices.Sort(toCmp)

// we return a nil slice if emtpy, change that here for deep.Equal
if len(heights) == 0 {
heights = []uint64{}
}

if diff := deep.Equal(toCmp[:len(toCmp)-1], heights); len(diff) != 0 {
t.Fatalf("unexpected diff %s", diff)
}
})
}
}

type BtcTransactionBroadcastRequest struct {
TxId string
SerializedTx []byte
Expand Down
Loading

0 comments on commit 1cd1bbd

Please sign in to comment.