Skip to content
This repository has been archived by the owner on Dec 8, 2022. It is now read-only.

[CAD-1397] ITN Ticker protection for mainnet and SMASH #38

Merged
merged 6 commits into from
Aug 4, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 19 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ SMASHPGPASSFILE=./config/pgpass stack run smash-exe -- run-app-with-db-sync --co

You can run the provided example and try out these commands (presuming you know what CURL is and how to use it).
```
curl --verbose --header "Content-Type: application/json" --request GET http://localhost:3000/api/v1/metadata/ed25519_pk1z2ffur59cq7t806nc9y2g64wa60pg5m6e9cmrhxz9phppaxk5d4sn8nsqg
curl --verbose --header "Content-Type: application/json" --request GET http://localhost:3100/api/v1/metadata/062693863e0bcf9f619238f020741381d4d3748aae6faf1c012e80e7/2560993cf1b6f3f1ebde429f062ce48751ed6551c2629ce62e4e169f140a3524

curl --verbose --user ksaric:test --header "Content-Type: application/json" --request POST --data '{"blacklistPool":"xyz"}' http://localhost:3000/api/v1/blacklist
```
Expand Down Expand Up @@ -148,7 +148,7 @@ pg_dump -c -s --no-owner cexplorer > cexplorer.sql

This is an example (we got the hash from Blake2 256):
```
stack exec smash-exe -- insert-pool --metadata test_pool.json --poolhash "cbdfc4f21feb0a414b2b9471fa56b0ebd312825e63db776d68cc3fa0ca1f5a2f"
stack exec smash-exe -- insert-pool --metadata test_pool.json --poolId "062693863e0bcf9f619238f020741381d4d3748aae6faf1c012e80e7" --poolhash "cbdfc4f21feb0a414b2b9471fa56b0ebd312825e63db776d68cc3fa0ca1f5a2f"
```

## Test blacklisting
Expand All @@ -167,7 +167,7 @@ curl -u ksaric:test -X PATCH -v http://localhost:3100/api/v1/blacklist -H 'conte

Fetching the pool:
```
curl -X GET -v http://localhost:3100/api/v1/metadata/93b13334b5edf623fd4c7a716f3cf47be5baf7fb3a431c16ee07aab8ff074873 | jq .
curl -X GET -v http://localhost:3100/api/v1/metadata/062693863e0bcf9f619238f020741381d4d3748aae6faf1c012e80e7/93b13334b5edf623fd4c7a716f3cf47be5baf7fb3a431c16ee07aab8ff074873 | jq .
```

## Basic Auth and DB
Expand All @@ -190,12 +190,12 @@ SMASHPGPASSFILE=config/pgpass stack run smash-exe -- run-migrations --mdir ./sch
SMASHPGPASSFILE=config/pgpass stack run smash-exe -- create-migration --mdir ./schema
SMASHPGPASSFILE=config/pgpass stack run smash-exe -- run-migrations --mdir ./schema

SMASHPGPASSFILE=config/pgpass stack run smash-exe -- insert-pool --metadata test_pool.json --poolhash "cbdfc4f21feb0a414b2b9471fa56b0ebd312825e63db776d68cc3fa0ca1f5a2f"
SMASHPGPASSFILE=config/pgpass stack run smash-exe -- insert-pool --metadata test_pool.json --poolId "062693863e0bcf9f619238f020741381d4d3748aae6faf1c012e80e7" --poolhash "cbdfc4f21feb0a414b2b9471fa56b0ebd312825e63db776d68cc3fa0ca1f5a2f"

