Skip to content

Commit 22804b8

Browse files
committed
Add more tests
1 parent 774872f commit 22804b8

File tree

5 files changed

+200
-6
lines changed

5 files changed

+200
-6
lines changed

services/horizon/internal/integration/sac_test.go

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -330,9 +330,10 @@ func TestExpirationAndRestoration(t *testing.T) {
330330
})
331331

332332
// create balance which we will expire
333+
holder := [32]byte{2}
333334
balanceToExpire := sac.BalanceToContractData(
334335
storeContractID,
335-
[32]byte{2},
336+
holder,
336337
37,
337338
)
338339
assertInvokeHostFnSucceeds(
@@ -408,11 +409,20 @@ func TestExpirationAndRestoration(t *testing.T) {
408409
})
409410

410411
// restore expired balance
411-
sourceAccount, restoreFootprint := itest.RestoreFootprint(
412-
itest.Master().Address(),
413-
balanceToExpireLedgerKey,
414-
)
415-
itest.MustSubmitOperations(&sourceAccount, itest.Master(), &restoreFootprint)
412+
restoreFootprint, err := txnbuild.NewAssetBalanceRestoration(txnbuild.AssetBalanceRestorationParams{
413+
NetworkPassphrase: itest.GetPassPhrase(),
414+
Contract: strkey.MustEncode(strkey.VersionByteContract, holder[:]),
415+
Asset: txnbuild.CreditAsset{
416+
Code: code,
417+
Issuer: issuer,
418+
},
419+
SourceAccount: itest.Master().Address(),
420+
})
421+
assert.NoError(t, err)
422+
// set the contract id to storeContractID because we are restoring a fake asset balance
423+
restoreFootprint.Ext.SorobanData.Resources.Footprint.ReadWrite[0].ContractData.Contract.ContractId = &storeContractID
424+
itest.MustSubmitOperations(itest.MasterAccount(), itest.Master(), &restoreFootprint)
425+
416426
assertAssetStats(itest, assetStats{
417427
code: code,
418428
issuer: issuer,

txnbuild/invoke_host_function.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ var defaultPaymentToContractFees = SorobanFees{
2929
ResourceFee: 5_000_000,
3030
}
3131

32+
// PaymentToContractParams configures the payment returned by NewPaymentToContract
3233
type PaymentToContractParams struct {
3334
// NetworkPassphrase is the passphrase for the Stellar network
3435
NetworkPassphrase string
@@ -46,6 +47,8 @@ type PaymentToContractParams struct {
4647
Fees SorobanFees
4748
}
4849

50+
// NewPaymentToContract constructs an invoke host operation to send a payment from a
51+
// source account to a destination smart contract
4952
func NewPaymentToContract(params PaymentToContractParams) (InvokeHostFunction, error) {
5053
asset, err := params.Asset.ToXDR()
5154
if err != nil {

txnbuild/invoke_host_function_test.go

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,62 @@ package txnbuild
33
import (
44
"testing"
55

6+
"github.com/stretchr/testify/require"
7+
8+
"github.com/stellar/go/network"
9+
"github.com/stellar/go/strkey"
610
"github.com/stellar/go/xdr"
711

812
"github.com/stretchr/testify/assert"
913
)
1014

15+
func TestPaymentToContract(t *testing.T) {
16+
issuer := newKeypair0()
17+
sourceAccount := newKeypair1()
18+
params := PaymentToContractParams{
19+
NetworkPassphrase: network.PublicNetworkPassphrase,
20+
Destination: "invalid",
21+
Amount: "10",
22+
Asset: CreditAsset{
23+
Code: "USD",
24+
Issuer: issuer.Address(),
25+
},
26+
SourceAccount: sourceAccount.Address(),
27+
}
28+
_, err := NewPaymentToContract(params)
29+
require.Error(t, err)
30+
31+
params.Destination = newKeypair2().Address()
32+
_, err = NewPaymentToContract(params)
33+
require.Error(t, err)
34+
35+
contractID := xdr.Hash{1}
36+
params.Destination = strkey.MustEncode(strkey.VersionByteContract, contractID[:])
37+
38+
op, err := NewPaymentToContract(params)
39+
require.NoError(t, err)
40+
require.NoError(t, op.Validate())
41+
require.Equal(t, int64(op.Ext.SorobanData.ResourceFee), defaultPaymentToContractFees.ResourceFee)
42+
require.Equal(t, uint32(op.Ext.SorobanData.Resources.WriteBytes), defaultPaymentToContractFees.WriteBytes)
43+
require.Equal(t, uint32(op.Ext.SorobanData.Resources.ReadBytes), defaultPaymentToContractFees.ReadBytes)
44+
require.Equal(t, uint32(op.Ext.SorobanData.Resources.Instructions), defaultPaymentToContractFees.Instructions)
45+
46+
params.Fees = SorobanFees{
47+
Instructions: 1,
48+
ReadBytes: 2,
49+
WriteBytes: 3,
50+
ResourceFee: 4,
51+
}
52+
53+
op, err = NewPaymentToContract(params)
54+
require.NoError(t, err)
55+
require.NoError(t, op.Validate())
56+
require.Equal(t, int64(op.Ext.SorobanData.ResourceFee), int64(4))
57+
require.Equal(t, uint32(op.Ext.SorobanData.Resources.WriteBytes), uint32(3))
58+
require.Equal(t, uint32(op.Ext.SorobanData.Resources.ReadBytes), uint32(2))
59+
require.Equal(t, uint32(op.Ext.SorobanData.Resources.Instructions), uint32(1))
60+
}
61+
1162
func TestCreateInvokeHostFunctionValid(t *testing.T) {
1263
kp1 := newKeypair1()
1364
sourceAccount := NewSimpleAccount(kp1.Address(), int64(41137196761100))

txnbuild/restore_footprint.go

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
package txnbuild
22

33
import (
4+
"github.com/stellar/go/ingest/sac"
5+
"github.com/stellar/go/strkey"
46
"github.com/stellar/go/support/errors"
57
"github.com/stellar/go/xdr"
68
)
@@ -10,6 +12,77 @@ type RestoreFootprint struct {
1012
Ext xdr.TransactionExt
1113
}
1214

15+
var defaultAssetBalanceRestorationFees = SorobanFees{
16+
Instructions: 0,
17+
ReadBytes: 500,
18+
WriteBytes: 500,
19+
ResourceFee: 4_000_000,
20+
}
21+
22+
// AssetBalanceRestorationParams configures the restore footprint operation returned by
23+
// NewAssetBalanceRestoration
24+
type AssetBalanceRestorationParams struct {
25+
// NetworkPassphrase is the passphrase for the Stellar network
26+
NetworkPassphrase string
27+
// Contract is the contract which holds the asset balance
28+
Contract string
29+
// Asset is the asset which is held in the balance
30+
Asset Asset
31+
// SourceAccount is the source account for the restoration operation
32+
SourceAccount string
33+
// Fees configures the fee values for the
34+
// soroban transaction. If this field is omitted
35+
// default fee values will be used
36+
Fees SorobanFees
37+
}
38+
39+
// NewAssetBalanceRestoration constructs a restore footprint operation which restores an
40+
// asset balance for a smart contract
41+
func NewAssetBalanceRestoration(params AssetBalanceRestorationParams) (RestoreFootprint, error) {
42+
asset, err := params.Asset.ToXDR()
43+
if err != nil {
44+
return RestoreFootprint{}, err
45+
}
46+
47+
var assetContractID xdr.Hash
48+
assetContractID, err = asset.ContractID(params.NetworkPassphrase)
49+
if err != nil {
50+
return RestoreFootprint{}, err
51+
}
52+
53+
decoded, err := strkey.Decode(strkey.VersionByteContract, params.Contract)
54+
if err != nil {
55+
return RestoreFootprint{}, err
56+
}
57+
var contractID xdr.Hash
58+
copy(contractID[:], decoded)
59+
60+
resources := params.Fees
61+
if resources.ResourceFee == 0 {
62+
resources = defaultAssetBalanceRestorationFees
63+
}
64+
65+
return RestoreFootprint{
66+
SourceAccount: params.SourceAccount,
67+
Ext: xdr.TransactionExt{
68+
V: 1,
69+
SorobanData: &xdr.SorobanTransactionData{
70+
Resources: xdr.SorobanResources{
71+
Footprint: xdr.LedgerFootprint{
72+
ReadWrite: []xdr.LedgerKey{
73+
sac.ContractBalanceLedgerKey(assetContractID, contractID),
74+
},
75+
},
76+
Instructions: xdr.Uint32(resources.Instructions),
77+
ReadBytes: xdr.Uint32(resources.ReadBytes),
78+
WriteBytes: xdr.Uint32(resources.WriteBytes),
79+
},
80+
ResourceFee: xdr.Int64(resources.ResourceFee),
81+
},
82+
},
83+
}, nil
84+
}
85+
1386
func (f *RestoreFootprint) BuildXDR() (xdr.Operation, error) {
1487
xdrOp := xdr.RestoreFootprintOp{
1588
Ext: xdr.ExtensionPoint{

txnbuild/restore_footprint_test.go

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
package txnbuild
2+
3+
import (
4+
"testing"
5+
6+
"github.com/stretchr/testify/require"
7+
8+
"github.com/stellar/go/network"
9+
"github.com/stellar/go/strkey"
10+
"github.com/stellar/go/xdr"
11+
)
12+
13+
func TestRestoreAssetBalance(t *testing.T) {
14+
issuer := newKeypair0()
15+
sourceAccount := newKeypair1()
16+
params := AssetBalanceRestorationParams{
17+
NetworkPassphrase: network.PublicNetworkPassphrase,
18+
Contract: "invalid",
19+
Asset: CreditAsset{
20+
Code: "USD",
21+
Issuer: issuer.Address(),
22+
},
23+
SourceAccount: sourceAccount.Address(),
24+
}
25+
_, err := NewAssetBalanceRestoration(params)
26+
require.Error(t, err)
27+
28+
params.Contract = newKeypair2().Address()
29+
_, err = NewAssetBalanceRestoration(params)
30+
require.Error(t, err)
31+
32+
contractID := xdr.Hash{1}
33+
params.Contract = strkey.MustEncode(strkey.VersionByteContract, contractID[:])
34+
35+
op, err := NewAssetBalanceRestoration(params)
36+
require.NoError(t, err)
37+
require.NoError(t, op.Validate())
38+
require.Equal(t, int64(op.Ext.SorobanData.ResourceFee), defaultAssetBalanceRestorationFees.ResourceFee)
39+
require.Equal(t, uint32(op.Ext.SorobanData.Resources.WriteBytes), defaultAssetBalanceRestorationFees.WriteBytes)
40+
require.Equal(t, uint32(op.Ext.SorobanData.Resources.ReadBytes), defaultAssetBalanceRestorationFees.ReadBytes)
41+
require.Equal(t, uint32(op.Ext.SorobanData.Resources.Instructions), defaultAssetBalanceRestorationFees.Instructions)
42+
43+
params.Fees = SorobanFees{
44+
Instructions: 1,
45+
ReadBytes: 2,
46+
WriteBytes: 3,
47+
ResourceFee: 4,
48+
}
49+
50+
op, err = NewAssetBalanceRestoration(params)
51+
require.NoError(t, err)
52+
require.NoError(t, op.Validate())
53+
require.Equal(t, int64(op.Ext.SorobanData.ResourceFee), int64(4))
54+
require.Equal(t, uint32(op.Ext.SorobanData.Resources.WriteBytes), uint32(3))
55+
require.Equal(t, uint32(op.Ext.SorobanData.Resources.ReadBytes), uint32(2))
56+
require.Equal(t, uint32(op.Ext.SorobanData.Resources.Instructions), uint32(1))
57+
}

0 commit comments

Comments
 (0)