Skip to content
This repository was archived by the owner on Apr 13, 2022. It is now read-only.

Commit 95a0510

Browse files
airvinNick Waywood
andcommitted
Implemented the stateQueryIterator functions hasNext and next
Co-authored-by: Nick Waywood <n.waywood@github.com> Signed-off-by: Allison Irvin <allison.irvin2@gmail.com>
1 parent 0f57360 commit 95a0510

File tree

6 files changed

+55
-15
lines changed

6 files changed

+55
-15
lines changed

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,3 +3,6 @@ fabric-chaincode-haskell.cabal
33
*~
44
dist-newstyle
55
cabal.project.local
6+
7+
.vscode
8+
hie.yaml

examples/Marbles.hs

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,14 +19,19 @@ import Shim ( start
1919
, ChaincodeStub(..)
2020
, ChaincodeStubInterface(..)
2121
, DefaultChaincodeStub
22+
, StateQueryIterator(..)
23+
, StateQueryIteratorInterface(..)
24+
, Error(..)
2225
)
2326

2427
import Peer.ProposalResponse as Pb
2528

2629
import Data.Text ( Text
2730
, unpack
2831
, pack
32+
, append
2933
)
34+
import qualified Data.Text.Encoding as TSE
3035
import qualified Data.ByteString as BS
3136
import qualified Data.ByteString.UTF8 as BSU
3237
import qualified Data.ByteString.Lazy as LBS
@@ -167,9 +172,18 @@ getMarblesByRange s params = if Prelude.length params == 2
167172
e <- getStateByRange s (params !! 0) (params !! 1)
168173
case e of
169174
Left _ -> pure $ errorPayload "Failed to get marbles"
170-
Right a -> trace (show a) (pure $ successPayload Nothing)
171-
else pure $ errorPayload
172-
"Incorrect arguments. Need a start key and an end key"
175+
Right sqi -> do
176+
resultBytes <- generateResultBytes sqi ""
177+
trace (show resultBytes) (pure $ successPayload Nothing)
178+
else pure $ errorPayload "Incorrect arguments. Need a start key and an end key"
179+
180+
generateResultBytes :: StateQueryIterator -> Text -> IO (Either Error BSU.ByteString)
181+
generateResultBytes sqi text = do
182+
hasNextBool <- hasNext sqi
183+
if hasNextBool then do
184+
eeKV <- next sqi
185+
generateResultBytes sqi (append text "abc")
186+
else pure $ Right $ TSE.encodeUtf8 text
173187

174188
parseMarble :: [Text] -> Marble
175189
parseMarble params = Marble { objectType = "marble"

src/Interfaces.hs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ class ChaincodeStubInterface ccs where
6868
class StateQueryIteratorInterface sqi where
6969
-- -- hasNext provides information on current status of the iterator and whether there are
7070
-- -- more elements in the collection key-value pairs returned by the result.
71-
hasNext :: sqi -> Bool
71+
hasNext :: sqi -> IO Bool
7272
-- -- close terminantes the iteration.
7373
close :: sqi -> IO (Maybe Error)
7474
-- -- Provides the next key-value pair pointed by the iterator

src/Shim.hs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@ module Shim
1010
, errorPayload
1111
, successPayload
1212
, ChaincodeStubInterface(..)
13+
, StateQueryIterator(..)
14+
, StateQueryIteratorInterface(..)
1315
)
1416
where
1517

@@ -36,12 +38,15 @@ import Peer.Proposal as Pb
3638
import Peer.ProposalResponse as Pb
3739

3840
import Stub
39-
import Interfaces ( ChaincodeStubInterface(..) )
41+
import Interfaces ( ChaincodeStubInterface(..)
42+
, StateQueryIteratorInterface(..)
43+
)
4044
import Messages
4145
import Types ( DefaultChaincodeStub(..)
4246
, Error(..)
4347
, ChaincodeStub(..)
4448
, MapTextBytes
49+
, StateQueryIterator(..)
4550
)
4651

4752
import Debug.Trace