SMASHPGPASSFILE=config/pgpass stack run smash-exe -- run-app
```

After the server is running, you can check the hash on http://localhost:3100/api/v1/metadata/cbdfc4f21feb0a414b2b9471fa56b0ebd312825e63db776d68cc3fa0ca1f5a2f to see it return the JSON metadata.
After the server is running, you can check the hash on http://localhost:3100/api/v1/metadata/062693863e0bcf9f619238f020741381d4d3748aae6faf1c012e80e7/cbdfc4f21feb0a414b2b9471fa56b0ebd312825e63db776d68cc3fa0ca1f5a2f to see it return the JSON metadata.

## How to figure out the JSON hash?

Expand All @@ -212,3 +212,17 @@ B16.encode $ Crypto.digest (Proxy :: Proxy Crypto.Blake2b_256) (encodeUtf8 poolM

This presumes that you have a file containing the JSON in your path called "test_pool.json".

## How to insert the reserved ticker name?

Currently, the SMASH service works by allowing superusers to insert the ticker name and the hash of the pool they want to be reserved _for that ticker name_.

There is a CLI utility for doing exactly that. If you want to reserve the ticker name "SALAD" for the specific metadata hash "2560993cf1b6f3f1ebde429f062ce48751ed6551c2629ce62e4e169f140a3524", then you would reserve it like this:
```
SMASHPGPASSFILE=config/pgpass stack run smash-exe -- insert-ticker-name --tickerName "SALAD" --poolhash "2560993cf1b6f3f1ebde429f062ce48751ed6551c2629ce62e4e169f140a3524"
```

If somebody adds the ticker name that exists there, it will not be returned, but it will return 404.




43 changes: 37 additions & 6 deletions app/Main.hs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import Cardano.Prelude
import DB
import DbSyncPlugin (poolMetadataDbSyncNodePlugin)
import Lib
import Types

import Cardano.SmashDbSync (ConfigFile (..),
SmashDbSyncNodeParams (..),
Expand Down Expand Up @@ -40,7 +41,8 @@ data Command
| RunMigrations SmashMigrationDir (Maybe SmashLogFileDir)
| RunApplication
| RunApplicationWithDbSync SmashDbSyncNodeParams
| InsertPool FilePath Text
| InsertPool FilePath PoolId PoolMetadataHash
| InsertTickerName Text PoolMetadataHash

runCommand :: Command -> IO ()
runCommand cmd =
Expand All @@ -52,13 +54,17 @@ runCommand cmd =
race_
(runDbSyncNode poolMetadataDbSyncNodePlugin dbSyncNodeParams)
(runApp defaultConfiguration)
InsertPool poolMetadataJsonPath poolHash -> do
InsertPool poolMetadataJsonPath poolId poolHash -> do
putTextLn "Inserting pool metadata!"
result <- runPoolInsertion poolMetadataJsonPath poolHash
result <- runPoolInsertion poolMetadataJsonPath poolId poolHash
either
(\err -> putTextLn $ "Error occured. " <> renderLookupFail err)
(\_ -> putTextLn "Insertion completed!")
result
InsertTickerName tickerName poolHash -> do
putTextLn "Inserting reserved ticker name!"
void $ runTickerNameInsertion tickerName poolHash


doCreateMigration :: SmashMigrationDir -> IO ()
doCreateMigration mdir = do
Expand Down Expand Up @@ -151,6 +157,10 @@ pCommand =
( Opt.info pInsertPool
$ Opt.progDesc "Inserts the pool into the database (utility)."
)
<> Opt.command "insert-ticker-name"
( Opt.info pInsertTickerName
$ Opt.progDesc "Inserts the ticker name into the database (utility)."
)
)
where
pCreateMigration :: Parser Command
Expand All @@ -174,7 +184,20 @@ pCommand =
-- Empty right now but we might add some params over time.
pInsertPool :: Parser Command
pInsertPool =
InsertPool <$> pFilePath <*> pPoolHash
InsertPool <$> pFilePath <*> pPoolId <*> pPoolHash

-- For inserting ticker names.
pInsertTickerName :: Parser Command
pInsertTickerName =
InsertTickerName <$> pTickerName <*> pPoolHash


pPoolId :: Parser PoolId
pPoolId =
PoolId <$> Opt.strOption
( Opt.long "poolId"
<> Opt.help "The pool id of the operator, the hash of the 'cold' pool key."
)

pFilePath :: Parser FilePath
pFilePath =
Expand All @@ -185,9 +208,9 @@ pFilePath =
<> Opt.completer (Opt.bashCompleter "directory")
)

pPoolHash :: Parser Text
pPoolHash :: Parser PoolMetadataHash
pPoolHash =
Opt.strOption
PoolMetadataHash <$> Opt.strOption
( Opt.long "poolhash"
<> Opt.help "The JSON metadata Blake2 256 hash."
)
Expand All @@ -208,3 +231,11 @@ pLogFileDir =
<> Opt.completer (Opt.bashCompleter "directory")
)

pTickerName :: Parser Text
pTickerName =
Opt.strOption
( Opt.long "tickerName"
<> Opt.help "The name of the ticker."
)


4 changes: 2 additions & 2 deletions doc/getting-started/running.md
Original file line number Diff line number Diff line change
Expand Up @@ -107,9 +107,9 @@ After this, the SMASH application should start syncing blocks and picking up poo

## Checking if it works

For example, after seeing that a pool has be registered, you can try to get it's info by running it's hash (the example here is `93b13334b5edf623fd4c7a716f3cf47be5baf7fb3a431c16ee07aab8ff074873`):
For example, after seeing that a pool has be registered, you can try to get it's info by running it's poolid and hash (the example of the hash here is `93b13334b5edf623fd4c7a716f3cf47be5baf7fb3a431c16ee07aab8ff074873`):
```
curl -X GET -v http://localhost:3100/api/v1/metadata/93b13334b5edf623fd4c7a716f3cf47be5baf7fb3a431c16ee07aab8ff074873
curl -X GET -v http://localhost:3100/api/v1/metadata/062693863e0bcf9f619238f020741381d4d3748aae6faf1c012e80e7/93b13334b5edf623fd4c7a716f3cf47be5baf7fb3a431c16ee07aab8ff074873
```

You can test the blacklisting by sending a PATCH on the blacklist endpoint.
Expand Down
20 changes: 0 additions & 20 deletions schema/migration-2-0001-20200615.sql

This file was deleted.

35 changes: 35 additions & 0 deletions schema/migration-2-0001-20200804.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
-- Persistent generated migration.

CREATE FUNCTION migrate() RETURNS void AS $$
DECLARE
next_version int ;
BEGIN
SELECT stage_two + 1 INTO next_version FROM schema_version ;
IF next_version = 1 THEN
CREATe TABLE "pool_metadata"("id" SERIAL8 PRIMARY KEY UNIQUE,"pool_id" text NOT NULL,"ticker_name" text NOT NULL,"hash" base16type NOT NULL,"metadata" text NOT NULL);
ALTER TABLE "pool_metadata" ADD CONSTRAINT "unique_pool_metadata" UNIQUE("pool_id","hash");
CREATe TABLE "pool_metadata_reference"("id" SERIAL8 PRIMARY KEY UNIQUE,"pool_id" text NOT NULL,"url" text NOT NULL,"hash" base16type NOT NULL);
ALTER TABLE "pool_metadata_reference" ADD CONSTRAINT "unique_pool_metadata_reference" UNIQUE("pool_id","hash");
CREATe TABLE "pool"("id" SERIAL8 PRIMARY KEY UNIQUE,"pool_id" INT8 NOT NULL);
ALTER TABLE "pool" ADD CONSTRAINT "unique_pool_id" UNIQUE("pool_id");
ALTER TABLE "pool" ADD CONSTRAINT "pool_pool_id_fkey" FOREIGN KEY("pool_id") REFERENCES "pool"("id");
CREATe TABLE "block"("id" SERIAL8 PRIMARY KEY UNIQUE,"hash" hash32type NOT NULL,"epoch_no" uinteger NULL,"slot_no" uinteger NULL,"block_no" uinteger NULL);
ALTER TABLE "block" ADD CONSTRAINT "unique_block" UNIQUE("hash");
CREATe TABLE "meta"("id" SERIAL8 PRIMARY KEY UNIQUE,"protocol_const" INT8 NOT NULL,"slot_duration" INT8 NOT NULL,"start_time" timestamp NOT NULL,"slots_per_epoch" INT8 NOT NULL,"network_name" VARCHAR NULL);
ALTER TABLE "meta" ADD CONSTRAINT "unique_meta" UNIQUE("start_time");
CREATe TABLE "blacklisted_pool"("id" SERIAL8 PRIMARY KEY UNIQUE,"pool_id" hash28type NOT NULL);
ALTER TABLE "blacklisted_pool" ADD CONSTRAINT "unique_blacklisted_pool" UNIQUE("pool_id");
CREATe TABLE "reserved_ticker"("id" SERIAL8 PRIMARY KEY UNIQUE,"name" text NOT NULL,"pool_hash" base16type NOT NULL);
ALTER TABLE "reserved_ticker" ADD CONSTRAINT "unique_reserved_ticker" UNIQUE("name");
CREATe TABLE "admin_user"("id" SERIAL8 PRIMARY KEY UNIQUE,"username" VARCHAR NOT NULL,"password" VARCHAR NOT NULL);
ALTER TABLE "admin_user" ADD CONSTRAINT "unique_admin_user" UNIQUE("username");
-- Hand written SQL statements can be added here.
UPDATE schema_version SET stage_two = 1 ;
RAISE NOTICE 'DB has been migrated to stage_two version %', next_version ;
END IF ;
END ;
$$ LANGUAGE plpgsql ;

SELECT migrate() ;

DROP FUNCTION migrate() ;
20 changes: 0 additions & 20 deletions schema/migration-2-0002-20200626.sql

This file was deleted.

19 changes: 0 additions & 19 deletions schema/migration-2-0003-20200630.sql

This file was deleted.

21 changes: 0 additions & 21 deletions schema/migration-2-0004-20200710.sql

This file was deleted.

22 changes: 0 additions & 22 deletions schema/migration-2-0005-20200722.sql

This file was deleted.

1 change: 1 addition & 0 deletions smash.cabal
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ library
, Cardano.Db.Error
, Cardano.Db.Insert
, Cardano.Db.Query
, Cardano.Db.Types


other-modules:
Expand Down
11 changes: 7 additions & 4 deletions src/Cardano/Db/Error.hs
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,13 @@ import Data.Aeson (ToJSON (..), (.=), object, Value (..))

import Data.ByteString.Char8 (ByteString)

import Cardano.Db.Types


-- | Errors, not exceptions.
data DBFail
= DbLookupBlockHash !ByteString
| DbLookupTxMetadataHash !ByteString
| DbLookupPoolMetadataHash !PoolId !PoolMetadataHash
| DbMetaEmpty
| DbMetaMultipleRows
| PoolMetadataHashMismatch
Expand All @@ -42,9 +45,9 @@ instance ToJSON DBFail where
[ "code" .= String "DbLookupBlockHash"
, "description" .= String (renderLookupFail failure)
]
toJSON failure@(DbLookupTxMetadataHash _hash) =
toJSON failure@(DbLookupPoolMetadataHash _poolId _poolMDHash) =
object
[ "code" .= String "DbLookupTxMetadataHash"
[ "code" .= String "DbLookupPoolMetadataHash"
, "description" .= String (renderLookupFail failure)
]
toJSON failure@DbMetaEmpty =
Expand Down Expand Up @@ -83,7 +86,7 @@ renderLookupFail :: DBFail -> Text
renderLookupFail lf =
case lf of
DbLookupBlockHash hash -> "The block hash " <> decodeUtf8 hash <> " is missing from the DB."
DbLookupTxMetadataHash hash -> "The tx hash " <> decodeUtf8 hash <> " is missing from the DB."
DbLookupPoolMetadataHash poolId poolMDHash -> "The metadata with hash " <> show poolId <> " for pool " <> show poolMDHash <> " is missing from the DB."
DbMetaEmpty -> "The metadata table is empty!"
DbMetaMultipleRows -> "The metadata table contains multiple rows. Error."
PoolMetadataHashMismatch -> "The pool metadata does not match!"
Expand Down
19 changes: 13 additions & 6 deletions src/Cardano/Db/Insert.hs
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,9 @@
module Cardano.Db.Insert
( insertBlock
, insertMeta
, insertTxMetadata
, insertPoolMetaData
, insertPoolMetadata
, insertPoolMetadataReference
, insertReservedTicker
, insertBlacklistedPool
, insertAdminUser

Expand All @@ -31,11 +32,17 @@ insertBlock = insertByReturnKey
insertMeta :: (MonadIO m) => Meta -> ReaderT SqlBackend m MetaId
insertMeta = insertByReturnKey

insertTxMetadata :: (MonadIO m) => TxMetadata -> ReaderT SqlBackend m TxMetadataId
insertTxMetadata = insertByReturnKey
insertPoolMetadata :: (MonadIO m) => PoolMetadata -> ReaderT SqlBackend m PoolMetadataId
insertPoolMetadata = insertByReturnKey

insertPoolMetaData :: (MonadIO m) => PoolMetaData -> ReaderT SqlBackend m PoolMetaDataId
insertPoolMetaData = insertByReturnKey
insertPoolMetadataReference
:: MonadIO m
=> PoolMetadataReference
-> ReaderT SqlBackend m PoolMetadataReferenceId
insertPoolMetadataReference = insertByReturnKey

insertReservedTicker :: (MonadIO m) => ReservedTicker -> ReaderT SqlBackend m ReservedTickerId
insertReservedTicker = insertByReturnKey

insertBlacklistedPool :: (MonadIO m) => BlacklistedPool -> ReaderT SqlBackend m BlacklistedPoolId
insertBlacklistedPool = insertByReturnKey
Expand Down
Loading