Skip to content

Commit

Permalink
Add encode/decode keystone
Browse files Browse the repository at this point in the history
  • Loading branch information
marcopeereboom committed Jan 30, 2025
1 parent 59beabb commit c027c32
Show file tree
Hide file tree
Showing 5 changed files with 38 additions and 20 deletions.
5 changes: 3 additions & 2 deletions database/tbcd/database.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import (
"github.com/syndtr/goleveldb/leveldb"

"github.com/hemilabs/heminetwork/database"
"github.com/hemilabs/heminetwork/hemi"
)

type InsertType int
Expand Down Expand Up @@ -125,8 +126,8 @@ type Database interface {
}

type Keystone struct {
BlockHash chainhash.Hash // Block that contains abbreviated keystone
AbbreviatedKeystone []byte // Abbreviated keystone
BlockHash chainhash.Hash // Block that contains abbreviated keystone
AbbreviatedKeystone [hemi.L2KeystoneAbrevSize]byte // Abbreviated keystone
}

// XXX there exist various types in this file that need to be reevaluated.
Expand Down
47 changes: 32 additions & 15 deletions database/tbcd/level/level.go
Original file line number Diff line number Diff line change
Expand Up @@ -296,11 +296,7 @@ func (l *ldb) BlockKeystoneByL2KeystoneAbrevHash(ctx context.Context, abrevhash
return nil, fmt.Errorf("l2 keystone get: %w", err)
}

ks := tbcd.Keystone{
BlockHash: chainhash.Hash(eks[:32]),
AbbreviatedKeystone: eks[32:],
}

ks := decodeKeystone(eks)
return &ks, nil
}

Expand Down Expand Up @@ -1729,6 +1725,32 @@ func (l *ldb) BlockTxUpdate(ctx context.Context, direction int, txs map[tbcd.TxK
return nil
}

// encodeKeystone encodes a database keystone as
// [blockhash,abbreviated keystone] or [32+76] bytes. The abbreviated keystone
// hash is the leveldb table key.
func encodeKeystone(ks tbcd.Keystone) (eks [chainhash.HashSize + hemi.L2KeystoneAbrevSize]byte) {
copy(eks[0:32], ks.BlockHash[:])
copy(eks[32:], ks.AbbreviatedKeystone[:])
return
}

func encodeKeystoneToSlice(ks tbcd.Keystone) []byte {
eks := encodeKeystone(ks)
return eks[:]
}

// decodeKeystone reverse the process of encodeKeystone.
func decodeKeystone(eks []byte) (ks tbcd.Keystone) {
bh, err := chainhash.NewHash(eks[0:32])
if err != nil {
panic(err) // Can't happen
}
ks.BlockHash = *bh
// copy the values to prevent slicing reentrancy problems.
copy(ks.AbbreviatedKeystone[:], eks[32:])
return ks
}

func (l *ldb) BlockKeystoneUpdate(ctx context.Context, direction int, keystones map[chainhash.Hash]tbcd.Keystone) error {
log.Tracef("BlockKeystoneUpdate")
defer log.Tracef("BlockKeystoneUpdate exit")
Expand All @@ -1748,17 +1770,15 @@ func (l *ldb) BlockKeystoneUpdate(ctx context.Context, direction int, keystones
for k, v := range keystones {
switch direction {
case -1:
foundKeystone, err := kssTx.Get(k[:], nil)
eks, err := kssTx.Get(k[:], nil)
if err != nil {
continue
}
fbh, err := chainhash.NewHash(foundKeystone[0:32])
if err != nil {
return err // XXX really can't happen
}
ks := decodeKeystone(eks)
// Only delete keystone if it is in the previously found block.
if fbh.IsEqual(&v.BlockHash) {
if ks.BlockHash.IsEqual(&v.BlockHash) {
kssBatch.Delete(k[:])
} else {

Check failure on line 1781 in database/tbcd/level/level.go

View workflow job for this annotation

GitHub Actions / Lint

SA9003: empty branch (staticcheck)
}
case 1:
has, err := kssTx.Has(k[:], nil)
Expand All @@ -1769,10 +1789,7 @@ func (l *ldb) BlockKeystoneUpdate(ctx context.Context, direction int, keystones
// Only store unknown keystones
continue
}
var value [chainhash.HashSize + hemi.L2KeystoneAbrevSize]byte
copy(value[0:32], v.BlockHash[:])
copy(value[32:], v.AbbreviatedKeystone)
kssBatch.Put(k[:], value[:])
kssBatch.Put(k[:], encodeKeystoneToSlice(v))
}
}

Expand Down
2 changes: 1 addition & 1 deletion service/tbc/crawler.go
Original file line number Diff line number Diff line change
Expand Up @@ -1241,7 +1241,7 @@ func processKeystones(blockHash *chainhash.Hash, txs []*btcutil.Tx, kssCache map
abvKss := aPoPTx.L2Keystone.Serialize()
kssCache[*aPoPTx.L2Keystone.Hash()] = tbcd.Keystone{
BlockHash: *blockHash,
AbbreviatedKeystone: abvKss[:],
AbbreviatedKeystone: abvKss,
}
}
}
Expand Down
2 changes: 1 addition & 1 deletion service/tbc/rpc_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1594,7 +1594,7 @@ func TestL2BlockByAbrevHash(t *testing.T) {

kssCache[*hemi.L2KeystoneAbbreviate(l2Keystone).Hash()] = tbcd.Keystone{
BlockHash: btcBlockHash,
AbbreviatedKeystone: abrvKss[:],
AbbreviatedKeystone: abrvKss,
}

if err := s.db.BlockKeystoneUpdate(ctx, 1, kssCache); err != nil {
Expand Down
2 changes: 1 addition & 1 deletion service/tbc/tbcfork_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -865,7 +865,7 @@ func (b *btcNode) mine(name string, from *chainhash.Hash, payToAddress btcutil.A
abrvKs := hemi.L2KeystoneAbbreviate(l2Keystone).Serialize()
blk.kss[*hemi.L2KeystoneAbbreviate(l2Keystone).Hash()] = tbcd.Keystone{
BlockHash: *blk.Hash(),
AbbreviatedKeystone: abrvKs[:],
AbbreviatedKeystone: abrvKs,
}
}

Expand Down

0 comments on commit c027c32

Please sign in to comment.