Skip to content

Commit

Permalink
Use isRedeemable to check if redeem is possible
Browse files Browse the repository at this point in the history
  • Loading branch information
martonp committed Dec 7, 2021
1 parent 4fe6304 commit 43c6852
Show file tree
Hide file tree
Showing 2 changed files with 84 additions and 24 deletions.
16 changes: 12 additions & 4 deletions client/asset/eth/eth.go
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,7 @@ type ethFetcher interface {
initiate(ctx context.Context, contracts []*asset.Contract, maxFeeRate uint64, contractVer uint32) (*types.Transaction, error)
shutdown()
syncProgress() ethereum.SyncProgress
isRedeemable(secretHash, secret [32]byte, contractVer uint32) (bool, error)
redeem(ctx context.Context, redemptions []*asset.Redemption, maxFeeRate uint64, contractVer uint32) (*types.Transaction, error)
refund(txOpts *bind.TransactOpts, secretHash [32]byte, contractVer uint32) (*types.Transaction, error)
swap(ctx context.Context, secretHash [32]byte, contractVer uint32) (*dexeth.SwapState, error)
Expand Down Expand Up @@ -684,11 +685,18 @@ func (eth *ExchangeWallet) Redeem(form *asset.RedeemForm) ([]dex.Bytes, asset.Co
inputs := make([]dex.Bytes, 0, len(form.Redemptions))
var redeemedValue uint64
for _, redemption := range form.Redemptions {
var secretHash [32]byte
var secretHash, secret [32]byte
copy(secretHash[:], redemption.Spends.SecretHash)
if secretHash != sha256.Sum256(redemption.Secret) {
return fail(fmt.Errorf("Redeem: secretHash %x != sha256(%x)", secretHash, redemption.Secret))
copy(secret[:], redemption.Secret)
redeemable, err := eth.node.isRedeemable(secretHash, secret, form.AssetVersion)
if err != nil {
return fail(fmt.Errorf("Redeem: failed to check if swap is redeemable: %w", err))
}
if !redeemable {
return fail(fmt.Errorf("Redeem: secretHash %x not redeemable with secret %x",
secretHash, secret))
}

swapData, err := eth.node.swap(eth.ctx, secretHash, form.AssetVersion)
if err != nil {
return nil, nil, 0, fmt.Errorf("Redeem: error finding swap state: %w", err)
Expand All @@ -700,7 +708,7 @@ func (eth *ExchangeWallet) Redeem(form *asset.RedeemForm) ([]dex.Bytes, asset.Co
fundsRequired := dexeth.RedeemGas(len(form.Redemptions), form.AssetVersion) * form.FeeSuggestion

// TODO: make sure the amount we locked for redemption is enough to cover the gas
// fees.
// fees. Also unlock coins.
_, err := eth.node.redeem(eth.ctx, form.Redemptions, form.FeeSuggestion, form.AssetVersion)
if err != nil {
return fail(fmt.Errorf("Redeem: redeem error: %w", err))
Expand Down
92 changes: 72 additions & 20 deletions client/asset/eth/eth_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,8 @@ type testNode struct {
initErr error
redeemErr error
nonce uint64
redeemable bool
isRedeemableErr error
}

func newBalance(current, pending, in, out uint64) *Balance {
Expand Down Expand Up @@ -121,7 +123,9 @@ func (n *testNode) initiate(ctx context.Context, contracts []*asset.Contract, ma
Nonce: n.nonce,
}), nil
}

func (n *testNode) isRedeemable(secretHash [32]byte, secret [32]byte, contractVer uint32) (redeemable bool, err error) {
return n.redeemable, n.isRedeemableErr
}
func (n *testNode) redeem(ctx context.Context, redemptions []*asset.Redemption, maxFeeRate uint64, contractVer uint32) (*types.Transaction, error) {
if n.redeemErr != nil {
return nil, n.redeemErr
Expand Down Expand Up @@ -1172,14 +1176,17 @@ func TestRedeem(t *testing.T) {
addSwapToSwapMap(secretHashes[1], 1e9, dexeth.SSInitiated)

tests := []struct {
name string
form asset.RedeemForm
redeemErr error
expectError bool
name string
form asset.RedeemForm
redeemErr error
isRedeemable bool
isRedeemableErr error
expectError bool
}{
{
name: "ok",
expectError: false,
name: "ok",
expectError: false,
isRedeemable: true,
form: asset.RedeemForm{
Redemptions: []*asset.Redemption{
{
Expand All @@ -1206,9 +1213,9 @@ func TestRedeem(t *testing.T) {
},
},
{
name: "redeem error",
redeemErr: errors.New(""),
expectError: true,
name: "not redeemable",
expectError: true,
isRedeemable: false,
form: asset.RedeemForm{
Redemptions: []*asset.Redemption{
{
Expand All @@ -1220,52 +1227,95 @@ func TestRedeem(t *testing.T) {
},
Secret: secrets[0][:],
},
{
Spends: &asset.AuditInfo{
SecretHash: secretHashes[1][:],
Coin: &coin{
id: encode.RandomBytes(32),
},
},
Secret: secrets[1][:],
},
},
FeeSuggestion: 200,
FeeSuggestion: 100,
AssetVersion: 0,
},
},
{
name: "swap not found in contract",
expectError: true,
name: "isRedeemable error",
expectError: true,
isRedeemable: true,
isRedeemableErr: errors.New(""),
form: asset.RedeemForm{
Redemptions: []*asset.Redemption{
{
Spends: &asset.AuditInfo{
SecretHash: secretHashes[2][:],
SecretHash: secretHashes[0][:],
Coin: &coin{
id: encode.RandomBytes(32),
},
},
Secret: secrets[2][:],
Secret: secrets[0][:],
},
{
Spends: &asset.AuditInfo{
SecretHash: secretHashes[1][:],
Coin: &coin{
id: encode.RandomBytes(32),
},
},
Secret: secrets[1][:],
},
},
FeeSuggestion: 100,
AssetVersion: 0,
},
},
{
name: "hash of secret != secretHash",
expectError: true,
name: "redeem error",
redeemErr: errors.New(""),
isRedeemable: true,
expectError: true,
form: asset.RedeemForm{
Redemptions: []*asset.Redemption{
{
Spends: &asset.AuditInfo{
SecretHash: secretHashes[1][:],
SecretHash: secretHashes[0][:],
Coin: &coin{
id: encode.RandomBytes(32),
},
},
Secret: secrets[0][:],
},
},
FeeSuggestion: 200,
AssetVersion: 0,
},
},
{
name: "swap not found in contract",
isRedeemable: true,
expectError: true,
form: asset.RedeemForm{
Redemptions: []*asset.Redemption{
{
Spends: &asset.AuditInfo{
SecretHash: secretHashes[2][:],
Coin: &coin{
id: encode.RandomBytes(32),
},
},
Secret: secrets[2][:],
},
},
FeeSuggestion: 100,
AssetVersion: 0,
},
},
{
name: "empty redemptions slice error",
expectError: true,
name: "empty redemptions slice error",
isRedeemable: true,
expectError: true,
form: asset.RedeemForm{
Redemptions: []*asset.Redemption{},
FeeSuggestion: 100,
Expand All @@ -1276,6 +1326,8 @@ func TestRedeem(t *testing.T) {

for _, test := range tests {
node.redeemErr = test.redeemErr
node.redeemable = test.isRedeemable
node.isRedeemableErr = test.isRedeemableErr

ins, out, fees, err := eth.Redeem(&test.form)
if test.expectError {
Expand Down

0 comments on commit 43c6852

Please sign in to comment.