Skip to content

Commit 3782793

Browse files
louisingeraltafan
andauthored
Add tests for adversarial scenarios (#300)
* fix and test cheating scenario (malicious double spend) * test and fix async vtxo cheating cases * add replace statement in go.mod * Update server/internal/core/application/covenantless.go Co-authored-by: Pietralberto Mazza <18440657+altafan@users.noreply.github.com> Signed-off-by: Louis Singer <41042567+louisinger@users.noreply.github.com> * Update server/internal/infrastructure/wallet/btc-embedded/psbt.go Co-authored-by: Pietralberto Mazza <18440657+altafan@users.noreply.github.com> Signed-off-by: Louis Singer <41042567+louisinger@users.noreply.github.com> * Update server/test/e2e/covenant/e2e_test.go Co-authored-by: Pietralberto Mazza <18440657+altafan@users.noreply.github.com> Signed-off-by: Louis Singer <41042567+louisinger@users.noreply.github.com> * Update server/test/e2e/covenantless/e2e_test.go Co-authored-by: Pietralberto Mazza <18440657+altafan@users.noreply.github.com> Signed-off-by: Louis Singer <41042567+louisinger@users.noreply.github.com> * Update server/test/e2e/covenantless/e2e_test.go Co-authored-by: Pietralberto Mazza <18440657+altafan@users.noreply.github.com> Signed-off-by: Louis Singer <41042567+louisinger@users.noreply.github.com> * remove unused * [btc-embedded] fix GetNotificationChannel * [tx-builder] fix redeem transaction fee estimator * close grpc client in tests * [application] rework listentoscannerNotification * [application][covenant] fix getConnectorAmount * [tx-builder][covenant] get connector amount from wallet * e2e test sleep time * [liquid-standalone] ListConnectorUtxos: filter by script client side * fix Makefile integrationtest * do not use cache in integration tests * use VtxoKey as argument of findForfeitTxBitcoin * wrap adversarial test in t.Run * increaste test timeout * CI: setup go 1.23.1 * CI: revert go version * add replace in server/go.mod * Update server/internal/core/application/covenant.go Co-authored-by: Pietralberto Mazza <18440657+altafan@users.noreply.github.com> Signed-off-by: Louis Singer <41042567+louisinger@users.noreply.github.com> * remove replace * readd replace statement * fixes * go work sync * fix CI --------- Signed-off-by: Louis Singer <41042567+louisinger@users.noreply.github.com> Co-authored-by: Pietralberto Mazza <18440657+altafan@users.noreply.github.com>
1 parent 4c8c5c0 commit 3782793

31 files changed

+710
-276
lines changed

.github/workflows/ark.artifacts.yaml

+2-2
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,9 @@ jobs:
1212
uses: actions/checkout@v2
1313

1414
- name: Set up Go
15-
uses: actions/setup-go@v2
15+
uses: actions/setup-go@v4
1616
with:
17-
go-version: 1.21.0
17+
go-version: 1.23.1
1818

1919
- name: Build binaries
2020
run: make build-all

.github/workflows/ark.integration.yaml

+7-5
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,8 @@ name: ci_integration
22

33
on:
44
push:
5-
branches: [master]
5+
branches:
6+
- master
67
pull_request:
78
branches:
89
- master
@@ -15,11 +16,12 @@ jobs:
1516
run:
1617
working-directory: ./server
1718
steps:
18-
- uses: actions/setup-go@v3
19-
with:
20-
go-version: ">1.17.2"
2119
- uses: actions/checkout@v3
22-
- run: go get -v -t -d ./...
20+
- uses: actions/setup-go@v4
21+
with:
22+
go-version: '>=1.23.1'
23+
- name: Run go work sync
24+
run: go work sync
2325

2426
- name: Run Nigiri
2527
uses: vulpemventures/nigiri-github-action@v1

.github/workflows/ark.release.yaml

+2-2
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,9 @@ jobs:
1616
uses: actions/checkout@v2
1717

1818
- name: Set up Go
19-
uses: actions/setup-go@v2
19+
uses: actions/setup-go@v4
2020
with:
21-
go-version: 1.21.0
21+
go-version: 1.23.1
2222

2323
# Build binaries for all architectures
2424
- name: Build binaries

.github/workflows/ark.unit.yaml

+5-3
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,11 @@ name: ci_unit
22

33
on:
44
push:
5+
branches:
6+
- master
57
paths:
68
- 'server/**'
79
- 'pkg/client-sdk/**'
8-
branches: [master]
910
pull_request:
1011
branches:
1112
- master
@@ -56,7 +57,8 @@ jobs:
5657
uses: securego/gosec@master
5758
with:
5859
args: '-severity high -quiet -exclude=G115 ./...'
59-
- run: go get -v -t -d ./...
60+
- name: Run go work sync
61+
run: go work sync
6062
- name: unit testing
6163
run: make test
6264

@@ -83,4 +85,4 @@ jobs:
8385
args: '-severity high -quiet -exclude=G115 ./...'
8486
- run: go get -v -t -d ./...
8587
- name: unit testing
86-
run: make test
88+
run: make test

docker-compose.clark.regtest.yml

-1
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@ services:
1111
- ARK_LOG_LEVEL=5
1212
- ARK_ROUND_LIFETIME=512
1313
- ARK_TX_BUILDER_TYPE=covenantless
14-
- ARK_MIN_RELAY_FEE=200
1514
- ARK_ESPLORA_URL=http://chopsticks:3000
1615
- ARK_BITCOIND_RPC_USER=admin1
1716
- ARK_BITCOIND_RPC_PASS=123

pkg/client-sdk/ark_sdk.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ type ArkClient interface {
1515
Unlock(ctx context.Context, password string) error
1616
Lock(ctx context.Context, password string) error
1717
Balance(ctx context.Context, computeExpiryDetails bool) (*Balance, error)
18-
Receive(ctx context.Context) (string, string, error)
18+
Receive(ctx context.Context) (offchainAddr, boardingAddr string, err error)
1919
SendOnChain(ctx context.Context, receivers []Receiver) (string, error)
2020
SendOffChain(
2121
ctx context.Context, withExpiryCoinselect bool, receivers []Receiver,
@@ -26,7 +26,7 @@ type ArkClient interface {
2626
) (string, error)
2727
SendAsync(ctx context.Context, withExpiryCoinselect bool, receivers []Receiver) (string, error)
2828
Claim(ctx context.Context) (string, error)
29-
ListVtxos(ctx context.Context) ([]client.Vtxo, []client.Vtxo, error)
29+
ListVtxos(ctx context.Context) (spendable, spent []client.Vtxo, err error)
3030
GetTransactionHistory(ctx context.Context) ([]Transaction, error)
3131
Dump(ctx context.Context) (seed string, err error)
3232
}

pkg/client-sdk/covenant_client.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ import (
1717
"github.com/ark-network/ark/pkg/client-sdk/client"
1818
"github.com/ark-network/ark/pkg/client-sdk/explorer"
1919
"github.com/ark-network/ark/pkg/client-sdk/internal/utils"
20-
"github.com/ark-network/ark/pkg/client-sdk/internal/utils/redemption"
20+
"github.com/ark-network/ark/pkg/client-sdk/redemption"
2121
"github.com/ark-network/ark/pkg/client-sdk/store"
2222
"github.com/ark-network/ark/pkg/client-sdk/wallet"
2323
"github.com/btcsuite/btcd/btcec/v2/schnorr"

pkg/client-sdk/covenantless_client.go

+23-1
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ import (
1818
"github.com/ark-network/ark/pkg/client-sdk/client"
1919
"github.com/ark-network/ark/pkg/client-sdk/explorer"
2020
"github.com/ark-network/ark/pkg/client-sdk/internal/utils"
21-
"github.com/ark-network/ark/pkg/client-sdk/internal/utils/redemption"
21+
"github.com/ark-network/ark/pkg/client-sdk/redemption"
2222
"github.com/ark-network/ark/pkg/client-sdk/store"
2323
"github.com/ark-network/ark/pkg/client-sdk/wallet"
2424
"github.com/btcsuite/btcd/btcec/v2/schnorr"
@@ -975,6 +975,15 @@ func (a *covenantlessArkClient) handleRoundStream(
975975

976976
var signerSession bitcointree.SignerSession
977977

978+
const (
979+
start = iota
980+
roundSigningStarted
981+
roundSigningNoncesGenerated
982+
roundFinalization
983+
)
984+
985+
step := start
986+
978987
for {
979988
select {
980989
case <-ctx.Done():
@@ -991,24 +1000,35 @@ func (a *covenantlessArkClient) handleRoundStream(
9911000
return "", fmt.Errorf("round failed: %s", event.(client.RoundFailedEvent).Reason)
9921001
case client.RoundSigningStartedEvent:
9931002
pingStop()
1003+
if step != start {
1004+
continue
1005+
}
9941006
log.Info("a round signing started")
9951007
signerSession, err = a.handleRoundSigningStarted(
9961008
ctx, roundEphemeralKey, event.(client.RoundSigningStartedEvent),
9971009
)
9981010
if err != nil {
9991011
return "", err
10001012
}
1013+
step++
10011014
continue
10021015
case client.RoundSigningNoncesGeneratedEvent:
1016+
if step != roundSigningStarted {
1017+
continue
1018+
}
10031019
pingStop()
10041020
log.Info("round combined nonces generated")
10051021
if err := a.handleRoundSigningNoncesGenerated(
10061022
ctx, event.(client.RoundSigningNoncesGeneratedEvent), roundEphemeralKey, signerSession,
10071023
); err != nil {
10081024
return "", err
10091025
}
1026+
step++
10101027
continue
10111028
case client.RoundFinalizationEvent:
1029+
if step != roundSigningNoncesGenerated {
1030+
continue
1031+
}
10121032
pingStop()
10131033
log.Info("a round finalization started")
10141034

@@ -1031,6 +1051,8 @@ func (a *covenantlessArkClient) handleRoundStream(
10311051

10321052
log.Info("done.")
10331053
log.Info("waiting for round finalization...")
1054+
step++
1055+
continue
10341056
}
10351057
}
10361058
}

pkg/client-sdk/internal/utils/utils.go

+6
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import (
88
"fmt"
99
"runtime/debug"
1010
"sort"
11+
"sync"
1112

1213
"github.com/ark-network/ark/common"
1314
"github.com/ark-network/ark/pkg/client-sdk/client"
@@ -265,8 +266,13 @@ func DecryptAES128(encrypted, password []byte) ([]byte, error) {
265266
return plaintext, nil
266267
}
267268

269+
var lock = &sync.Mutex{}
270+
268271
// deriveKey derives a 32 byte array key from a custom passhprase
269272
func deriveKey(password, salt []byte) ([]byte, []byte, error) {
273+
lock.Lock()
274+
defer lock.Unlock()
275+
270276
if salt == nil {
271277
salt = make([]byte, 32)
272278
if _, err := rand.Read(salt); err != nil {

pkg/client-sdk/wallet/singlekey/bitcoin_wallet.go

+9-7
Original file line numberDiff line numberDiff line change
@@ -181,14 +181,16 @@ func (s *bitcoinWallet) SignTransaction(
181181
return "", fmt.Errorf("signature verification failed")
182182
}
183183

184-
updater.Upsbt.Inputs[i].TaprootScriptSpendSig = []*psbt.TaprootScriptSpendSig{
185-
{
186-
XOnlyPubKey: schnorr.SerializePubKey(pubkey),
187-
LeafHash: hash.CloneBytes(),
188-
Signature: sig.Serialize(),
189-
SigHash: txscript.SigHashDefault,
190-
},
184+
if len(updater.Upsbt.Inputs[i].TaprootScriptSpendSig) == 0 {
185+
updater.Upsbt.Inputs[i].TaprootScriptSpendSig = make([]*psbt.TaprootScriptSpendSig, 0)
191186
}
187+
188+
updater.Upsbt.Inputs[i].TaprootScriptSpendSig = append(updater.Upsbt.Inputs[i].TaprootScriptSpendSig, &psbt.TaprootScriptSpendSig{
189+
XOnlyPubKey: schnorr.SerializePubKey(pubkey),
190+
LeafHash: hash.CloneBytes(),
191+
Signature: sig.Serialize(),
192+
SigHash: txscript.SigHashDefault,
193+
})
192194
}
193195
}
194196
}

server/Makefile

+2-1
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,8 @@ help:
2323
## intergrationtest: runs integration tests
2424
integrationtest:
2525
@echo "Running integration tests..."
26-
@go test -v -count=1 -race -timeout 200s github.com/ark-network/ark/server/test/e2e/...
26+
@go test -v -count 1 -timeout 300s github.com/ark-network/ark/server/test/e2e/covenant
27+
@go test -v -count 1 -timeout 300s github.com/ark-network/ark/server/test/e2e/covenantless
2728

2829
## lint: lint codebase
2930
lint:

0 commit comments

Comments
 (0)