src/Stub.hs

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ import Data.IORef (readIORef, newIORef, modifyIORef
2727
import Control.Monad.Except (ExceptT(..), runExceptT)
2828

2929
import qualified Peer.ChaincodeShim as Pb
30+
import qualified Ledger.Queryresult.KvQueryResult as Pb
3031

3132
import Network.GRPC.HighLevel
3233
import Google.Protobuf.Timestamp as Pb
@@ -134,7 +135,7 @@ instance ChaincodeStubInterface DefaultChaincodeStub where
134135
bsToSqi bs = let eeaQueryResponse = parse (decodeMessage (FieldNumber 1)) bs :: Either ParseError Pb.QueryResponse in
135136
case eeaQueryResponse of
136137
-- TODO: refactor out pattern matching, e.g. using >>= or <*>
137-
Left _ -> ExceptT $ pure $ Left ParseError
138+
Left err -> ExceptT $ pure $ Left $ DecodeError err
138139
Right queryResponse -> ExceptT $ do
139140
-- queryResponse and currentLoc are IORefs as they need to be mutated
140141
-- as a part of the next() function
@@ -156,12 +157,19 @@ instance ChaincodeStubInterface DefaultChaincodeStub where
156157

157158
-- TODO : implement all these interface functions
158159
instance StateQueryIteratorInterface StateQueryIterator where
159-
-- hasNext :: sqi -> Bool
160-
hasNext sqi = True
160+
-- hasNext :: sqi -> IO Bool
161+
hasNext sqi = do
162+
queryResponse <- readIORef $ sqiResponse sqi
163+
currentLoc <- readIORef $ sqiCurrentLoc sqi
164+
pure $ currentLoc < Prelude.length (Pb.queryResponseResults queryResponse) || (Pb.queryResponseHasMore queryResponse)
161165
-- close :: sqi -> IO (Maybe Error)
162166
close _ = pure Nothing
163167
-- next :: sqi -> IO (Either Error Pb.KV)
164-
next _ = pure $ Left $ Error "not implemented"
168+
next sqi = do
169+
eeQueryResultBytes <- nextResult sqi
170+
case eeQueryResultBytes of
171+
Left _ -> pure $ Left $ Error "Error getting next queryResultBytes"
172+
Right queryResultBytes -> pure $ first DecodeError (parse (decodeMessage (FieldNumber 1)) (Pb.queryResultBytesResultBytes queryResultBytes) :: Either ParseError Pb.KV)
165173

166174

167175
nextResult :: StateQueryIterator -> IO (Either Error Pb.QueryResultBytes)
@@ -200,7 +208,7 @@ fetchNextQueryResult sqi = do
200208
Pb.QueryResponse
201209
in case eeaQueryResponse of
202210
-- TODO: refactor out pattern matching, e.g. using >>= or <*>
203-
Left _ -> ExceptT $ pure $ Left ParseError
211+
Left err -> ExceptT $ pure $ Left $ DecodeError err
204212
Right queryResponse -> ExceptT $ do
205213
-- Need to put the new queryResponse in the sqi queryResponse
206214
writeIORef (sqiCurrentLoc sqi) 0

src/Types.hs

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,15 @@ module Types where
22

33
import Data.ByteString
44
import Data.Map
5-
import Data.Vector
5+
import qualified Data.Vector
66
import Data.Text
77
import Data.IORef
88
import System.IO.Unsafe
99

1010
import Network.GRPC.HighLevel.Generated
1111
import Proto3.Suite
12+
import Proto3.Wire.Decode
13+
1214
import Network.GRPC.HighLevel
1315

1416
import Peer.ChaincodeShim as Pb
@@ -19,7 +21,7 @@ import Peer.ProposalResponse as Pb
1921
data Error = GRPCError GRPCIOError
2022
| InvalidArgs
2123
| Error String
22-
| ParseError
24+
| DecodeError ParseError
2325
deriving (Eq, Show)
2426

2527
data ChaincodeStub = ChaincodeStub {
@@ -34,7 +36,7 @@ data ChaincodeStub = ChaincodeStub {
3436
-- TODO: remove all these maybes when the stub is being created properly
3537
data DefaultChaincodeStub = DefaultChaincodeStub {
3638
-- chaincode invocation arguments. serialised as arrays of bytes.
37-
args :: Vector ByteString,
39+
args :: Data.Vector.Vector ByteString,
3840
-- -- name of the function being invoked.
3941
-- function :: Maybe Text,
4042
-- -- arguments of the function idenfied by the chaincode invocation.
@@ -68,9 +70,17 @@ data StateQueryIterator = StateQueryIterator {
6870
instance (Show a) => Show (IORef a) where
6971
show a = show (unsafePerformIO (readIORef a))
7072

71-
-- TODO: Implement this properly
7273
instance (Show DefaultChaincodeStub) where
73-
show ccs = "Chaincode stub"
74+
show ccs = "Chaincode stub { "
75+
++ show (args ccs) ++ ", "
76+
++ show (txId ccs) ++ ", "
77+
++ show (channelId ccs) ++ ", "
78+
++ show (creator ccs) ++ ", "
79+
++ show (signedProposal ccs) ++ ", "
80+
++ show (proposal ccs) ++ ", "
81+
++ show (transient ccs) ++ ", "
82+
++ show (binding ccs) ++ ", "
83+
++ show (decorations ccs) ++ " }"
7484

7585
-- MapStringBytes is a synonym for the Map type whose keys are String and values
7686
type MapStringBytes = Map String ByteString

0 commit comments

Comments
 (0)