Skip to content

Commit

Permalink
Upgrade foreign-generics (#101)
Browse files Browse the repository at this point in the history
* update bower file

* tests pass

* remove simple-json dep

* fix tests

* add live tests

* add cliquebait to docker file

* make cliquebait make more accounts

* update bower file
  • Loading branch information
martyall authored May 9, 2018
1 parent f9dab66 commit 6cad0e4
Show file tree
Hide file tree
Showing 10 changed files with 467 additions and 132 deletions.
4 changes: 4 additions & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,17 @@ language: node_js
dist: trusty
sudo: required
node_js: stable
services:
- docker
install:
- npm install -g bower
- npm install
script:
- bower install --production
- npm run -s build
- bower install
- docker run -d -p 8545:8545 -e ACCOUNTS_TO_CREATE=10 foamspace/cliquebait:latest
- sleep 10
- npm -s test
after_success:
- >-
Expand Down
17 changes: 7 additions & 10 deletions bower.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,25 +17,22 @@
],
"dependencies": {
"purescript-errors": "^3.0.0",
"purescript-profunctor-lenses": "^3.7.0",
"purescript-profunctor-lenses": "^3.8.0",
"purescript-foreign": "^4.0.1",
"purescript-foreign-generic": "^5.0.0",
"purescript-foreign-generic": "^6.0.0",
"purescript-proxy": "^2.1.0",
"purescript-bytestrings": "^6.0.0",
"purescript-eth-core": "^0.0.1",
"purescript-eth-core": "^1.0.0",
"purescript-partial": "^1.2.1",
"purescript-parsing": "^4.3.1",
"purescript-transformers": "^3.6.0",
"purescript-identity": "^3.1.0",
"purescript-aff": "^4.0.0",
"purescript-aff": "^4.1.0",
"purescript-tagged": "^2.0.0",
"purescript-free": "^4.2.0",
"purescript-free": "^4.3.0",
"purescript-coroutines": "^4.0.0",
"purescript-typelevel-prelude": "^2.6.0",
"purescript-type-equality": "^2.1.0",
"purescript-modules": "^3.0.0",
"purescript-mmorph": "^3.0.0",
"purescript-simple-json": "^2.0.1"
"purescript-typelevel-prelude": "^2.7.0",
"purescript-modules": "^3.0.0"
},
"devDependencies": {
"purescript-debug": "v3.0.0",
Expand Down
32 changes: 10 additions & 22 deletions src/Network/Ethereum/Web3/Api.purs
Original file line number Diff line number Diff line change
@@ -1,20 +1,21 @@
module Network.Ethereum.Web3.Api where

import Data.Maybe (Maybe, fromMaybe)
import Network.Ethereum.Web3.JsonRPC (remote)
import Network.Ethereum.Types (Address, HexString, BigNumber)
import Network.Ethereum.Web3.Types (Block, BlockNumber, ChainCursor, Change, FalseOrObject, Filter, FilterId, NoPay, SyncStatus, Transaction, TransactionOptions, TransactionReceipt, Web3, Wei)
import Type.Data.Boolean (kind Boolean)

-- | Returns current node version string.
web3_clientVersion :: forall e . Web3 e String
web3_clientVersion :: forall e . Partial => Web3 e String
web3_clientVersion = remote "web3_clientVersion"

-- | Returns Keccak-256 (*not* the standardized SHA3-256) of the given data.
web3_sha3 :: forall e. HexString -> Web3 e HexString
web3_sha3 :: forall e. Partial => HexString -> Web3 e HexString
web3_sha3 hexInput = remote "web3_sha3" hexInput

-- | Get the network id that the node is listening to.
net_version :: forall e . Web3 e BigNumber
net_version :: forall e . Web3 e String
net_version = remote "net_version"

-- | Returns `true`` if client is actively listening for network connections
Expand Down Expand Up @@ -73,8 +74,6 @@ eth_getBlockTransactionCountByHash blockHash = remote "eth_getBlockTransactionCo
eth_getBlockTransactionCountByNumber :: forall e. ChainCursor -> Web3 e BigNumber
eth_getBlockTransactionCountByNumber cm = remote "eth_getBlockTransactionCountByNumber" cm

-- TODO - is it appropriate for these to be Ints?

-- | Returns the number of uncles in a block from a block matching the given block hash
eth_getUncleCountByBlockHash :: forall e. HexString -> Web3 e BigNumber
eth_getUncleCountByBlockHash blockNumber = remote "eth_getUncleCountByBlockHash" blockNumber
Expand All @@ -87,19 +86,13 @@ eth_getUncleCountByBlockNumber cm = remote "eth_getUncleCountByBlockNumber" cm
eth_getCode :: forall e. Address -> ChainCursor -> Web3 e HexString
eth_getCode addr cm = remote "eth_getCode" addr cm

-- | The sign method calculates an Ethereum specific signature with: `sign(keccak256("\x19Ethereum Signed Message:\n" + len(message) + message)))`.
-- | By adding a prefix to the message makes the calculated signature recognisable as an Ethereum specific signature. This prevents misuse where a malicious DApp can sign arbitrary data (e.g. transaction) and use the signature to impersonate the victim.
-- | **Note** the address to sign with must be unlocked.
eth_sign :: forall e. Warn "eth_sign is deprecated in favor of personal_sign" => Address -> HexString -> Web3 e HexString
eth_sign addr msg = remote "eth_sign" addr msg

-- | Creates new message call transaction or a contract creation for signed transactions
eth_sendRawTransaction :: forall e. HexString -> Web3 e HexString
eth_sendRawTransaction rawTx = remote "eth_sendRawTransaction" rawTx

-- | Makes a call or transaction, which won't be added to the blockchain and returns the used gas, which can be used for estimating the used gas.
eth_estimateGas :: forall e. TransactionOptions Wei -> ChainCursor -> Web3 e BigNumber
eth_estimateGas txOpts cm = remote "eth_estimateGas" txOpts cm
eth_estimateGas :: forall e. TransactionOptions Wei -> Web3 e BigNumber
eth_estimateGas txOpts = remote "eth_estimateGas" txOpts

-- | Returns information about a transaction by block hash and transaction index position.
eth_getTransactionByBlockHashAndIndex :: forall e. HexString -> BigNumber -> Web3 e Transaction
Expand All @@ -122,14 +115,9 @@ eth_getUncleByBlockNumberAndIndex :: forall e. ChainCursor -> BigNumber -> Web3
eth_getUncleByBlockNumberAndIndex cm uncleIndex = remote "eth_getUncleByBlockNumberAndIndex" cm uncleIndex

-- | Returns a list of available compilers in the client.
eth_getCompilers :: forall e. Web3 e (Array String)
eth_getCompilers :: forall e. Partial => Web3 e (Array String)
eth_getCompilers = remote "eth_getCompilers"

-- TODO: As the ABI is returned decoding this isn't trivial - not going to implement without a need
-- -- | Returns compiled solidity code.
-- eth_compileSolidity :: forall e. String -> Web3 e HexString
-- eth_compileSolidity code = remote "eth_compileSolidity"

-- | Returns information about a block by number.
eth_getBlockByNumber :: forall e . ChainCursor -> Web3 e Block
eth_getBlockByNumber cm = remote "eth_getBlockByNumber" cm false
Expand Down Expand Up @@ -181,9 +169,9 @@ eth_uninstallFilter :: forall e . FilterId -> Web3 e Boolean
eth_uninstallFilter fid = remote "eth_uninstallFilter" fid

-- | Sign a message with the given address, returning the signature.
personal_sign :: forall e . HexString -> Address -> Web3 e HexString
personal_sign _data signer = remote "personal_sign" _data signer
personal_sign :: forall e . HexString -> Address -> Maybe String -> Web3 e HexString
personal_sign _data signer password = remote "personal_sign" _data signer (fromMaybe "" password)

-- | Recover the address that signed the message.
-- | Recover the address that signed the message from (1) the message and (2) the signature
personal_ecRecover :: forall e . HexString -> HexString -> Web3 e Address
personal_ecRecover _data sig = remote "personal_ecRecover" _data sig
2 changes: 1 addition & 1 deletion src/Network/Ethereum/Web3/Contract.purs
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,7 @@ _sendTransaction :: forall a u rep e selector .
-> Web3 e HexString
_sendTransaction txOptions dat = do
let sel = toSelector <<< reflectSymbol $ (SProxy :: SProxy selector)
eth_sendTransaction <<< txdata $ sel <> (genericABIEncode <<< untagged $ dat)
eth_sendTransaction $ txdata $ sel <> (genericABIEncode <<< untagged $ dat)
where
txdata d = txOptions # _data .~ Just d
# _value %~ map convert
Expand Down
118 changes: 52 additions & 66 deletions src/Network/Ethereum/Web3/Types/Types.purs
Original file line number Diff line number Diff line change
Expand Up @@ -46,13 +46,13 @@ import Prelude

import Control.Alt (class Alt)
import Control.Alternative (class Alternative, class Plus, (<|>))
import Control.Monad.Aff (Aff, Fiber, ParAff, forkAff, liftEff', throwError)
import Control.Monad.Aff (Aff, Fiber, ParAff, forkAff, liftEff')
import Control.Monad.Aff.Class (class MonadAff, liftAff)
import Control.Monad.Eff (kind Effect)
import Control.Monad.Eff.Class (class MonadEff)
import Control.Monad.Eff.Exception (Error, throwException)
import Control.Monad.Error.Class (class MonadThrow, catchError)
import Control.Monad.Except (ExceptT, except, runExceptT)
import Control.Monad.Except (ExceptT, runExceptT)
import Control.Monad.Reader (class MonadAsk, class MonadReader, ReaderT, ask, runReaderT)
import Control.Monad.Rec.Class (class MonadRec)
import Control.Parallel.Class (class Parallel, parallel, sequential)
Expand All @@ -61,7 +61,6 @@ import Data.Foreign (F, Foreign, ForeignError(..), fail, isNull, readBoolean, re
import Data.Foreign.Class (class Decode, class Encode, decode, encode)
import Data.Foreign.Generic (defaultOptions, genericDecode, genericEncode)
import Data.Foreign.Index (readProp)
import Data.Foreign.NullOrUndefined (NullOrUndefined(..), unNullOrUndefined)
import Data.Functor.Compose (Compose)
import Data.Generic.Rep (class Generic)
import Data.Generic.Rep.Eq (genericEq)
Expand All @@ -70,12 +69,9 @@ import Data.Lens.Lens (Lens', Lens, lens)
import Data.Maybe (Maybe(..))
import Data.Newtype (class Newtype, unwrap)
import Data.Ordering (invert)
import Data.Record as Record
import Data.Symbol (SProxy(..))
import Network.Ethereum.Types (Address, BigNumber, HexString)
import Network.Ethereum.Web3.Types.EtherUnit (class EtherUnit, NoPay, Value, Wei, convert)
import Network.Ethereum.Web3.Types.Provider (Provider)
import Simple.JSON (read)

--------------------------------------------------------------------------------
-- * Block
Expand Down Expand Up @@ -128,11 +124,11 @@ newtype Block
, extraData :: HexString
, gasLimit :: BigNumber
, gasUsed :: BigNumber
, hash :: HexString
, logsBloom :: HexString
, hash :: Maybe HexString
, logsBloom :: Maybe HexString
, miner :: HexString
, nonce :: HexString
, number :: BigNumber
, nonce :: Maybe HexString
, number :: Maybe BigNumber
, parentHash :: HexString
, receiptsRoot :: HexString
, sha3Uncles :: HexString
Expand All @@ -153,18 +149,7 @@ instance showBlock :: Show Block where
show = genericShow

instance decodeBlock :: Decode Block where
decode x = catchError (genericDecode decodeOpts x)
-- if this attempt fails for any reason pass back the original error
\origError -> catchError tryKovanAuthorHack (\_ -> throwError origError)
where
decodeOpts = defaultOptions { unwrapSingleConstructors = true }
tryKovanAuthorHack = do
rec <- except $ read x
let blockRec = Record.delete (SProxy :: SProxy "author") rec
# Record.insert (SProxy :: SProxy "nonce") rec.author
pure $ Block blockRec


decode x = genericDecode (defaultOptions { unwrapSingleConstructors = true }) x

--------------------------------------------------------------------------------
-- * Transaction
Expand All @@ -173,11 +158,11 @@ instance decodeBlock :: Decode Block where
newtype Transaction =
Transaction { hash :: HexString
, nonce :: BigNumber
, blockHash :: HexString
, blockNumber :: BlockNumber
, transactionIndex :: BigNumber
, blockHash :: Maybe HexString
, blockNumber :: Maybe BlockNumber
, transactionIndex :: Maybe BigNumber
, from :: Address
, to :: NullOrUndefined Address
, to :: Maybe Address
, value :: Value Wei
, gas :: BigNumber
, gasPrice :: BigNumber
Expand Down Expand Up @@ -221,7 +206,7 @@ newtype TransactionReceipt =
, blockNumber :: BlockNumber
, cumulativeGasUsed :: BigNumber
, gasUsed :: BigNumber
, contractAddress :: NullOrUndefined Address
, contractAddress :: Maybe Address
, logs :: Array Change
, status :: TransactionStatus
}
Expand All @@ -241,13 +226,13 @@ instance decodeTxReceipt :: Decode TransactionReceipt where
--------------------------------------------------------------------------------

newtype TransactionOptions u =
TransactionOptions { from :: NullOrUndefined Address
, to :: NullOrUndefined Address
, value :: NullOrUndefined (Value u)
, gas :: NullOrUndefined BigNumber
, gasPrice :: NullOrUndefined BigNumber
, data :: NullOrUndefined HexString
, nonce :: NullOrUndefined BigNumber
TransactionOptions { from :: Maybe Address
, to :: Maybe Address
, value :: Maybe (Value u)
, gas :: Maybe BigNumber
, gasPrice :: Maybe BigNumber
, data :: Maybe HexString
, nonce :: Maybe BigNumber
}

derive instance genericTransactionOptions :: Generic (TransactionOptions u) _
Expand All @@ -262,42 +247,42 @@ instance encodeTransactionOptions :: Encode (TransactionOptions u) where

defaultTransactionOptions :: TransactionOptions NoPay
defaultTransactionOptions =
TransactionOptions { from : NullOrUndefined Nothing
, to : NullOrUndefined Nothing
, value : NullOrUndefined Nothing
, gas : NullOrUndefined Nothing
, gasPrice : NullOrUndefined Nothing
, data : NullOrUndefined Nothing
, nonce : NullOrUndefined Nothing
TransactionOptions { from: Nothing
, to: Nothing
, value: Nothing
, gas: Nothing
, gasPrice: Nothing
, data: Nothing
, nonce: Nothing
}
-- * Lens Boilerplate
_from :: forall u. Lens' (TransactionOptions u) (Maybe Address)
_from = lens (\(TransactionOptions txOpt) -> unNullOrUndefined $ txOpt.from)
(\(TransactionOptions txOpts) addr -> TransactionOptions $ txOpts {from = NullOrUndefined addr})
_from = lens (\(TransactionOptions txOpt) -> txOpt.from)
(\(TransactionOptions txOpts) addr -> TransactionOptions $ txOpts {from = addr})

_to :: forall u. Lens' (TransactionOptions u) (Maybe Address)
_to = lens (\(TransactionOptions txOpt) -> unNullOrUndefined $ txOpt.to)
(\(TransactionOptions txOpts) addr -> TransactionOptions $ txOpts {to = NullOrUndefined addr})
_to = lens (\(TransactionOptions txOpt) -> txOpt.to)
(\(TransactionOptions txOpts) addr -> TransactionOptions $ txOpts {to = addr})

_data :: forall u. Lens' (TransactionOptions u) (Maybe HexString)
_data = lens (\(TransactionOptions txOpt) -> unNullOrUndefined $ txOpt.data)
(\(TransactionOptions txOpts) dat -> TransactionOptions $ txOpts {data = NullOrUndefined dat})
_data = lens (\(TransactionOptions txOpt) -> txOpt.data)
(\(TransactionOptions txOpts) dat -> TransactionOptions $ txOpts {data = dat})

_value :: forall u. EtherUnit (Value u) => Lens (TransactionOptions u) (TransactionOptions Wei) (Maybe (Value u)) (Maybe (Value Wei))
_value = lens (\(TransactionOptions txOpt) -> unNullOrUndefined $ txOpt.value)
(\(TransactionOptions txOpts) val -> TransactionOptions $ txOpts {value = NullOrUndefined $ map convert val})
_value = lens (\(TransactionOptions txOpt) -> txOpt.value)
(\(TransactionOptions txOpts) val -> TransactionOptions $ txOpts {value = map convert val})

_gas :: forall u. Lens' (TransactionOptions u) (Maybe BigNumber)
_gas = lens (\(TransactionOptions txOpt) -> unNullOrUndefined $ txOpt.gas)
(\(TransactionOptions txOpts) g -> TransactionOptions $ txOpts {gas = NullOrUndefined g})
_gas = lens (\(TransactionOptions txOpt) -> txOpt.gas)
(\(TransactionOptions txOpts) g -> TransactionOptions $ txOpts {gas = g})

_gasPrice :: forall u. Lens' (TransactionOptions u) (Maybe BigNumber)
_gasPrice = lens (\(TransactionOptions txOpt) -> unNullOrUndefined $ txOpt.gasPrice)
(\(TransactionOptions txOpts) gp -> TransactionOptions $ txOpts {gasPrice = NullOrUndefined gp})
_gasPrice = lens (\(TransactionOptions txOpt) -> txOpt.gasPrice)
(\(TransactionOptions txOpts) gp -> TransactionOptions $ txOpts {gasPrice = gp})

_nonce :: forall u. Lens' (TransactionOptions u) (Maybe BigNumber)
_nonce = lens (\(TransactionOptions txOpt) -> unNullOrUndefined $ txOpt.nonce)
(\(TransactionOptions txOpts) n -> TransactionOptions $ txOpts {nonce = NullOrUndefined n})
_nonce = lens (\(TransactionOptions txOpt) -> txOpt.nonce)
(\(TransactionOptions txOpts) n -> TransactionOptions $ txOpts {nonce = n})

--------------------------------------------------------------------------------
-- * Node Synchronisation
Expand Down Expand Up @@ -395,8 +380,8 @@ forkWeb3' web3Action = do

-- | Low-level event filter data structure
newtype Filter a = Filter
{ address :: NullOrUndefined Address
, topics :: NullOrUndefined (Array (NullOrUndefined HexString))
{ address :: Maybe Address
, topics :: Maybe (Array (Maybe HexString))
, fromBlock :: ChainCursor
, toBlock :: ChainCursor
}
Expand All @@ -414,19 +399,19 @@ instance encodeFilter :: Encode (Filter a) where
encode x = genericEncode (defaultOptions { unwrapSingleConstructors = true }) x

defaultFilter :: forall a. Filter a
defaultFilter = Filter { address: NullOrUndefined Nothing
, topics: NullOrUndefined Nothing
defaultFilter = Filter { address: Nothing
, topics: Nothing
, fromBlock: Latest
, toBlock: Latest
}

_address :: forall a. Lens' (Filter a) (Maybe Address)
_address = lens (\(Filter f) -> unNullOrUndefined f.address)
(\(Filter f) addr -> Filter $ f {address = NullOrUndefined addr})
_address = lens (\(Filter f) -> f.address)
(\(Filter f) addr -> Filter $ f {address = addr})

_topics :: forall a. Lens' (Filter a) (Maybe (Array (Maybe HexString)))
_topics = lens (\(Filter f) -> map unNullOrUndefined <$> unNullOrUndefined f.topics)
(\(Filter f) ts -> Filter $ f {topics = NullOrUndefined (map NullOrUndefined <$> ts)})
_topics = lens (\(Filter f) -> f.topics)
(\(Filter f) ts -> Filter $ f {topics = ts})

_fromBlock :: forall a. Lens' (Filter a) ChainCursor
_fromBlock = lens (\(Filter f) -> f.fromBlock)
Expand All @@ -437,7 +422,7 @@ _toBlock = lens (\(Filter f) -> f.toBlock)
(\(Filter f) b -> Filter $ f {toBlock = b})

-- | Used by the ethereum client to identify the filter you are querying
newtype FilterId = FilterId HexString
newtype FilterId = FilterId BigNumber

derive instance genericFilterId :: Generic FilterId _

Expand Down Expand Up @@ -480,9 +465,10 @@ instance eqEventAction :: Eq EventAction where
-- | Changes pulled by low-level call 'eth_getFilterChanges', 'eth_getLogs',
-- | and 'eth_getFilterLogs'
newtype Change = Change
{ logIndex :: HexString
, transactionIndex :: HexString
{ logIndex :: BigNumber
, transactionIndex :: BigNumber
, transactionHash :: HexString
, removed :: Boolean
, blockHash :: HexString
, blockNumber :: BlockNumber
, address :: Address
Expand Down
Loading

0 comments on commit 6cad0e4

Please sign in to comment.