Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

account.get_utxo pagination #1436

Merged
merged 125 commits into from
Apr 16, 2020
Merged
Show file tree
Hide file tree
Changes from 105 commits
Commits
Show all changes
125 commits
Select commit Hold shift + click to select a range
bcad37f
attempt number 2!
jarindr Mar 24, 2020
57fceb3
Merge remote-tracking branch 'origin/master' into ddos-account-utxo
jarindr Mar 24, 2020
2ec81cc
wow it finally works
jarindr Mar 24, 2020
4657132
should failed on no address
jarindr Mar 24, 2020
6837726
add more parse test
jarindr Mar 24, 2020
50f584d
check constranints
jarindr Mar 26, 2020
f68386f
(test) paginator attempt 3
jarindr Mar 26, 2020
7e0e6c3
spandex
jarindr Mar 26, 2020
1d2a21d
fix address test
jarindr Mar 26, 2020
adbe2c0
return list
jarindr Mar 26, 2020
c947893
bring back paginator
jarindr Mar 26, 2020
3317430
get utxo
jarindr Mar 26, 2020
5fe3290
fix spec OMG.Crypto.address_t()
jarindr Mar 26, 2020
3506806
remove redundancy
jarindr Mar 26, 2020
f04e4af
add data paginator
jarindr Mar 26, 2020
4784983
wtf it works
jarindr Mar 26, 2020
45a8864
all passed
jarindr Mar 26, 2020
df3a8dd
fix eth_event_test
jarindr Mar 26, 2020
1dc509e
fix another eth event test failed
jarindr Mar 26, 2020
a825eab
fix response schemas for account get utxo
jarindr Mar 26, 2020
e52ff49
fix request body yamal
jarindr Mar 26, 2020
014eb4e
improve description
jarindr Mar 26, 2020
94af0bd
Merge branch 'master' into ddos-account-utxo
jarindr Mar 26, 2020
beb0978
add new line
jarindr Mar 26, 2020
06a07de
add new line
jarindr Mar 26, 2020
7e74935
Merge branch 'ddos-account-utxo' of github.com:omisego/elixir-omg int…
jarindr Mar 26, 2020
1db6f0a
mix format
jarindr Mar 26, 2020
b8a49f8
format mix
jarindr Mar 26, 2020
862d622
fix test
jarindr Mar 26, 2020
a878b02
fix test
jarindr Mar 26, 2020
27690a4
fix naming
jarindr Mar 26, 2020
82db6b3
format mix
jarindr Mar 26, 2020
ed3b2bf
fix warning error
jarindr Mar 27, 2020
421b961
Merge branch 'master' into ddos-account-utxo
jarindr Mar 27, 2020
bef4738
Merge branch 'master' into ddos-account-utxo
jarindr Mar 27, 2020
e10b874
add paging test case
jarindr Mar 29, 2020
55e8e5d
add pagination test
jarindr Mar 29, 2020
d315ae4
fix limit on swagger
jarindr Mar 29, 2020
c89c1e2
format test
jarindr Mar 29, 2020
1e92425
fix get_utxo spect
jarindr Mar 29, 2020
5b7d29f
sort alias
jarindr Mar 29, 2020
83fc982
add leser validate
jarindr Mar 29, 2020
c07bdc3
remove empty lines
jarindr Mar 29, 2020
2813132
change name optional_lesser
jarindr Mar 29, 2020
2592a1b
add todo for watcher info api test cabbage for monday !
jarindr Mar 29, 2020
b336dbe
new line
jarindr Mar 29, 2020
b143220
mix format
jarindr Mar 29, 2020
224d559
rename optional lesser
jarindr Mar 29, 2020
bb3e59a
add limit for block and transaction count
jarindr Mar 29, 2020
b99b015
if con test
jarindr Mar 29, 2020
812a0e6
add feature for alice call
jarindr Mar 30, 2020
40a7f1f
alice_addr
jarindr Mar 30, 2020
f3e625f
take only single account
jarindr Mar 30, 2020
1f2c84f
fix account array
jarindr Mar 31, 2020
efbab84
add required
jarindr Mar 31, 2020
6499c8d
okay runnable test... gosh
jarindr Mar 31, 2020
835aa39
add alias for apimoedl
jarindr Mar 31, 2020
30aad8a
fix fixture
jarindr Mar 31, 2020
4335bec
test 2 utxo
jarindr Mar 31, 2020
ea8c8e7
format
jarindr Mar 31, 2020
80ae26e
fix patterm atching
jarindr Mar 31, 2020
c16051f
yay working
jarindr Mar 31, 2020
4877bef
update info api spec
jarindr Mar 31, 2020
8b3cdb0
change to pure call
jarindr Apr 1, 2020
b9d5451
_alice_priv fix warning
jarindr Apr 1, 2020
e38bad1
add payload
jarindr Apr 1, 2020
5f16fde
fix pattern matching
jarindr Apr 1, 2020
7f46024
dynamic value
jarindr Apr 2, 2020
f38a142
remove fixture
jarindr Apr 2, 2020
5f66fd1
fix key as string for map
jarindr Apr 2, 2020
0d06417
test single tx
jarindr Apr 2, 2020
c3d612f
format
jarindr Apr 2, 2020
fd45748
more format
jarindr Apr 2, 2020
59466b5
fix sometimes failed test
jarindr Apr 2, 2020
2f6dc9b
test pagination
jarindr Apr 2, 2020
1673679
format
jarindr Apr 2, 2020
b9e4526
fix expression
jarindr Apr 2, 2020
88d0d0c
fix pattern match
jarindr Apr 2, 2020
b08cbdf
remove warning
jarindr Apr 2, 2020
517bb39
Merge branch 'master' into ddos-account-utxo
jarindr Apr 3, 2020
d7caa7d
update make file
jarindr Apr 3, 2020
6049bb2
use ipoller
jarindr Apr 3, 2020
4329bb7
Merge branch 'ddos-account-utxo' of github.com:omisego/elixir-omg int…
jarindr Apr 3, 2020
203c2f5
fix default limit
jarindr Apr 3, 2020
876763b
default paging
jarindr Apr 3, 2020
cb8514c
remove unused utxo
jarindr Apr 3, 2020
d3c5334
fix mix warn
jarindr Apr 3, 2020
f445672
Update priv/cabbage/apps/itest/test/features/watcher_info_api.feature
jarindr Apr 7, 2020
ce566e4
fix comments and eng
jarindr Apr 7, 2020
a04dda6
merge
jarindr Apr 7, 2020
42485e6
fix scenario
jarindr Apr 7, 2020
817458f
mix format
jarindr Apr 7, 2020
908d87c
fix scnerio
jarindr Apr 7, 2020
e5ac445
format
jarindr Apr 7, 2020
b87ca52
Merge branch 'master' into ddos-account-utxo
jarindr Apr 7, 2020
87296b2
fix comments
jarindr Apr 7, 2020
474e667
mix format
jarindr Apr 7, 2020
0cd0c1c
use to atom
jarindr Apr 7, 2020
4807d5f
Merge branch 'ddos-account-utxo' of github.com:omisego/elixir-omg int…
jarindr Apr 7, 2020
dfb422c
Merge branch 'master' into ddos-account-utxo
jarindr Apr 7, 2020
8a684c9
mix format
jarindr Apr 7, 2020
203e988
mix format
jarindr Apr 7, 2020
9e74e9b
add atom
jarindr Apr 7, 2020
e800c64
wow it works
jarindr Apr 7, 2020
bf600f4
Merge branch 'ddos-account-utxo' of github.com:omisego/elixir-omg int…
jarindr Apr 7, 2020
c7776b8
Merge branch 'master' into ddos-account-utxo
jarindr Apr 7, 2020
f9f8ab7
alias
jarindr Apr 7, 2020
a31bf88
mix format
jarindr Apr 7, 2020
3d5ce81
Merge branch 'ddos-account-utxo' of github.com:omisego/elixir-omg int…
jarindr Apr 7, 2020
b3e9f4d
add helper spec
jarindr Apr 7, 2020
918a6d4
fix lint
jarindr Apr 7, 2020
703f83b
update doc
jarindr Apr 7, 2020
3302d11
Merge branch 'master' into ddos-account-utxo
jarindr Apr 10, 2020
a96ef9d
Merge branch 'master' into ddos-account-utxo
jarindr Apr 12, 2020
1722a3c
Merge branch 'master' into ddos-account-utxo
jarindr Apr 13, 2020
6475ec3
Merge branch 'master' into ddos-account-utxo
jarindr Apr 14, 2020
396ca91
fix type spec for all existing paginator
jarindr Apr 16, 2020
b657f2b
fix paginator type
jarindr Apr 16, 2020
b83375a
t(%__MODULE__{}) for own paginator
jarindr Apr 16, 2020
1f9ab33
fix the last man standing paginator spec
jarindr Apr 16, 2020
4306c50
okay i lied not last one
jarindr Apr 16, 2020
f176ea1
fix paginator
jarindr Apr 16, 2020
25e6485
fix missing )
jarindr Apr 16, 2020
d110618
change type
jarindr Apr 16, 2020
107e73c
Merge branch 'master' into ddos-account-utxo
unnawut Apr 16, 2020
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
5 changes: 5 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,11 @@ data/
# local test setup
localchain_contract_addresses.env


