Skip to content

Commit b7d4c3c

Browse files
committed
[FAB-11526] Prover: Request Transfer
This change-set does the following: - Impliments support for the SignedCommand related to a request trasnfer - Local interfaces have been introduces to reduce dependency from TMS Change-Id: I8501cda493a5cb04ac3a02e2e992aad01031dba9 Signed-off-by: Angelo De Caro <adc@zurich.ibm.com> Signed-off-by: Mathias Bjoerkqvist <mbj@zurich.ibm.com>
1 parent 59f419d commit b7d4c3c

File tree

9 files changed

+295
-73
lines changed

9 files changed

+295
-73
lines changed

protos/token/prover.pb.go

Lines changed: 70 additions & 69 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

protos/token/prover.proto

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ message ImportRequest {
7171
message TransferRequest {
7272
bytes credential = 1;
7373

74-
repeated bytes tokenIDs = 2;
74+
repeated bytes token_ids = 2;
7575

7676
repeated RecipientTransferShare shares = 3;
7777
}

token/client/prover.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ func (prover *ProverPeer) RequestTransfer(
5757

5858
tr := &token.TransferRequest{
5959
Shares: shares,
60-
TokenIDs: tokenIDs,
60+
TokenIds: tokenIDs,
6161
}
6262
payload := &token.Command_TransferRequest{TransferRequest: tr}
6363

token/client/prover_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -197,7 +197,7 @@ func prepareInputsForRequestTransfer(t *testing.T) ([][]byte, []*token.Recipient
197197

198198
tr := &token.TransferRequest{
199199
Shares: shares,
200-
TokenIDs: tokenIDs,
200+
TokenIds: tokenIDs,
201201
}
202202

203203
nonce := make([]byte, 32)

token/server/mock/transactor.go

Lines changed: 66 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

token/server/prover.go

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,8 @@ func (s *Prover) ProcessCommand(ctx context.Context, sc *token.SignedCommand) (*
5555
switch t := command.GetPayload().(type) {
5656
case *token.Command_ImportRequest:
5757
payload, err = s.RequestImport(ctx, command.Header, t.ImportRequest)
58+
case *token.Command_TransferRequest:
59+
payload, err = s.RequestTransfer(ctx, command.Header, t.TransferRequest)
5860
case *token.Command_ListRequest:
5961
payload, err = s.ListUnspentTokens(ctx, command.Header, t.ListRequest)
6062
default:
@@ -84,6 +86,20 @@ func (s *Prover) RequestImport(ctx context.Context, header *token.Header, reques
8486
return &token.CommandResponse_TokenTransaction{TokenTransaction: tokenTransaction}, nil
8587
}
8688

89+
func (s *Prover) RequestTransfer(ctx context.Context, header *token.Header, request *token.TransferRequest) (*token.CommandResponse_TokenTransaction, error) {
90+
transactor, err := s.TMSManager.GetTransactor(header.ChannelId, request.Credential, header.Creator)
91+
if err != nil {
92+
return nil, err
93+
}
94+
95+
tokenTransaction, err := transactor.RequestTransfer(request)
96+
if err != nil {
97+
return nil, err
98+
}
99+
100+
return &token.CommandResponse_TokenTransaction{TokenTransaction: tokenTransaction}, nil
101+
}
102+
87103
func (s *Prover) ListUnspentTokens(ctxt context.Context, header *token.Header, listRequest *token.ListRequest) (*token.CommandResponse_UnspentTokens, error) {
88104
transactor, err := s.TMSManager.GetTransactor(header.ChannelId, listRequest.Credential, header.Creator)
89105
if err != nil {

token/server/prover_test.go

Lines changed: 130 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,9 @@ var _ = Describe("Prover", func() {
4646
tokenTransaction *token.TokenTransaction
4747
marshaledResponse *token.SignedCommandResponse
4848

49+
transferRequest *token.TransferRequest
50+
trTokenTransaction *token.TokenTransaction
51+
4952
listRequest *token.ListRequest
5053
unspentTokens *token.UnspentTokens
5154
transactorTokens []*token.TokenOutput
@@ -72,13 +75,34 @@ var _ = Describe("Prover", func() {
7275
fakeIssuer = &mock.Issuer{}
7376
fakeIssuer.RequestImportReturns(tokenTransaction, nil)
7477

78+
trTokenTransaction = &token.TokenTransaction{
79+
Action: &token.TokenTransaction_PlainAction{
80+
PlainAction: &token.PlainTokenAction{
81+
Data: &token.PlainTokenAction_PlainTransfer{
82+
PlainTransfer: &token.PlainTransfer{
83+
Inputs: []*token.InputId{{
84+
TxId: []byte("txid"),
85+
Index: 0,
86+
}},
87+
Outputs: []*token.PlainOutput{{
88+
Owner: []byte("token-owner"),
89+
Type: "PDQ",
90+
Quantity: 777,
91+
}},
92+
},
93+
},
94+
},
95+
},
96+
}
97+
fakeTransactor = &mock.Transactor{}
98+
fakeTransactor.RequestTransferReturns(trTokenTransaction, nil)
99+
75100
transactorTokens = []*token.TokenOutput{
76101
{Id: []byte("idaz"), Type: "typeaz", Quantity: 135},
77102
{Id: []byte("idby"), Type: "typeby", Quantity: 79},
78103
}
79104
unspentTokens = &token.UnspentTokens{Tokens: transactorTokens}
80105

81-
fakeTransactor = &mock.Transactor{}
82106
fakeTransactor.ListTokensReturns(unspentTokens, nil)
83107

84108
fakeTMSManager = &mock.TMSManager{}
@@ -119,6 +143,15 @@ var _ = Describe("Prover", func() {
119143
Signature: []byte("command-signature"),
120144
}
121145

146+
transferRequest = &token.TransferRequest{
147+
Credential: []byte("credential"),
148+
TokenIds: [][]byte{},
149+
Shares: []*token.RecipientTransferShare{{
150+
Recipient: []byte("recipient"),
151+
Quantity: 99,
152+
}},
153+
}
154+
122155
listRequest = &token.ListRequest{
123156
Credential: []byte("credential"),
124157
}
@@ -281,6 +314,55 @@ var _ = Describe("Prover", func() {
281314
})
282315
})
283316

317+
Describe("ProcessCommand_RequestImport", func() {
318+
It("returns a signed command response", func() {
319+
resp, err := prover.ProcessCommand(context.Background(), signedCommand)
320+
Expect(err).NotTo(HaveOccurred())
321+
Expect(resp).To(Equal(marshaledResponse))
322+
323+
Expect(fakeMarshaler.MarshalCommandResponseCallCount()).To(Equal(1))
324+
cmd, payload := fakeMarshaler.MarshalCommandResponseArgsForCall(0)
325+
Expect(cmd).To(Equal(marshaledCommand))
326+
Expect(payload).To(Equal(&token.CommandResponse_TokenTransaction{
327+
TokenTransaction: tokenTransaction,
328+
}))
329+
})
330+
})
331+
332+
Describe("ProcessCommand_RequestTransfer", func() {
333+
BeforeEach(func() {
334+
command = &token.Command{
335+
Header: &token.Header{
336+
ChannelId: "channel-id",
337+
Creator: []byte("creator"),
338+
Nonce: []byte("nonce"),
339+
},
340+
Payload: &token.Command_TransferRequest{
341+
TransferRequest: transferRequest,
342+
},
343+
}
344+
marshaledCommand = ProtoMarshal(command)
345+
signedCommand = &token.SignedCommand{
346+
Command: marshaledCommand,
347+
Signature: []byte("command-signature"),
348+
}
349+
fakeMarshaler.MarshalCommandResponseReturns(marshaledResponse, nil)
350+
})
351+
352+
It("returns a signed command response", func() {
353+
resp, err := prover.ProcessCommand(context.Background(), signedCommand)
354+
Expect(err).NotTo(HaveOccurred())
355+
Expect(resp).To(Equal(marshaledResponse))
356+
357+
Expect(fakeMarshaler.MarshalCommandResponseCallCount()).To(Equal(1))
358+
cmd, payload := fakeMarshaler.MarshalCommandResponseArgsForCall(0)
359+
Expect(cmd).To(Equal(marshaledCommand))
360+
Expect(payload).To(Equal(&token.CommandResponse_TokenTransaction{
361+
TokenTransaction: trTokenTransaction,
362+
}))
363+
})
364+
})
365+
284366
Describe("Process RequestImport command", func() {
285367
It("returns a signed command response", func() {
286368
resp, err := prover.ProcessCommand(context.Background(), signedCommand)
@@ -376,6 +458,53 @@ var _ = Describe("Prover", func() {
376458
})
377459
})
378460

461+
Describe("RequestTransfer", func() {
462+
It("gets a transactor", func() {
463+
_, err := prover.RequestTransfer(context.Background(), command.Header, transferRequest)
464+
Expect(err).NotTo(HaveOccurred())
465+
466+
Expect(fakeTMSManager.GetTransactorCallCount()).To(Equal(1))
467+
channel, cred, creator := fakeTMSManager.GetTransactorArgsForCall(0)
468+
Expect(channel).To(Equal("channel-id"))
469+
Expect(cred).To(Equal([]byte("credential")))
470+
Expect(creator).To(Equal([]byte("creator")))
471+
})
472+
473+
It("uses the transactor to request a transfer", func() {
474+
resp, err := prover.RequestTransfer(context.Background(), command.Header, transferRequest)
475+
Expect(err).NotTo(HaveOccurred())
476+
Expect(resp).To(Equal(&token.CommandResponse_TokenTransaction{
477+
TokenTransaction: trTokenTransaction,
478+
}))
479+
480+
Expect(fakeTransactor.RequestTransferCallCount()).To(Equal(1))
481+
tr := fakeTransactor.RequestTransferArgsForCall(0)
482+
Expect(tr).To(Equal(transferRequest))
483+
})
484+
485+
Context("when the TMS manager fails to get a transactor", func() {
486+
BeforeEach(func() {
487+
fakeTMSManager.GetTransactorReturns(nil, errors.New("boing boing"))
488+
})
489+
490+
It("retuns the error", func() {
491+
_, err := prover.RequestTransfer(context.Background(), command.Header, transferRequest)
492+
Expect(err).To(MatchError("boing boing"))
493+
})
494+
})
495+
496+
Context("when the transactor fails to transfer", func() {
497+
BeforeEach(func() {
498+
fakeTransactor.RequestTransferReturns(nil, errors.New("watermelon"))
499+
})
500+
501+
It("retuns the error", func() {
502+
_, err := prover.RequestTransfer(context.Background(), command.Header, transferRequest)
503+
Expect(err).To(MatchError("watermelon"))
504+
})
505+
})
506+
})
507+
379508
Describe("Issue tokens by a plain issuer", func() {
380509
var (
381510
manager *server.Manager

token/server/tms.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,11 @@ type Issuer interface {
2121

2222
// Transactor allows to operate on issued tokens
2323
type Transactor interface {
24+
// RequestTransfer Create data associated to the transfer of a token assuming
25+
// an application-level identity. The inTokens bytes are the identifiers
26+
// of the outputs, the details of which need to be looked up from the ledger.
27+
RequestTransfer(request *token.TransferRequest) (*token.TokenTransaction, error)
28+
2429
// ListTokens returns a slice of unspent tokens owned by this transactor
2530
ListTokens() (*token.UnspentTokens, error)
2631
}

token/tms/plain/transactor.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,11 @@ type Transactor struct {
2626
Ledger ledger.LedgerReader
2727
}
2828

29+
// RequestTransfer creates a TokenTransaction of type transfer request
30+
func (t *Transactor) RequestTransfer(request *token.TransferRequest) (*token.TokenTransaction, error) {
31+
panic("not implemented!")
32+
}
33+
2934
// ListTokens creates a TokenTransaction that lists the unspent tokens owned by owner.
3035
func (t *Transactor) ListTokens() (*token.UnspentTokens, error) {
3136
iterator, err := t.Ledger.GetStateRangeScanIterator(namespace, "", "")

0 commit comments

Comments
 (0)