{-# LANGUAGE TemplateHaskell #-}
module Network.ABCI.Types.Messages.Response where
import Control.Lens (iso, traverse, (&),
(.~), (^.), (^..),
(^?), _Just)
import Control.Lens.Wrapped (Wrapped (..),
_Unwrapped')
import Data.Aeson (FromJSON (..),
ToJSON (..),
genericParseJSON,
genericToJSON,
withObject, (.!=),
(.:), (.:?))
import Data.ByteArray.Base64String (Base64String)
import qualified Data.ByteArray.Base64String as Base64
import Data.ByteArray.HexString (HexString)
import qualified Data.ByteArray.HexString as Hex
import Data.Default.Class (Default (..))
import Data.Int (Int64)
import Data.ProtoLens.Message (Message (defMessage))
import Data.Text (Text)
import Data.Word (Word32, Word64)
import GHC.Generics (Generic)
import Network.ABCI.Types.Messages.Common (defaultABCIOptions,
makeABCILenses)
import Network.ABCI.Types.Messages.FieldTypes (ConsensusParams, Event,
Proof, ValidatorUpdate,
WrappedVal (..))
import qualified Proto.Types as PT
import qualified Proto.Types_Fields as PT
data Echo = Echo
{ echoMessage :: Text
} deriving (Eq, Show, Generic)
makeABCILenses ''Echo
instance ToJSON Echo where
toJSON = genericToJSON $ defaultABCIOptions "echo"
instance FromJSON Echo where
parseJSON = genericParseJSON $ defaultABCIOptions "echo"
instance Wrapped Echo where
type Unwrapped Echo = PT.ResponseEcho
_Wrapped' = iso t f
where
t Echo {..} = defMessage & PT.message .~ echoMessage
f message = Echo { echoMessage = message ^. PT.message }
instance Default Echo where
def = defMessage ^. _Unwrapped'
data Flush =
Flush deriving (Eq, Show, Generic)
instance ToJSON Flush where
toJSON = genericToJSON $ defaultABCIOptions "flush"
instance FromJSON Flush where
parseJSON = genericParseJSON $ defaultABCIOptions "flush"
instance Wrapped Flush where
type Unwrapped Flush = PT.ResponseFlush
_Wrapped' = iso t f
where
t Flush = defMessage
f _ = Flush
instance Default Flush where
def = defMessage ^. _Unwrapped'
data Info = Info
{ infoData :: Text
, infoVersion :: Text
, infoAppVersion :: WrappedVal Word64
, infoLastBlockHeight :: WrappedVal Int64
, infoLastBlockAppHash :: HexString
} deriving (Eq, Show, Generic)
makeABCILenses ''Info
instance ToJSON Info where
toJSON = genericToJSON $ defaultABCIOptions "info"
instance FromJSON Info where
parseJSON = withObject "Info" $ \v -> Info
<$> v .: "data"
<*> v .: "version"
<*> v .: "app_version"
<*> v .:? "last_block_height" .!= 0
<*> v .:? "last_block_app_hash" .!= ""
instance Wrapped Info where
type Unwrapped Info = PT.ResponseInfo
_Wrapped' = iso t f
where
t Info {..} =
defMessage
& PT.data' .~ infoData
& PT.version .~ infoVersion
& PT.appVersion .~ unWrappedVal infoAppVersion
& PT.lastBlockHeight .~ unWrappedVal infoLastBlockHeight
& PT.lastBlockAppHash .~ Hex.toBytes infoLastBlockAppHash
f message = Info
{ infoData = message ^. PT.data'
, infoVersion = message ^. PT.version
, infoAppVersion = WrappedVal $ message ^. PT.appVersion
, infoLastBlockHeight = WrappedVal $ message ^. PT.lastBlockHeight
, infoLastBlockAppHash = Hex.fromBytes $ message ^. PT.lastBlockAppHash
}
instance Default Info where
def = defMessage ^. _Unwrapped'
data SetOption = SetOption
{ setOptionCode :: Word32
, setOptionLog :: Text
, setOptionInfo :: Text
} deriving (Eq, Show, Generic)
makeABCILenses ''SetOption
instance ToJSON SetOption where
toJSON = genericToJSON $ defaultABCIOptions "setOption"
instance FromJSON SetOption where
parseJSON = genericParseJSON $ defaultABCIOptions "setOption"
instance Wrapped SetOption where
type Unwrapped SetOption = PT.ResponseSetOption
_Wrapped' = iso t f
where
t SetOption {..} =
defMessage
& PT.code .~ setOptionCode
& PT.log .~ setOptionLog
& PT.info .~ setOptionInfo
f message = SetOption { setOptionCode = message ^. PT.code
, setOptionLog = message ^. PT.log
, setOptionInfo = message ^. PT.info
}
instance Default SetOption where
def = defMessage ^. _Unwrapped'
data InitChain = InitChain
{ initChainConsensusParams :: Maybe ConsensusParams
, initChainValidators :: [ValidatorUpdate]
} deriving (Eq, Show, Generic)
makeABCILenses ''InitChain
instance ToJSON InitChain where
toJSON = genericToJSON $ defaultABCIOptions "initChain"
instance FromJSON InitChain where
parseJSON = withObject "InitChain" $ \v -> InitChain
<$> v .:? "consensusParams"
<*> v .:? "validators" .!= []
instance Wrapped InitChain where
type Unwrapped InitChain = PT.ResponseInitChain
_Wrapped' = iso t f
where
t InitChain {..} =
defMessage
& PT.maybe'consensusParams .~ initChainConsensusParams ^? _Just . _Wrapped'
& PT.validators .~ initChainValidators ^.. traverse . _Wrapped'
f message = InitChain
{ initChainConsensusParams = message ^? PT.maybe'consensusParams . _Just . _Unwrapped'
, initChainValidators = message ^.. PT.validators . traverse . _Unwrapped'
}
instance Default InitChain where
def = defMessage ^. _Unwrapped'
data Query = Query
{ queryCode :: Word32
, queryLog :: Text
, queryInfo :: Text
, queryIndex :: WrappedVal Int64
, queryKey :: Base64String
, queryValue :: Base64String
, queryProof :: Maybe Proof
, queryHeight :: WrappedVal Int64
, queryCodespace :: Text
} deriving (Eq, Show, Generic)
makeABCILenses ''Query
instance ToJSON Query where
toJSON = genericToJSON $ defaultABCIOptions "query"
instance FromJSON Query where
parseJSON = genericParseJSON $ defaultABCIOptions "query"
instance Wrapped Query where
type Unwrapped Query = PT.ResponseQuery
_Wrapped' = iso t f
where
t Query {..} =
defMessage
& PT.code .~ queryCode
& PT.log .~ queryLog
& PT.info .~ queryInfo
& PT.index .~ unWrappedVal queryIndex
& PT.key .~ Base64.toBytes queryKey
& PT.value .~ Base64.toBytes queryValue
& PT.maybe'proof .~ queryProof ^? _Just . _Wrapped'
& PT.height .~ unWrappedVal queryHeight
& PT.codespace .~ queryCodespace
f message = Query
{ queryCode = message ^. PT.code
, queryLog = message ^. PT.log
, queryInfo = message ^. PT.info
, queryIndex = WrappedVal $ message ^. PT.index
, queryKey = Base64.fromBytes $ message ^. PT.key
, queryValue = Base64.fromBytes $ message ^. PT.value
, queryProof = message ^? PT.maybe'proof . _Just . _Unwrapped'
, queryHeight = WrappedVal $ message ^. PT.height
, queryCodespace = message ^. PT.codespace
}
instance Default Query where
def = defMessage ^. _Unwrapped'
data BeginBlock = BeginBlock
{ beginBlockEvents :: [Event]
} deriving (Eq, Show, Generic)
makeABCILenses ''BeginBlock
instance ToJSON BeginBlock where
toJSON = genericToJSON $ defaultABCIOptions "beginBlock"
instance FromJSON BeginBlock where
parseJSON = withObject "BeginBlock" $ \v -> BeginBlock
<$> v .:? "events" .!= []
instance Wrapped BeginBlock where
type Unwrapped BeginBlock = PT.ResponseBeginBlock
_Wrapped' = iso t f
where
t BeginBlock {..} =
defMessage & PT.events .~ beginBlockEvents ^.. traverse . _Wrapped'
f message = BeginBlock
{ beginBlockEvents = message ^.. PT.events . traverse . _Unwrapped'
}
instance Default BeginBlock where
def = defMessage ^. _Unwrapped'
data CheckTx = CheckTx
{ checkTxCode :: Word32
, checkTxData :: Base64String
, checkTxLog :: Text
, checkTxInfo :: Text
, checkTxGasWanted :: WrappedVal Int64
, checkTxGasUsed :: WrappedVal Int64
, checkTxEvents :: [Event]
, checkTxCodespace :: Text
} deriving (Eq, Show, Generic)
makeABCILenses ''CheckTx
instance ToJSON CheckTx where
toJSON = genericToJSON $ defaultABCIOptions "checkTx"
instance FromJSON CheckTx where
parseJSON = withObject "CheckTx" $ \v -> CheckTx
<$> v .: "code"
<*> v .: "data"
<*> v .: "log"
<*> v .: "info"
<*> v .: "gasWanted"
<*> v .: "gasUsed"
<*> v .:? "events" .!= []
<*> v .: "codespace"
instance Wrapped CheckTx where
type Unwrapped CheckTx = PT.ResponseCheckTx
_Wrapped' = iso t f
where
t CheckTx {..} =
defMessage
& PT.code .~ checkTxCode
& PT.data' .~ Base64.toBytes checkTxData
& PT.log .~ checkTxLog
& PT.info .~ checkTxInfo
& PT.gasWanted .~ unWrappedVal checkTxGasWanted
& PT.gasUsed .~ unWrappedVal checkTxGasUsed
& PT.events .~ checkTxEvents ^.. traverse . _Wrapped'
& PT.codespace .~ checkTxCodespace
f message = CheckTx
{ checkTxCode = message ^. PT.code
, checkTxData = Base64.fromBytes $ message ^. PT.data'
, checkTxLog = message ^. PT.log
, checkTxInfo = message ^. PT.info
, checkTxGasWanted = WrappedVal $ message ^. PT.gasWanted
, checkTxGasUsed = WrappedVal $ message ^. PT.gasUsed
, checkTxEvents = message ^.. PT.events . traverse . _Unwrapped'
, checkTxCodespace = message ^. PT.codespace
}
instance Default CheckTx where
def = defMessage ^. _Unwrapped'
data DeliverTx = DeliverTx
{ deliverTxCode :: Word32
, deliverTxData :: Base64String
, deliverTxLog :: Text
, deliverTxInfo :: Text
, deliverTxGasWanted :: WrappedVal Int64
, deliverTxGasUsed :: WrappedVal Int64
, deliverTxEvents :: [Event]
, deliverTxCodespace :: Text
} deriving (Eq, Show, Generic)
makeABCILenses ''DeliverTx
instance ToJSON DeliverTx where
toJSON = genericToJSON $ defaultABCIOptions "deliverTx"
instance FromJSON DeliverTx where
parseJSON = withObject "DeliverTx" $ \v -> DeliverTx
<$> v .: "code"
<*> v .: "data"
<*> v .: "log"
<*> v .: "info"
<*> v .: "gasWanted"
<*> v .: "gasUsed"
<*> v .:? "events" .!= []
<*> v .: "codespace"
instance Wrapped DeliverTx where
type Unwrapped DeliverTx = PT.ResponseDeliverTx
_Wrapped' = iso t f
where
t DeliverTx {..} =
defMessage
& PT.code .~ deliverTxCode
& PT.data' .~ Base64.toBytes deliverTxData
& PT.log .~ deliverTxLog
& PT.info .~ deliverTxInfo
& PT.gasWanted .~ unWrappedVal deliverTxGasWanted
& PT.gasUsed .~ unWrappedVal deliverTxGasUsed
& PT.events .~ deliverTxEvents ^.. traverse . _Wrapped'
& PT.codespace .~ deliverTxCodespace
f responseDeliverTx = DeliverTx
{ deliverTxCode = responseDeliverTx ^. PT.code
, deliverTxData = Base64.fromBytes $ responseDeliverTx ^. PT.data'
, deliverTxLog = responseDeliverTx ^. PT.log
, deliverTxInfo = responseDeliverTx ^. PT.info
, deliverTxGasWanted = WrappedVal $ responseDeliverTx ^. PT.gasWanted
, deliverTxGasUsed = WrappedVal $ responseDeliverTx ^. PT.gasUsed
, deliverTxEvents = responseDeliverTx ^.. PT.events . traverse . _Unwrapped'
, deliverTxCodespace = responseDeliverTx ^. PT.codespace
}
instance Default DeliverTx where
def = defMessage ^. _Unwrapped'
data EndBlock = EndBlock
{ endBlockValidatorUpdates :: [ValidatorUpdate]
, endBlockConsensusParamUpdates :: Maybe ConsensusParams
, endBlockEvents :: [Event]
} deriving (Eq, Show, Generic)
makeABCILenses ''EndBlock
instance ToJSON EndBlock where
toJSON = genericToJSON $ defaultABCIOptions "endBlock"
instance FromJSON EndBlock where
parseJSON = withObject "EndBlock" $ \v -> EndBlock
<$> v .:? "validatorUpdates" .!= []
<*> v .:? "consensusParams"
<*> v .:? "events" .!= []
instance Wrapped EndBlock where
type Unwrapped EndBlock = PT.ResponseEndBlock
_Wrapped' = iso t f
where
t EndBlock {..} =
defMessage
& PT.validatorUpdates .~ endBlockValidatorUpdates ^.. traverse . _Wrapped'
& PT.maybe'consensusParamUpdates .~ endBlockConsensusParamUpdates ^? _Just . _Wrapped'
& PT.events .~ endBlockEvents ^.. traverse . _Wrapped'
f message = EndBlock
{ endBlockValidatorUpdates = message ^.. PT.validatorUpdates . traverse . _Unwrapped'
, endBlockConsensusParamUpdates = message ^? PT.maybe'consensusParamUpdates . _Just . _Unwrapped'
, endBlockEvents = message ^.. PT.events . traverse . _Unwrapped'
}
instance Default EndBlock where
def = defMessage ^. _Unwrapped'
data Commit = Commit
{ commitData :: Base64String
} deriving (Eq, Show, Generic)
makeABCILenses ''Commit
instance ToJSON Commit where
toJSON = genericToJSON $ defaultABCIOptions "commit"
instance FromJSON Commit where
parseJSON = genericParseJSON $ defaultABCIOptions "commit"
instance Wrapped Commit where
type Unwrapped Commit = PT.ResponseCommit
_Wrapped' = iso t f
where
t Commit {..} = defMessage & PT.data' .~ Base64.toBytes commitData
f message = Commit { commitData = Base64.fromBytes $ message ^. PT.data' }
instance Default Commit where
def = defMessage ^. _Unwrapped'
data Exception = Exception
{ exceptionError :: Text
} deriving (Eq, Show, Generic)
makeABCILenses ''Exception
instance ToJSON Exception where
toJSON = genericToJSON $ defaultABCIOptions "exception"
instance FromJSON Exception where
parseJSON = genericParseJSON $ defaultABCIOptions "exception"
instance Default Exception where
def = defMessage ^. _Unwrapped'
instance Wrapped Exception where
type Unwrapped Exception = PT.ResponseException
_Wrapped' = iso t f
where
t Exception {..} = defMessage & PT.error .~ exceptionError
f responseException =
Exception { exceptionError = responseException ^. PT.error }