Skip to content

Commit

Permalink
fix matrix of bytes encoding
Browse files Browse the repository at this point in the history
  • Loading branch information
louisinger committed Jan 22, 2025
1 parent fc9cabb commit 46cf2cd
Show file tree
Hide file tree
Showing 3 changed files with 152 additions and 19 deletions.
26 changes: 23 additions & 3 deletions common/bitcointree/musig2.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
"errors"
"fmt"
"io"
"reflect"
"runtime"
"strings"
"sync"
Expand Down Expand Up @@ -686,15 +687,25 @@ func encodeMatrix[T writable](matrix [][]T) ([]byte, error) {

// For each row, write its length and then its elements
for _, row := range matrix {
// Write row length
// for each row, write its length
if err := binary.Write(&buf, binary.LittleEndian, uint32(len(row))); err != nil {
return nil, err
}
// Write row data
// for each cell, write <isNil> | <cell> bytes
for _, cell := range row {
if err := cell.Encode(&buf); err != nil {
notNil := true
if reflect.ValueOf(cell).IsNil() {
notNil = false
}
if err := binary.Write(&buf, binary.LittleEndian, notNil); err != nil {
return nil, err
}

if notNil {
if err := cell.Encode(&buf); err != nil {
return nil, err
}
}
}
}

Expand Down Expand Up @@ -723,6 +734,15 @@ func decodeMatrix[T readable](factory func() T, data io.Reader) ([][]T, error) {
row := make([]T, 0, colCount)
// Read row data
for j := uint32(0); j < colCount; j++ {
// check if the cell is nil
var notNil bool
if err := binary.Read(data, binary.LittleEndian, &notNil); err != nil {
return nil, err
}
if !notNil {
row = append(row, *new(T)) // append a new nil cell
continue
}
cell := factory()
if err := cell.Decode(data); err != nil {
return nil, err
Expand Down
27 changes: 27 additions & 0 deletions common/bitcointree/musig2_test.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package bitcointree_test

import (
"bytes"
"encoding/hex"
"fmt"
"testing"
Expand Down Expand Up @@ -81,6 +82,17 @@ func TestBuildAndSignVtxoTree(t *testing.T) {
for pubkey, session := range signerSessions {
nonces, err := session.GetNonces()
require.NoError(t, err)
var encodedNonces bytes.Buffer
err = nonces.Encode(&encodedNonces)
require.NoError(t, err)
decodedNonces, err := bitcointree.DecodeNonces(&encodedNonces)
require.NoError(t, err)
for i, nonceRow := range nonces {
for j, nonce := range nonceRow {
require.Equal(t, nonce, decodedNonces[i][j])
}
}

serverCoordinator.AddNonce(pubkey, nonces)
}

Expand All @@ -96,6 +108,21 @@ func TestBuildAndSignVtxoTree(t *testing.T) {
for pubkey, session := range signerSessions {
sig, err := session.Sign()
require.NoError(t, err)
var encodedSig bytes.Buffer
err = sig.Encode(&encodedSig)
require.NoError(t, err)
decodedSig, err := bitcointree.DecodeSignatures(&encodedSig)
require.NoError(t, err)
for i, sigRow := range sig {
for j, sig := range sigRow {
if sig == nil {
require.Nil(t, decodedSig[i][j])
} else {
require.Equal(t, sig.S, decodedSig[i][j].S)
}
}
}

serverCoordinator.AddSig(pubkey, sig)
}

Expand Down
118 changes: 102 additions & 16 deletions server/test/e2e/covenantless/e2e_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import (
"net/http"
"os"
"strings"
"sync"
"testing"
"time"

Expand Down Expand Up @@ -81,40 +82,125 @@ func TestMain(m *testing.M) {
os.Exit(code)
}

func TestSendOffchain(t *testing.T) {
var receive utils.ArkReceive
receiveStr, err := runClarkCommand("receive")
func TestSettleInSameRound(t *testing.T) {
ctx := context.Background()
alice, grpcAlice := setupArkSDK(t)
defer grpcAlice.Close()

bob, grpcBob := setupArkSDK(t)
defer grpcBob.Close()

_, aliceBoardingAddress, err := alice.Receive(ctx)
require.NoError(t, err)

err = json.Unmarshal([]byte(receiveStr), &receive)
_, bobBoardingAddress, err := bob.Receive(ctx)
require.NoError(t, err)

_, err = utils.RunCommand("nigiri", "faucet", receive.Boarding)
_, err = utils.RunCommand("nigiri", "faucet", aliceBoardingAddress)
require.NoError(t, err)

_, err = utils.RunCommand("nigiri", "faucet", bobBoardingAddress)
require.NoError(t, err)

time.Sleep(5 * time.Second)

_, err = runClarkCommand("settle", "--password", utils.Password)
aliceOffchainAddr, _, err := alice.Receive(ctx)
require.NoError(t, err)

time.Sleep(3 * time.Second)
bobOffchainAddr, _, err := bob.Receive(ctx)
require.NoError(t, err)

_, err = runClarkCommand("send", "--amount", "10000", "--to", receive.Offchain, "--password", utils.Password)
// Alice sends to Bob
_, err = alice.SendOffChain(ctx, false, []arksdk.Receiver{arksdk.NewBitcoinReceiver(bobOffchainAddr, 5000)})
require.NoError(t, err)

var balance utils.ArkBalance
balanceStr, err := runClarkCommand("balance")
// Bob sends to Alice
_, err = bob.SendOffChain(ctx, false, []arksdk.Receiver{arksdk.NewBitcoinReceiver(aliceOffchainAddr, 3000)})
require.NoError(t, err)
require.NoError(t, json.Unmarshal([]byte(balanceStr), &balance))
require.NotZero(t, balance.Offchain.Total)

_, err = runClarkCommand("settle", "--password", utils.Password)
time.Sleep(2 * time.Second)

var wg sync.WaitGroup
wg.Add(2)

var aliceRoundID, bobRoundID string
var aliceErr, bobErr error

go func() {
defer wg.Done()
aliceRoundID, aliceErr = alice.Settle(ctx)
}()

go func() {
defer wg.Done()
bobRoundID, bobErr = bob.Settle(ctx)
}()

wg.Wait()

require.NoError(t, aliceErr)
require.NoError(t, bobErr)
require.NotEmpty(t, aliceRoundID)
require.NotEmpty(t, bobRoundID)
require.Equal(t, aliceRoundID, bobRoundID)

time.Sleep(5 * time.Second)

aliceVtxos, _, err := alice.ListVtxos(ctx)
require.NoError(t, err)
require.NotEmpty(t, aliceVtxos)

balanceStr, err = runClarkCommand("balance")
bobVtxos, _, err := bob.ListVtxos(ctx)
require.NoError(t, err)
require.NoError(t, json.Unmarshal([]byte(balanceStr), &balance))
require.NotZero(t, balance.Offchain.Total)
require.NotEmpty(t, bobVtxos)

wg.Add(2)

var aliceSecondRoundID, bobSecondRoundID string

go func() {
defer wg.Done()
aliceSecondRoundID, aliceErr = alice.Settle(ctx)
}()

go func() {
defer wg.Done()
bobSecondRoundID, bobErr = bob.Settle(ctx)
}()

wg.Wait()

require.NoError(t, aliceErr)
require.NoError(t, bobErr)
require.Equal(t, aliceSecondRoundID, bobSecondRoundID, "Second settle round IDs should match")

time.Sleep(5 * time.Second)

aliceVtxosAfter, _, err := alice.ListVtxos(ctx)
require.NoError(t, err)
require.NotEmpty(t, aliceVtxosAfter)

bobVtxosAfter, _, err := bob.ListVtxos(ctx)
require.NoError(t, err)
require.NotEmpty(t, bobVtxosAfter)

var aliceNewVtxo, bobNewVtxo client.Vtxo
for _, vtxo := range aliceVtxosAfter {
if vtxo.RoundTxid == aliceSecondRoundID {
aliceNewVtxo = vtxo
break
}
}
for _, vtxo := range bobVtxosAfter {
if vtxo.RoundTxid == bobSecondRoundID {
bobNewVtxo = vtxo
break
}
}

require.NotEmpty(t, aliceNewVtxo)
require.NotEmpty(t, bobNewVtxo)
require.Equal(t, aliceNewVtxo.RoundTxid, bobNewVtxo.RoundTxid)
}

func TestUnilateralExit(t *testing.T) {
Expand Down

0 comments on commit 46cf2cd

Please sign in to comment.