# the famous mac .DS_Store
.DS_Store

# IntelliJ files
.idea/
*.iml

9 changes: 7 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,11 @@ help:
@echo "DOCKER DEVELOPMENT"
@echo "------------------"
@echo ""
@echo " - \`make docker-build-cluster\`: build child_chain, watcher and watcher_info images \c"
@echo " - \`make docker-build-start-cluster\`: build child_chain, watcher and watcher_info images \c"
jarindr marked this conversation as resolved.
Show resolved Hide resolved
@echo "from your current code base, then start a cluster with these freshly built images."
@echo ""
@echo " - \`make docker-build-local\`" build child_chain, watcher and watcher_info images from your current code base
@echo ""
@echo " - \`make docker-update-watcher\`, \`make docker-update-watcher_info\` or \c"
@echo "\`make docker-update-child_chain\`: replaces containers with your code changes\c"
@echo "for rapid development."
Expand Down Expand Up @@ -305,6 +307,8 @@ docker-watcher: docker-watcher-prod docker-watcher-build
docker-watcher_info: docker-watcher_info-prod docker-watcher_info-build
docker-child_chain: docker-child_chain-prod docker-child_chain-build

docker-build-local: docker-watcher docker-watcher_info docker-child_chain
jarindr marked this conversation as resolved.
Show resolved Hide resolved

