Skip to content

Commit 5e779dc

Browse files
committed
[FAB-14147] TokenOwner Validation
Outputs' owners in an issue must be valid. Change-Id: I7732356e3a8aaad3b0d52339bf2b3fa350c5966f Signed-off-by: Angelo De Caro <adc@zurich.ibm.com>
1 parent 91bf19d commit 5e779dc

File tree

3 files changed

+75
-7
lines changed

3 files changed

+75
-7
lines changed

token/tms/manager/validator_test.go

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ SPDX-License-Identifier: Apache-2.0
77
package manager_test
88

99
import (
10+
"github.com/hyperledger/fabric/protos/token"
1011
mockid "github.com/hyperledger/fabric/token/identity/mock"
1112
"github.com/hyperledger/fabric/token/tms/manager"
1213
. "github.com/onsi/ginkgo"
@@ -20,6 +21,7 @@ var _ = Describe("AllIssuingValidator", func() {
2021
fakeIdentityDeserializer *mockid.Deserializer
2122
fakeIdentity *mockid.Identity
2223
policyValidator *manager.AllIssuingValidator
24+
tokenOwnerValidator *manager.FabricTokenOwnerValidator
2325
)
2426

2527
BeforeEach(func() {
@@ -30,6 +32,9 @@ var _ = Describe("AllIssuingValidator", func() {
3032
policyValidator = &manager.AllIssuingValidator{
3133
Deserializer: fakeIdentityDeserializer,
3234
}
35+
tokenOwnerValidator = &manager.FabricTokenOwnerValidator{
36+
Deserializer: fakeIdentityDeserializer,
37+
}
3338
})
3439

3540
Describe("Validate", func() {
@@ -76,4 +81,56 @@ var _ = Describe("AllIssuingValidator", func() {
7681
})
7782

7883
})
84+
85+
Describe("Token Owner Validation", func() {
86+
87+
Context("when owner is valid", func() {
88+
BeforeEach(func() {
89+
fakeIdentityDeserializer.DeserializeIdentityReturns(fakeIdentity, nil)
90+
})
91+
It("returns nil", func() {
92+
err := tokenOwnerValidator.Validate(&token.TokenOwner{Type: token.TokenOwner_MSP_IDENTIFIER, Raw: []byte{0, 1, 2, 3}})
93+
Expect(err).ToNot(HaveOccurred())
94+
})
95+
})
96+
97+
Context("when owner is nil", func() {
98+
It("returns no error", func() {
99+
err := tokenOwnerValidator.Validate(nil)
100+
Expect(err).To(MatchError("identity cannot be nil"))
101+
})
102+
})
103+
104+
Context("when owner has an invalid type", func() {
105+
It("returns no error", func() {
106+
err := tokenOwnerValidator.Validate(&token.TokenOwner{Type: 2})
107+
Expect(err).To(MatchError("identity's type '2' not recognized"))
108+
})
109+
})
110+
111+
Context("when the owner cannot be deserialized", func() {
112+
BeforeEach(func() {
113+
fakeIdentityDeserializer.DeserializeIdentityReturns(nil, errors.New("Deserialize, no-way-man"))
114+
})
115+
116+
It("returns an error", func() {
117+
err := tokenOwnerValidator.Validate(&token.TokenOwner{Type: token.TokenOwner_MSP_IDENTIFIER, Raw: []byte{0, 1, 2, 3}})
118+
Expect(err.Error()).To(BeEquivalentTo("identity [0x7261773a225c3030305c3030315c3030325c3030332220] cannot be deserialised: Deserialize, no-way-man"))
119+
})
120+
})
121+
122+
Context("when identity validation fail", func() {
123+
BeforeEach(func() {
124+
fakeIdentity.ValidateReturns(errors.New("Validate, no-way-man"))
125+
fakeIdentityDeserializer.DeserializeIdentityReturns(fakeIdentity, nil)
126+
})
127+
128+
It("returns an error", func() {
129+
err := tokenOwnerValidator.Validate(&token.TokenOwner{Type: token.TokenOwner_MSP_IDENTIFIER, Raw: []byte{0, 1, 2, 3}})
130+
Expect(err.Error()).To(BeEquivalentTo("identity [0x7261773a225c3030305c3030315c3030325c3030332220] cannot be validated: Validate, no-way-man"))
131+
})
132+
133+
})
134+
135+
})
79136
})

token/tms/plain/verifier.go

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@ package plain
88

99
import (
1010
"bytes"
11-
"encoding/hex"
1211
"fmt"
1312
"strconv"
1413
"strings"
@@ -111,8 +110,9 @@ func (v *Verifier) checkImportOutputs(outputs []*token.PlainOutput, txID string,
111110
return &customtx.InvalidTxError{Msg: fmt.Sprintf("output %d quantity is 0 in transaction: %s", i, txID)}
112111
}
113112

114-
if output.Owner == nil {
115-
return &customtx.InvalidTxError{Msg: fmt.Sprintf("missing owner in output for txID '%s'", txID)}
113+
err = v.TokenOwnerValidator.Validate(output.Owner)
114+
if err != nil {
115+
return &customtx.InvalidTxError{Msg: fmt.Sprintf("invalid owner in output for txID '%s', err '%s'", txID, err)}
116116
}
117117
}
118118
return nil
@@ -142,8 +142,6 @@ func (v *Verifier) checkRedeemAction(creator identity.PublicInfo, redeemAction *
142142

143143
// if output[1] presents, its owner must be same as the creator
144144
if len(outputs) == 2 && !bytes.Equal(creator.Public(), outputs[1].Owner.Raw) {
145-
println(hex.EncodeToString(creator.Public()))
146-
println(hex.EncodeToString(outputs[1].Owner.Raw))
147145
return &customtx.InvalidTxError{Msg: fmt.Sprintf("wrong owner for remaining tokens, should be original owner %s, but got %s", creator.Public(), outputs[1].Owner.Raw)}
148146
}
149147

token/tms/plain/verifier_test.go

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -199,7 +199,19 @@ var _ = Describe("Verifier", func() {
199199

200200
It("returns an InvalidTxError", func() {
201201
err := verifier.ProcessTx(importTxID, fakePublicInfo, importTransaction, memoryLedger)
202-
Expect(err).To(Equal(&customtx.InvalidTxError{Msg: fmt.Sprintf("missing owner in output for txID '%s'", importTxID)}))
202+
Expect(err).To(Equal(&customtx.InvalidTxError{Msg: fmt.Sprintf("invalid owner in output for txID '%s', err 'owner is nil'", importTxID)}))
203+
})
204+
})
205+
206+
Context("when an output has empty owner", func() {
207+
BeforeEach(func() {
208+
importTransaction.GetPlainAction().GetPlainImport().Outputs[0].Owner = &token.TokenOwner{}
209+
importTxID = "no-owner-id"
210+
})
211+
212+
It("returns an InvalidTxError", func() {
213+
err := verifier.ProcessTx(importTxID, fakePublicInfo, importTransaction, memoryLedger)
214+
Expect(err).To(Equal(&customtx.InvalidTxError{Msg: fmt.Sprintf("invalid owner in output for txID '%s', err 'raw is empty'", importTxID)}))
203215
})
204216
})
205217

@@ -935,7 +947,8 @@ func (TestTokenOwnerValidator) Validate(owner *token.TokenOwner) error {
935947
}
936948

937949
if len(owner.Raw) == 0 {
938-
return errors.New("raw is emptyr")
950+
return errors.New("raw is empty")
939951
}
952+
940953
return nil
941954
}

0 commit comments

Comments
 (0)