Skip to content

Commit

Permalink
move htlc and pledge validator to common
Browse files Browse the repository at this point in the history
Signed-off-by: Angelo De Caro <[email protected]>
  • Loading branch information
adecaro committed Nov 16, 2024
1 parent 97e2c7a commit 6e9c0b5
Show file tree
Hide file tree
Showing 11 changed files with 140 additions and 312 deletions.
87 changes: 87 additions & 0 deletions token/core/common/validator_htlc.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
/*
Copyright IBM Corp. All Rights Reserved.
SPDX-License-Identifier: Apache-2.0
*/

package common

import (
"encoding/json"
"time"

"github.com/hyperledger-labs/fabric-token-sdk/token/driver"
"github.com/hyperledger-labs/fabric-token-sdk/token/services/identity"
"github.com/hyperledger-labs/fabric-token-sdk/token/services/interop/htlc"
"github.com/pkg/errors"
)

// TransferHTLCValidate checks the validity of the HTLC scripts, if any
func TransferHTLCValidate[P driver.PublicParameters, T driver.Output, TA driver.TransferAction, IA driver.IssueAction](ctx *Context[P, T, TA, IA]) error {

Check failure on line 20 in token/core/common/validator_htlc.go

View workflow job for this annotation

GitHub Actions / lint

not enough type arguments for type Context: have 4, want 5

Check failure on line 20 in token/core/common/validator_htlc.go

View workflow job for this annotation

GitHub Actions / checks

not enough type arguments for type Context: have 4, want 5
now := time.Now()

for i, in := range ctx.InputTokens {

Check failure on line 23 in token/core/common/validator_htlc.go

View workflow job for this annotation

GitHub Actions / lint

ctx.InputTokens undefined (type *Context[P, T, TA, IA] has no field or method InputTokens)

Check failure on line 23 in token/core/common/validator_htlc.go

View workflow job for this annotation

GitHub Actions / checks

ctx.InputTokens undefined (type *Context[P, T, TA, IA] has no field or method InputTokens)
owner, err := identity.UnmarshalTypedIdentity(in.GetOwner())
if err != nil {
return errors.Wrap(err, "failed to unmarshal owner of input token")
}
// is it owned by an htlc script?
if owner.Type == htlc.ScriptType {
// Then, the first output must be compatible with this input.
if len(ctx.TransferAction.GetOutputs()) != 1 {

Check failure on line 31 in token/core/common/validator_htlc.go

View workflow job for this annotation

GitHub Actions / lint

ctx.TransferAction undefined (type *Context[P, T, TA, IA] has no field or method TransferAction)

Check failure on line 31 in token/core/common/validator_htlc.go

View workflow job for this annotation

GitHub Actions / checks

ctx.TransferAction undefined (type *Context[P, T, TA, IA] has no field or method TransferAction)
return errors.New("invalid transfer action: an htlc script only transfers the ownership of a token")
}

// check it is not a redeem
output := ctx.TransferAction.GetOutputs()[0]

Check failure on line 36 in token/core/common/validator_htlc.go

View workflow job for this annotation

GitHub Actions / lint

ctx.TransferAction undefined (type *Context[P, T, TA, IA] has no field or method TransferAction)

Check failure on line 36 in token/core/common/validator_htlc.go

View workflow job for this annotation

GitHub Actions / checks

ctx.TransferAction undefined (type *Context[P, T, TA, IA] has no field or method TransferAction)
if output.IsRedeem() {
return errors.New("invalid transfer action: the output corresponding to an htlc spending should not be a redeem")
}

// check that owner field in output is correct
script, op, err := htlc.VerifyOwner(ctx.InputTokens[0].GetOwner(), output.GetOwner(), now)

Check failure on line 42 in token/core/common/validator_htlc.go

View workflow job for this annotation

GitHub Actions / lint

ctx.InputTokens undefined (type *Context[P, T, TA, IA] has no field or method InputTokens)

Check failure on line 42 in token/core/common/validator_htlc.go

View workflow job for this annotation

GitHub Actions / checks

ctx.InputTokens undefined (type *Context[P, T, TA, IA] has no field or method InputTokens)
if err != nil {
return errors.Wrap(err, "failed to verify transfer from htlc script")
}

// check metadata
sigma := ctx.Signatures[i]

Check failure on line 48 in token/core/common/validator_htlc.go

View workflow job for this annotation

GitHub Actions / lint

ctx.Signatures undefined (type *Context[P, T, TA, IA] has no field or method Signatures)

Check failure on line 48 in token/core/common/validator_htlc.go

View workflow job for this annotation

GitHub Actions / checks

ctx.Signatures undefined (type *Context[P, T, TA, IA] has no field or method Signatures)
metadataKey, err := htlc.MetadataClaimKeyCheck(ctx.TransferAction, script, op, sigma)

Check failure on line 49 in token/core/common/validator_htlc.go

View workflow job for this annotation

GitHub Actions / lint

ctx.TransferAction undefined (type *Context[P, T, TA, IA] has no field or method TransferAction)

Check failure on line 49 in token/core/common/validator_htlc.go

View workflow job for this annotation

GitHub Actions / checks

ctx.TransferAction undefined (type *Context[P, T, TA, IA] has no field or method TransferAction)
if err != nil {
return errors.WithMessagef(err, "failed to check htlc metadata")
}
if op != htlc.Reclaim {
ctx.CountMetadataKey(metadataKey)
}
}
}

for _, out := range ctx.TransferAction.GetOutputs() {

Check failure on line 59 in token/core/common/validator_htlc.go

View workflow job for this annotation

GitHub Actions / lint

ctx.TransferAction undefined (type *Context[P, T, TA, IA] has no field or method TransferAction)

Check failure on line 59 in token/core/common/validator_htlc.go

View workflow job for this annotation

GitHub Actions / checks

ctx.TransferAction undefined (type *Context[P, T, TA, IA] has no field or method TransferAction)
if out.IsRedeem() {
continue
}

// if it is an htlc script then the deadline must still be valid
owner, err := identity.UnmarshalTypedIdentity(out.GetOwner())
if err != nil {
return err
}
if owner.Type == htlc.ScriptType {
script := &htlc.Script{}
err = json.Unmarshal(owner.Identity, script)
if err != nil {
return err
}
if err := script.Validate(now); err != nil {
return errors.WithMessagef(err, "htlc script invalid")
}
metadataKey, err := htlc.MetadataLockKeyCheck(ctx.TransferAction, script)

Check failure on line 78 in token/core/common/validator_htlc.go

View workflow job for this annotation

GitHub Actions / lint

ctx.TransferAction undefined (type *Context[P, T, TA, IA] has no field or method TransferAction)

Check failure on line 78 in token/core/common/validator_htlc.go

View workflow job for this annotation

GitHub Actions / checks

ctx.TransferAction undefined (type *Context[P, T, TA, IA] has no field or method TransferAction)
if err != nil {
return errors.WithMessagef(err, "failed to check htlc metadata")
}
ctx.CountMetadataKey(metadataKey)
continue
}
}
return nil
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,40 +4,39 @@ Copyright IBM Corp. All Rights Reserved.
SPDX-License-Identifier: Apache-2.0
*/

package validator
package common

import (
"bytes"
"encoding/json"
"fmt"
"time"

"github.com/hyperledger-labs/fabric-token-sdk/token/core/zkatdlog/crypto/token"
"github.com/hyperledger-labs/fabric-token-sdk/token/core/zkatdlog/crypto/transfer"
"github.com/hyperledger-labs/fabric-token-sdk/token/driver"
"github.com/hyperledger-labs/fabric-token-sdk/token/services/identity"
"github.com/hyperledger-labs/fabric-token-sdk/token/services/interop/pledge"
"github.com/pkg/errors"
)

func IssuePledgeValidate(ctx *Context) error {
for k := range ctx.IssueAction.Metadata {
func IssuePledgeValidate[P driver.PublicParameters, T driver.Output, TA driver.TransferAction, IA driver.IssueAction](ctx *Context[P, T, TA, IA]) error {

Check failure on line 21 in token/core/common/validator_pledge.go

View workflow job for this annotation

GitHub Actions / lint

not enough type arguments for type Context: have 4, want 5

Check failure on line 21 in token/core/common/validator_pledge.go

View workflow job for this annotation

GitHub Actions / checks

not enough type arguments for type Context: have 4, want 5
for k := range ctx.IssueAction.GetMetadata() {
ctx.CountMetadataKey(k)
}
return nil
}

func TransferPledgeValidate(ctx *Context) error {
func TransferPledgeValidate[P driver.PublicParameters, T driver.Output, TA driver.TransferAction, IA driver.IssueAction](ctx *Context[P, T, TA, IA]) error {
for _, in := range ctx.InputTokens {
id, err := identity.UnmarshalTypedIdentity(in.Owner)
id, err := identity.UnmarshalTypedIdentity(in.GetOwner())
if err != nil {
return errors.Wrap(err, "failed to unmarshal owner of input token")
}
if id.Type == pledge.ScriptType {
if len(ctx.InputTokens) != 1 || len(ctx.TransferAction.GetOutputs()) != 1 {
return errors.Errorf("invalid transfer action: a pledge script only transfers the ownership of a token")
}
out := ctx.TransferAction.GetOutputs()[0].(*token.Token)
sender, err := identity.UnmarshalTypedIdentity(ctx.InputTokens[0].Owner)
out := ctx.TransferAction.GetOutputs()[0]
sender, err := identity.UnmarshalTypedIdentity(ctx.InputTokens[0].GetOwner())
if err != nil {
return err
}
Expand Down Expand Up @@ -67,7 +66,7 @@ func TransferPledgeValidate(ctx *Context) error {
ctx.CountMetadataKey(redeemKey)
continue
}
if !script.Sender.Equal(out.Owner) {
if !script.Sender.Equal(out.GetOwner()) {
return errors.New("recipient of token does not correspond to sender of reclaim request")
}

Expand All @@ -83,15 +82,11 @@ func TransferPledgeValidate(ctx *Context) error {
}
}

for _, o := range ctx.TransferAction.GetOutputs() {
out, ok := o.(*token.Token)
if !ok {
return errors.Errorf("invalid output")
}
for _, out := range ctx.TransferAction.GetOutputs() {
if out.IsRedeem() {
continue
}
owner, err := identity.UnmarshalTypedIdentity(out.Owner)
owner, err := identity.UnmarshalTypedIdentity(out.GetOwner())
if err != nil {
return err
}
Expand All @@ -117,7 +112,7 @@ func TransferPledgeValidate(ctx *Context) error {
return nil
}

func constructMetadataKey(action *transfer.Action) (string, error) {
func constructMetadataKey(action driver.TransferAction) (string, error) {
inputs, err := action.GetInputs()
if err != nil {
return "", errors.Wrap(err, "failed to retrieve input IDs from action")
Expand Down
4 changes: 4 additions & 0 deletions token/core/fabtoken/actions.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,10 @@ func (t *Output) IsRedeem() bool {
return len(t.Output.Owner.Raw) == 0
}

func (t *Output) GetOwner() []byte {
return t.Output.Owner.Raw
}

// IssueAction encodes a fabtoken Issue
type IssueAction struct {
// issuer's public key
Expand Down
6 changes: 3 additions & 3 deletions token/core/fabtoken/validator.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,14 +49,14 @@ func NewValidator(logger logging.Logger, pp *PublicParams, deserializer driver.D
transferValidators := []ValidateTransferFunc{
TransferSignatureValidate,
TransferBalanceValidate,
TransferHTLCValidate,
TransferPledgeValidate,
common.TransferHTLCValidate[*PublicParams, *token.Token, *TransferAction, *IssueAction],
common.TransferPledgeValidate[*PublicParams, *token.Token, *TransferAction, *IssueAction],
}
transferValidators = append(transferValidators, extraValidators...)

issueValidators := []ValidateIssueFunc{
IssueValidate,
IssuePledgeValidate,
common.IssuePledgeValidate[*PublicParams, *token.Token, *TransferAction, *IssueAction],
}

return common.NewValidator[*PublicParams, *token.Token, *TransferAction, *IssueAction](
Expand Down
129 changes: 0 additions & 129 deletions token/core/fabtoken/validator_pledge.go

This file was deleted.

Loading

0 comments on commit 6e9c0b5

Please sign in to comment.