docker-push: docker
docker push $(CHILD_CHAIN_IMAGE_NAME)
docker push $(WATCHER_IMAGE_NAME)
Expand All @@ -315,7 +319,8 @@ docker-start-cluster:
SNAPSHOT=SNAPSHOT_MIX_EXIT_PERIOD_SECONDS_120 make init_test && \
docker-compose build --no-cache && docker-compose up

docker-build-cluster: docker-child_chain docker-watcher docker-watcher_info
docker-build-start-cluster:
$(MAKE) docker-build-local
SNAPSHOT=SNAPSHOT_MIX_EXIT_PERIOD_SECONDS_120 make init_test && \
docker-compose build --no-cache && docker-compose up

Expand Down
6 changes: 6 additions & 0 deletions apps/omg_utils/lib/omg_utils/http_rpc/validators/base.ex
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,12 @@ defmodule OMG.Utils.HttpRPC.Validator.Base do
def greater({val, []}, _b) when not is_integer(val), do: {val, [:integer]}
def greater({val, []}, bound), do: {val, greater: bound}

@spec lesser({any(), list()}, integer()) :: {any(), list()}
def lesser({_, [_ | _]} = err, _b), do: err
def lesser({val, []}, bound) when is_integer(val) and val < bound, do: {val, []}
def lesser({val, []}, _b) when not is_integer(val), do: {val, [:integer]}
def lesser({val, []}, bound), do: {val, lesser: bound}

@spec list({any(), list()}, function() | nil) :: {any(), list()}
def list(tuple, mapper \\ nil)
def list({_, [_ | _]} = err, _), do: err
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ defmodule OMG.Watcher.Integration.BlockGetterTest do
|> Enum.map(fn utxo -> Map.take(utxo, fields) end)

utxos =
alice.addr
%{address: alice.addr}
|> WatcherHelper.get_utxos()
|> Enum.map(fn utxo -> Map.take(utxo, fields) end)

Expand Down
10 changes: 9 additions & 1 deletion apps/omg_watcher/test/support/watcher_helper.ex
Original file line number Diff line number Diff line change
Expand Up @@ -125,8 +125,16 @@ defmodule Support.WatcherHelper do
|> Map.get("amount")
end

