Skip to content

Commit 728ec4d

Browse files
committed
Add sdk/ton/timelock_executor_test.go
1 parent 3e808a9 commit 728ec4d

File tree

4 files changed

+165
-7
lines changed

4 files changed

+165
-7
lines changed

sdk/ton/timelock_converter_test.go

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,14 +7,17 @@ import (
77

88
"github.com/ethereum/go-ethereum/common"
99
cselectors "github.com/smartcontractkit/chain-selectors"
10+
1011
"github.com/stretchr/testify/assert"
1112
"github.com/stretchr/testify/require"
13+
1214
"github.com/xssnick/tonutils-go/address"
1315
"github.com/xssnick/tonutils-go/tvm/cell"
1416

1517
sdkerrors "github.com/smartcontractkit/mcms/sdk/errors"
16-
"github.com/smartcontractkit/mcms/sdk/ton"
1718
"github.com/smartcontractkit/mcms/types"
19+
20+
"github.com/smartcontractkit/mcms/sdk/ton"
1821
)
1922

2023
func TestTimelockConverter_ConvertBatchToChainOperation(t *testing.T) {

sdk/ton/timelock_executor.go

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import (
44
"context"
55
"encoding/hex"
66
"encoding/json"
7+
"errors"
78
"fmt"
89
"math/rand/v2"
910

@@ -35,15 +36,19 @@ type timelockExecutor struct {
3536
}
3637

3738
// NewTimelockExecutor creates a new TimelockExecutor
38-
func NewTimelockExecutor(client ton.APIClientWrapped, wallet *wallet.Wallet, amount tlb.Coins) sdk.TimelockExecutor {
39+
func NewTimelockExecutor(client ton.APIClientWrapped, wallet *wallet.Wallet, amount tlb.Coins) (sdk.TimelockExecutor, error) {
40+
if IsNil(client) {
41+
return nil, errors.New("failed to create sdk.Executor - client (ton.APIClientWrapped) is nil")
42+
}
43+
3944
return &timelockExecutor{
4045
TimelockInspector: NewTimelockInspector(client),
4146
wallet: wallet,
4247
amount: amount,
43-
}
48+
}, nil
4449
}
4550

46-
func (t *timelockExecutor) Execute(
51+
func (e *timelockExecutor) Execute(
4752
ctx context.Context, bop types.BatchOperation, timelockAddress string, predecessor common.Hash, salt common.Hash,
4853
) (types.TransactionResult, error) {
4954
// Map to Ton Address type
@@ -95,13 +100,13 @@ func (t *timelockExecutor) Execute(
95100
IHRDisabled: true,
96101
Bounce: true,
97102
DstAddr: dstAddr,
98-
Amount: t.amount,
103+
Amount: e.amount,
99104
Body: body,
100105
},
101106
}
102107

103108
// TODO: do we wait for execution trace?
104-
tx, _, err := t.wallet.SendWaitTransaction(ctx, msg)
109+
tx, _, err := e.wallet.SendWaitTransaction(ctx, msg)
105110
if err != nil {
106111
return types.TransactionResult{}, fmt.Errorf("failed to execute batch: %w", err)
107112
}

sdk/ton/timelock_executor_test.go

Lines changed: 150 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,150 @@
1+
package ton_test
2+
3+
import (
4+
"context"
5+
"encoding/json"
6+
"errors"
7+
"fmt"
8+
"math/big"
9+
"testing"
10+
11+
"github.com/stretchr/testify/assert"
12+
"github.com/stretchr/testify/mock"
13+
14+
"github.com/xssnick/tonutils-go/tlb"
15+
"github.com/xssnick/tonutils-go/ton"
16+
"github.com/xssnick/tonutils-go/tvm/cell"
17+
18+
"github.com/ethereum/go-ethereum/common"
19+
20+
"github.com/smartcontractkit/mcms/internal/testutils/chaintest"
21+
"github.com/smartcontractkit/mcms/types"
22+
23+
tonmcms "github.com/smartcontractkit/mcms/sdk/ton"
24+
ton_mocks "github.com/smartcontractkit/mcms/sdk/ton/mocks"
25+
)
26+
27+
func TestNewTimelockExecutor(t *testing.T) {
28+
t.Parallel()
29+
30+
chainID := chaintest.Chain7ToniID
31+
32+
_api := ton_mocks.NewTonAPI(t)
33+
walletOperator := must(makeRandomTestWallet(_api, chainID))
34+
client := ton_mocks.NewAPIClientWrapped(t)
35+
36+
executor, err := tonmcms.NewTimelockExecutor(client, walletOperator, tlb.MustFromTON("0"))
37+
assert.NotNil(t, executor, "expected Executor")
38+
assert.NoError(t, err)
39+
}
40+
41+
func TestTimelockExecutor_Execute(t *testing.T) {
42+
t.Parallel()
43+
44+
ctx := context.Background()
45+
46+
sharedMockSetup := func(api *ton_mocks.TonAPI, client *ton_mocks.APIClientWrapped) {
47+
// Mock CurrentMasterchainInfo
48+
api.EXPECT().CurrentMasterchainInfo(mock.Anything).
49+
Return(&ton.BlockIDExt{}, nil)
50+
51+
// Mock WaitForBlock
52+
client.EXPECT().GetAccount(mock.Anything, mock.Anything, mock.Anything).
53+
Return(&tlb.Account{}, nil)
54+
55+
client.EXPECT().RunGetMethod(mock.Anything, mock.Anything, mock.Anything, mock.Anything).
56+
Return(ton.NewExecutionResult([]any{big.NewInt(5)}), nil)
57+
58+
api.EXPECT().WaitForBlock(mock.Anything).
59+
Return(client)
60+
}
61+
62+
tests := []struct {
63+
name string
64+
timelockAddress string
65+
bop types.BatchOperation
66+
predecessor common.Hash
67+
salt common.Hash
68+
mockSetup func(api *ton_mocks.TonAPI, client *ton_mocks.APIClientWrapped)
69+
wantTxHash string
70+
wantErr error
71+
}{
72+
{
73+
name: "success",
74+
// auth: mockAuth,
75+
timelockAddress: "EQADa3W6G0nSiTV4a6euRA42fU9QxSEnb-WeDpcrtWzA2jM8",
76+
bop: types.BatchOperation{
77+
ChainSelector: chaintest.Chain7Selector,
78+
Transactions: []types.Transaction{
79+
{
80+
To: "EQADa3W6G0nSiTV4a6euRA42fU9QxSEnb-WeDpcrtWzA2jM8",
81+
Data: cell.BeginCell().MustStoreBinarySnake([]byte{1, 2, 3}).EndCell().ToBOC(),
82+
AdditionalFields: json.RawMessage(`{"value": 0}`)},
83+
},
84+
},
85+
mockSetup: func(api *ton_mocks.TonAPI, client *ton_mocks.APIClientWrapped) {
86+
// Successful tx send
87+
sharedMockSetup(api, client)
88+
89+
// Mock SendTransaction to return (no error)
90+
api.EXPECT().SendExternalMessageWaitTransaction(mock.Anything, mock.Anything).
91+
Return(&tlb.Transaction{Hash: []byte{1, 2, 3, 4, 14}}, &ton.BlockIDExt{}, []byte{}, nil)
92+
93+
},
94+
wantTxHash: "010203040e",
95+
wantErr: nil,
96+
},
97+
{
98+
name: "failure in tx execution",
99+
// auth: mockAuth,
100+
timelockAddress: "EQADa3W6G0nSiTV4a6euRA42fU9QxSEnb-WeDpcrtWzA2jM8",
101+
bop: types.BatchOperation{
102+
ChainSelector: chaintest.Chain7Selector,
103+
Transactions: []types.Transaction{
104+
{
105+
To: "EQADa3W6G0nSiTV4a6euRA42fU9QxSEnb-WeDpcrtWzA2jM8",
106+
Data: cell.BeginCell().MustStoreBinarySnake([]byte{1, 2, 3}).EndCell().ToBOC(),
107+
AdditionalFields: json.RawMessage(`{"value": 0}`)},
108+
},
109+
},
110+
mockSetup: func(api *ton_mocks.TonAPI, client *ton_mocks.APIClientWrapped) {
111+
// Error tx send
112+
sharedMockSetup(api, client)
113+
114+
// Mock SendTransaction to return an error
115+
api.EXPECT().SendExternalMessageWaitTransaction(mock.Anything, mock.Anything).
116+
Return(&tlb.Transaction{Hash: []byte{1, 2, 3, 4, 14}}, &ton.BlockIDExt{}, []byte{}, errors.New("error during tx send"))
117+
},
118+
wantTxHash: "",
119+
wantErr: fmt.Errorf("failed to execute batch: error during tx send"),
120+
},
121+
}
122+
123+
for _, tt := range tests {
124+
t.Run(tt.name, func(t *testing.T) {
125+
t.Parallel()
126+
127+
// Initialize the mock
128+
chainID := chaintest.Chain7ToniID
129+
_api := ton_mocks.NewTonAPI(t)
130+
walletOperator := must(makeRandomTestWallet(_api, chainID))
131+
132+
client := ton_mocks.NewAPIClientWrapped(t)
133+
134+
if tt.mockSetup != nil {
135+
tt.mockSetup(_api, client)
136+
}
137+
138+
executor, err := tonmcms.NewTimelockExecutor(client, walletOperator, tlb.MustFromTON("0"))
139+
assert.NoError(t, err)
140+
141+
tx, err := executor.Execute(ctx, tt.bop, tt.timelockAddress, tt.predecessor, tt.salt)
142+
assert.Equal(t, tt.wantTxHash, tx.Hash)
143+
if tt.wantErr != nil {
144+
assert.EqualError(t, err, tt.wantErr.Error())
145+
} else {
146+
assert.NoError(t, err)
147+
}
148+
})
149+
}
150+
}

types/signature_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -132,7 +132,7 @@ func Test_Recover(t *testing.T) {
132132
V: 1,
133133
},
134134
giveHash: hash,
135-
wantErr: "recovery failed",
135+
wantErr: "failed to recover public key: recovery failed",
136136
},
137137
}
138138

0 commit comments

Comments
 (0)