def get_utxos(params) when is_map(params) do
hex_string_address = Encoding.to_hex(params.address)
success?("/account.get_utxos", %{params | address: hex_string_address})
end

@doc """
shortcut helper for get_utxos that inject pagination data for you
"""
def get_utxos(address) do
success?("/account.get_utxos", %{"address" => Encoding.to_hex(address)})
success?("/account.get_utxos", %{"address" => Encoding.to_hex(address), "page" => 1, "limit" => 100})
jarindr marked this conversation as resolved.
Show resolved Hide resolved
end

def get_exitable_utxos(address) do
Expand Down
8 changes: 4 additions & 4 deletions apps/omg_watcher_info/lib/omg_watcher_info/api/account.ex
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ defmodule OMG.WatcherInfo.API.Account do
@moduledoc """
Module provides operations related to plasma accounts.
"""

alias OMG.Utils.Paginator
alias OMG.WatcherInfo.DB

@doc """
Expand All @@ -30,8 +30,8 @@ defmodule OMG.WatcherInfo.API.Account do
@doc """
Gets all utxos belonging to the given address.
"""
@spec get_utxos(OMG.Crypto.address_t()) :: list(%DB.TxOutput{})
def get_utxos(address) do
DB.TxOutput.get_utxos(address)
@spec get_utxos(Keyword.t()) :: Paginator.t()
jarindr marked this conversation as resolved.
Show resolved Hide resolved
def get_utxos(params) do
DB.TxOutput.get_utxos(params)
end
end
59 changes: 40 additions & 19 deletions apps/omg_watcher_info/lib/omg_watcher_info/db/txoutput.ex
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ defmodule OMG.WatcherInfo.DB.TxOutput do
use Ecto.Schema

alias OMG.State.Transaction
alias OMG.Utils.Paginator
alias OMG.Utxo
alias OMG.WatcherInfo.DB
alias OMG.WatcherInfo.DB.Repo
Expand All @@ -29,6 +30,8 @@ defmodule OMG.WatcherInfo.DB.TxOutput do

import Ecto.Query, only: [from: 2, where: 2]

@default_get_utxos_limit 200

@type balance() :: %{
currency: binary(),
amount: non_neg_integer()
Expand Down Expand Up @@ -79,24 +82,18 @@ defmodule OMG.WatcherInfo.DB.TxOutput do
)
end

def get_utxos(owner) do
query =
from(
txoutput in __MODULE__,
preload: [:ethevents],
left_join: ethevent in assoc(txoutput, :ethevents),
# select txoutputs by owner that have neither been spent nor have a corresponding ethevents exit events
where: txoutput.owner == ^owner and is_nil(txoutput.spending_txhash) and (is_nil(ethevent) or fragment("
NOT EXISTS (SELECT 1
FROM ethevents_txoutputs AS etfrag
JOIN ethevents AS efrag ON
etfrag.root_chain_txhash_event=efrag.root_chain_txhash_event
AND efrag.event_type IN (?)
AND etfrag.child_chain_utxohash = ?)", "standard_exit", txoutput.child_chain_utxohash)),
order_by: [asc: :blknum, asc: :txindex, asc: :oindex]
)

Repo.all(query)
@spec get_utxos(keyword) :: OMG.Utils.Paginator.t()
def get_utxos(params) do
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Very clean refactor. I like!

address = Keyword.fetch!(params, :address)
paginator = Paginator.from_constraints(params, @default_get_utxos_limit)
%{limit: limit, page: page} = paginator.data_paging
offset = (page - 1) * limit

address
|> query_get_utxos()
|> from(limit: ^limit, offset: ^offset)
|> Repo.all()
boolafish marked this conversation as resolved.
Show resolved Hide resolved
|> Paginator.set_data(paginator)
end

@spec get_balance(OMG.Crypto.address_t()) :: list(balance())
Expand Down Expand Up @@ -192,9 +189,33 @@ defmodule OMG.WatcherInfo.DB.TxOutput do
@spec get_sorted_grouped_utxos(OMG.Crypto.address_t()) :: %{OMG.Crypto.address_t() => list(%__MODULE__{})}
def get_sorted_grouped_utxos(owner) do
# TODO: use clever DB query to get following out of DB
get_utxos(owner)
owner
|> get_all_utxos()
|> Enum.group_by(& &1.currency)
|> Enum.map(fn {k, v} -> {k, Enum.sort_by(v, & &1.amount, &>=/2)} end)
|> Map.new()
end

defp query_get_utxos(address) do
from(
txoutput in __MODULE__,
preload: [:ethevents],
left_join: ethevent in assoc(txoutput, :ethevents),
# select txoutputs by owner that have neither been spent nor have a corresponding ethevents exit events
where: txoutput.owner == ^address and is_nil(txoutput.spending_txhash) and (is_nil(ethevent) or fragment("
NOT EXISTS (SELECT 1
FROM ethevents_txoutputs AS etfrag
JOIN ethevents AS efrag ON
etfrag.root_chain_txhash_event=efrag.root_chain_txhash_event
AND efrag.event_type IN (?)
AND etfrag.child_chain_utxohash = ?)", "standard_exit", txoutput.child_chain_utxohash)),
order_by: [asc: :blknum, asc: :txindex, asc: :oindex]
)
end

@spec get_all_utxos(OMG.Crypto.address_t()) :: list()
defp get_all_utxos(address) do
query = query_get_utxos(address)
Repo.all(query)
end
end
Original file line number Diff line number Diff line change
Expand Up @@ -189,9 +189,10 @@ defmodule OMG.WatcherInfo.DB.EthEventTest do
root_chain_txhash_event: ^expected_root_chain_txhash_event_3
} = DB.EthEvent.get(expected_root_chain_txhash_event_3)

%{data: alice_utxos} = DB.TxOutput.get_utxos(address: alice.addr)

assert [^expected_root_chain_txhash_1, ^expected_root_chain_txhash_2, ^expected_root_chain_txhash_3] =
DB.TxOutput.get_utxos(alice.addr)
|> Enum.map(fn txoutput ->
Enum.map(alice_utxos, fn txoutput ->
[head | _tail] = txoutput.ethevents
head.root_chain_txhash
end)
Expand Down Expand Up @@ -225,7 +226,8 @@ defmodule OMG.WatcherInfo.DB.EthEventTest do
}
])

assert length(DB.TxOutput.get_utxos(expected_owner)) == 1
%{data: utxos} = DB.TxOutput.get_utxos(address: expected_owner)
assert length(utxos) == 1

assert :ok =
DB.EthEvent.insert_exits!([
Expand All @@ -236,7 +238,8 @@ defmodule OMG.WatcherInfo.DB.EthEventTest do
}
])

assert Enum.empty?(DB.TxOutput.get_utxos(expected_owner))
%{data: utxos_after_exit} = DB.TxOutput.get_utxos(address: expected_owner)
assert Enum.empty?(utxos_after_exit)
end

@tag fixtures: [:alice, :initial_blocks]
Expand Down
7 changes: 4 additions & 3 deletions apps/omg_watcher_rpc/lib/web/controllers/account.ex
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ defmodule OMG.WatcherRPC.Web.Controller.Account do

alias OMG.Watcher.API, as: SecurityAPI
alias OMG.WatcherInfo.API, as: InfoAPI
alias OMG.WatcherRPC.Web.Validator.AccountConstraints

@doc """
Gets plasma account balance
Expand All @@ -34,8 +35,8 @@ defmodule OMG.WatcherRPC.Web.Controller.Account do
end

def get_utxos(conn, params) do
with {:ok, address} <- expect(params, "address", :address) do
address
with {:ok, constraints} <- AccountConstraints.parse(params) do
constraints
|> InfoAPI.Account.get_utxos()
|> api_response(conn, :utxos)
end
Expand All @@ -45,7 +46,7 @@ defmodule OMG.WatcherRPC.Web.Controller.Account do
with {:ok, address} <- expect(params, "address", :address) do
address
|> SecurityAPI.Account.get_exitable_utxos()
|> api_response(conn, :utxos)
|> api_response(conn, :exitable_utxos)
end
end
end
35 changes: 35 additions & 0 deletions apps/omg_watcher_rpc/lib/web/validators/account_constraints.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
# Copyright 2019-2020 OmiseGO Pte Ltd
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

defmodule OMG.WatcherRPC.Web.Validator.AccountConstraints do
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice! Thank you!

@moduledoc """
Validates `/account.get_utxos` query parameters
"""

import OMG.Utils.HttpRPC.Validator.Base, only: [expect: 3]

@doc """
Validates possible query constraints, stops on first error.
"""
@spec parse(%{binary() => any()}) :: {:ok, Keyword.t()} | {:error, any()}
def parse(params) do
constraints = [
{"limit", [pos_integer: true, lesser: 1000, optional: true], :limit},
{"page", [:pos_integer, :optional], :page},
{"address", [:address], :address}
]

OMG.WatcherRPC.Web.Validator.Helpers.validate_constraints(params, constraints)
end
end
14 changes: 3 additions & 11 deletions apps/omg_watcher_rpc/lib/web/validators/block_constraints.ex
Original file line number Diff line number Diff line change
Expand Up @@ -17,24 +17,16 @@ defmodule OMG.WatcherRPC.Web.Validator.BlockConstraints do
Validates `/block.all` query parameters
"""

import OMG.Utils.HttpRPC.Validator.Base, only: [expect: 3]

@doc """
Validates possible query constraints, stops on first error.
"""
@spec parse(%{binary() => any()}) :: {:ok, Keyword.t()} | {:error, any()}
def parse(params) do
constraints = [
{"limit", [:pos_integer, :optional]},
{"page", [:pos_integer, :optional]}
{"limit", [pos_integer: true, lesser: 1000, optional: true], :limit},
{"page", [:pos_integer, :optional], :page}
]

Enum.reduce_while(constraints, {:ok, []}, fn {key, validators}, {:ok, list} ->
case expect(params, key, validators) do
{:ok, nil} -> {:cont, {:ok, list}}
{:ok, value} -> {:cont, {:ok, [{String.to_existing_atom(key), value} | list]}}
error -> {:halt, error}
end
end)
OMG.WatcherRPC.Web.Validator.Helpers.validate_constraints(params, constraints)
end
end
38 changes: 38 additions & 0 deletions apps/omg_watcher_rpc/lib/web/validators/helpers.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
# Copyright 2019-2020 OmiseGO Pte Ltd
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

defmodule OMG.WatcherRPC.Web.Validator.Helpers do
@moduledoc """
helper for validators
"""
import OMG.Utils.HttpRPC.Validator.Base, only: [expect: 3]

@doc """
Validates possible query constraints, stops on first error.
"""
def validate_constraints(params, constraints) do
jarindr marked this conversation as resolved.
Show resolved Hide resolved
Enum.reduce_while(constraints, {:ok, []}, fn {key, validators, atom}, {:ok, list} ->
case expect(params, key, validators) do
{:ok, nil} ->
{:cont, {:ok, list}}

{:ok, value} ->
{:cont, {:ok, [{atom, value} | list]}}

error ->
{:halt, error}
end
end)
end
end
19 changes: 3 additions & 16 deletions apps/omg_watcher_rpc/lib/web/validators/transaction_constraints.ex
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,7 @@ defmodule OMG.WatcherRPC.Web.Validator.TransactionConstraints do
@moduledoc """
Validates `/transaction.all` query parameters
"""

import OMG.Utils.HttpRPC.Validator.Base

import OMG.Utils.HttpRPC.Validator.Base, only: [expect: 3]
@max_tx_types 16

@doc """
Expand All @@ -31,22 +29,11 @@ defmodule OMG.WatcherRPC.Web.Validator.TransactionConstraints do
{"blknum", [:pos_integer, :optional], :blknum},
{"metadata", [:hash, :optional], :metadata},
{"txtypes", [list: &to_tx_type/1, max_length: @max_tx_types, optional: true], :txtypes},
{"limit", [:pos_integer, :optional], :limit},
{"limit", [pos_integer: true, lesser: 1000, optional: true], :limit},
{"page", [:pos_integer, :optional], :page}
]

Enum.reduce_while(constraints, {:ok, []}, fn {key, validators, atom}, {:ok, list} ->
case expect(params, key, validators) do
{:ok, nil} ->
{:cont, {:ok, list}}

{:ok, value} ->
{:cont, {:ok, [{atom, value} | list]}}

error ->
{:halt, error}
end
end)
OMG.WatcherRPC.Web.Validator.Helpers.validate_constraints(params, constraints)
end

defp to_tx_type(tx_type_str) do
Expand Down
Loading