parent
4f326808cd
commit
f0ace70d9b
@ -1 +1,2 @@ |
|||||||
web: mix phx.server |
web: mix phx.server |
||||||
|
worker: mix exq.start |
||||||
|
@ -1,16 +0,0 @@ |
|||||||
defmodule Explorer.LatestBlock do |
|
||||||
alias Explorer.Fetcher |
|
||||||
import Ethereumex.HttpClient, only: [eth_block_number: 0] |
|
||||||
|
|
||||||
@moduledoc false |
|
||||||
|
|
||||||
@dialyzer {:nowarn_function, fetch: 0} |
|
||||||
def fetch do |
|
||||||
get_latest_block() |> Fetcher.fetch |
|
||||||
end |
|
||||||
|
|
||||||
def get_latest_block do |
|
||||||
{:ok, block_number} = eth_block_number() |
|
||||||
block_number |
|
||||||
end |
|
||||||
end |
|
@ -1,38 +1,29 @@ |
|||||||
defmodule Explorer.SkippedBlocks do |
defmodule Explorer.SkippedBlocks do |
||||||
alias Explorer.Fetcher |
|
||||||
alias Explorer.Block |
alias Explorer.Block |
||||||
alias Explorer.Repo |
alias Explorer.Repo |
||||||
alias Ecto.Adapters.SQL |
alias Ecto.Adapters.SQL |
||||||
import Ecto.Query |
|
||||||
|
import Ecto.Query, only: [limit: 2] |
||||||
|
|
||||||
@moduledoc false |
@moduledoc false |
||||||
|
|
||||||
@query """ |
@query """ |
||||||
SELECT missing_numbers.number AS missing_number |
SELECT missing_numbers.number AS missing_number |
||||||
FROM generate_series($1, 1, -1) missing_numbers(number) |
FROM generate_series($1, 0, -1) missing_numbers(number) |
||||||
LEFT OUTER JOIN blocks ON (blocks.number = missing_numbers.number) |
LEFT OUTER JOIN blocks ON (blocks.number = missing_numbers.number) |
||||||
WHERE blocks.id IS NULL; |
WHERE blocks.id IS NULL |
||||||
|
LIMIT $2; |
||||||
""" |
""" |
||||||
|
|
||||||
@dialyzer {:nowarn_function, fetch: 0} |
def first, do: first(1) |
||||||
def fetch do |
def first(count) do |
||||||
get_skipped_blocks() |
SQL.query!(Repo, @query, [latest_block_number(), count]).rows |
||||||
|> Enum.map(&Integer.to_string/1) |
|
||||||
|> Enum.map(&Fetcher.fetch/1) |
|
||||||
end |
|
||||||
|
|
||||||
def get_skipped_blocks do |
|
||||||
last_block_number = get_last_block_number() |
|
||||||
SQL.query!(Repo, @query, [last_block_number]).rows |
|
||||||
|> Enum.map(&List.first/1) |
|> Enum.map(&List.first/1) |
||||||
|
|> Enum.map(&Integer.to_string/1) |
||||||
end |
end |
||||||
|
|
||||||
def get_last_block_number do |
def latest_block_number do |
||||||
block = Block |
(Block |> Block.latest |> limit(1) |> Repo.one || Block.null) |
||||||
|> order_by(desc: :number) |
|> Map.fetch!(:number) |
||||||
|> limit(1) |
|
||||||
|> Repo.all |
|
||||||
|> List.first || %{number: 0} |
|
||||||
block.number |
|
||||||
end |
end |
||||||
end |
end |
||||||
|
@ -0,0 +1,17 @@ |
|||||||
|
defmodule Explorer.Workers.ImportBlock do |
||||||
|
alias Explorer.Fetcher |
||||||
|
|
||||||
|
@moduledoc "Imports blocks by web3 conventions." |
||||||
|
|
||||||
|
@dialyzer {:nowarn_function, perform: 1} |
||||||
|
def perform(number) do |
||||||
|
Fetcher.fetch("#{number}") |
||||||
|
end |
||||||
|
|
||||||
|
@dialyzer {:nowarn_function, perform: 0} |
||||||
|
def perform, do: perform("latest") |
||||||
|
|
||||||
|
def perform_later(number) do |
||||||
|
Exq.enqueue(Exq.Enqueuer, "default", __MODULE__, [number]) |
||||||
|
end |
||||||
|
end |
@ -0,0 +1,16 @@ |
|||||||
|
defmodule Explorer.Workers.ImportSkippedBlocks do |
||||||
|
alias Explorer.SkippedBlocks |
||||||
|
alias Explorer.Workers.ImportBlock |
||||||
|
|
||||||
|
@moduledoc "Imports skipped blocks." |
||||||
|
|
||||||
|
def perform, do: perform(1) |
||||||
|
def perform(count) do |
||||||
|
count |> SkippedBlocks.first |> Enum.map(&ImportBlock.perform_later/1) |
||||||
|
end |
||||||
|
|
||||||
|
def perform_later, do: perform_later(1) |
||||||
|
def perform_later(count) do |
||||||
|
Exq.enqueue(Exq.Enqueuer, "default", __MODULE__, [count]) |
||||||
|
end |
||||||
|
end |
@ -1,12 +0,0 @@ |
|||||||
defmodule Mix.Tasks.Backfill do |
|
||||||
use Mix.Task |
|
||||||
alias Explorer.SkippedBlocks |
|
||||||
|
|
||||||
@shortdoc "Backfill blocks from the chain." |
|
||||||
@moduledoc false |
|
||||||
|
|
||||||
def run(_) do |
|
||||||
Mix.Task.run("app.start") |
|
||||||
SkippedBlocks.fetch() |
|
||||||
end |
|
||||||
end |
|
@ -0,0 +1,18 @@ |
|||||||
|
defmodule Mix.Tasks.Exq.Start do |
||||||
|
alias Explorer.Repo |
||||||
|
alias Explorer.Scheduler |
||||||
|
|
||||||
|
use Mix.Task |
||||||
|
|
||||||
|
@moduledoc "Starts the Exq worker" |
||||||
|
|
||||||
|
def run(_args) do |
||||||
|
[:postgrex, :ecto, :ethereumex, :tzdata] |
||||||
|
|> Enum.each(&Application.ensure_all_started/1) |
||||||
|
Repo.start_link() |
||||||
|
Exq.start_link(mode: :default) |
||||||
|
Scheduler.start_link() |
||||||
|
IO.puts "Started Exq" |
||||||
|
:timer.sleep(:infinity) |
||||||
|
end |
||||||
|
end |
@ -1,13 +0,0 @@ |
|||||||
defmodule Mix.Tasks.Scrape do |
|
||||||
use Mix.Task |
|
||||||
alias Explorer.LatestBlock |
|
||||||
|
|
||||||
@shortdoc "Scrape the blockchain." |
|
||||||
@moduledoc false |
|
||||||
|
|
||||||
@dialyzer {:nowarn_function, run: 1} |
|
||||||
def run(_) do |
|
||||||
Mix.Task.run("app.start") |
|
||||||
LatestBlock.fetch() |
|
||||||
end |
|
||||||
end |
|
@ -1,31 +0,0 @@ |
|||||||
defmodule Explorer.LatestBlockTest do |
|
||||||
use Explorer.DataCase |
|
||||||
|
|
||||||
alias Explorer.Block |
|
||||||
alias Explorer.Repo |
|
||||||
alias Explorer.LatestBlock |
|
||||||
|
|
||||||
describe "fetch/0" do |
|
||||||
test "the latest block is copied over from the blockchain" do |
|
||||||
use_cassette "latest_block_fetch" do |
|
||||||
LatestBlock.fetch() |
|
||||||
|
|
||||||
last_block = Block |
|
||||||
|> order_by(desc: :inserted_at) |
|
||||||
|> limit(1) |
|
||||||
|> Repo.all |
|
||||||
|> List.first |
|
||||||
|
|
||||||
assert(last_block.number) |
|
||||||
end |
|
||||||
end |
|
||||||
end |
|
||||||
|
|
||||||
describe "get_latest_block/0" do |
|
||||||
test "returns the number of the latest block" do |
|
||||||
use_cassette "fetcher_get_latest_block" do |
|
||||||
assert LatestBlock.get_latest_block() == "0x89923" |
|
||||||
end |
|
||||||
end |
|
||||||
end |
|
||||||
end |
|
@ -1,53 +1,76 @@ |
|||||||
defmodule Explorer.SkippedBlocksTest do |
defmodule Explorer.SkippedBlocksTest do |
||||||
use Explorer.DataCase |
use Explorer.DataCase |
||||||
|
|
||||||
alias Explorer.Block |
|
||||||
alias Explorer.Repo |
|
||||||
alias Explorer.SkippedBlocks |
alias Explorer.SkippedBlocks |
||||||
|
|
||||||
describe "fetch/0" do |
describe "first/0 when there are no blocks" do |
||||||
test "inserts a missing block into the database" do |
test "returns no blocks" do |
||||||
insert(:block, %{number: 2}) |
assert SkippedBlocks.first() == [] |
||||||
use_cassette "skipped_block_fetch" do |
end |
||||||
SkippedBlocks.fetch() |
end |
||||||
|
|
||||||
blocks = Block |> order_by(asc: :number) |> Repo.all |> Enum.map(fn(block) -> block.number end) |
describe "first/0 when there are no skipped blocks" do |
||||||
|
test "returns no blocks" do |
||||||
|
insert(:block, %{number: 0}) |
||||||
|
assert SkippedBlocks.first() == [] |
||||||
|
end |
||||||
|
end |
||||||
|
|
||||||
assert blocks == [1, 2] |
describe "first/0 when a block has been skipped" do |
||||||
end |
test "returns the first skipped block number" do |
||||||
|
insert(:block, %{number: 0}) |
||||||
|
insert(:block, %{number: 2}) |
||||||
|
assert SkippedBlocks.first() == ["1"] |
||||||
end |
end |
||||||
end |
end |
||||||
|
|
||||||
describe "get_skipped_blocks/0 when there are no blocks" do |
describe "first/1 when there are no blocks" do |
||||||
test "returns no blocks" do |
test "returns no blocks" do |
||||||
assert SkippedBlocks.get_skipped_blocks() == [] |
assert SkippedBlocks.first(1) == [] |
||||||
end |
end |
||||||
end |
end |
||||||
|
|
||||||
describe "get_skipped_blocks/0 when there are no skipped blocks" do |
describe "first/1 when there are no skipped blocks" do |
||||||
test "returns no blocks" do |
test "returns no blocks" do |
||||||
insert(:block, %{number: 1}) |
insert(:block, %{number: 0}) |
||||||
assert SkippedBlocks.get_skipped_blocks() == [] |
assert SkippedBlocks.first(1) == [] |
||||||
end |
end |
||||||
end |
end |
||||||
|
|
||||||
describe "get_skipped_blocks/0 when a block has been skipped" do |
describe "first/1 when a block has been skipped" do |
||||||
test "returns no blocks" do |
test "returns the skipped block number" do |
||||||
insert(:block, %{number: 2}) |
insert(:block, %{number: 1}) |
||||||
assert SkippedBlocks.get_skipped_blocks() == [1] |
assert SkippedBlocks.first(1) == ["0"] |
||||||
|
end |
||||||
|
|
||||||
|
test "returns up to the requested number of skipped block numbers in reverse order" do |
||||||
|
insert(:block, %{number: 1}) |
||||||
|
insert(:block, %{number: 3}) |
||||||
|
assert SkippedBlocks.first(1) == ["2"] |
||||||
|
end |
||||||
|
|
||||||
|
test "returns only the skipped block number" do |
||||||
|
insert(:block, %{number: 1}) |
||||||
|
assert SkippedBlocks.first(100) == ["0"] |
||||||
|
end |
||||||
|
|
||||||
|
test "returns all the skipped block numbers in descending order" do |
||||||
|
insert(:block, %{number: 1}) |
||||||
|
insert(:block, %{number: 3}) |
||||||
|
assert SkippedBlocks.first(100) == ["2", "0"] |
||||||
end |
end |
||||||
end |
end |
||||||
|
|
||||||
describe "get_last_block_number/0 when there are no blocks" do |
describe "latest_block_number/0 when there are no blocks" do |
||||||
test "returns zero" do |
test "returns -1" do |
||||||
assert SkippedBlocks.get_last_block_number() == 0 |
assert SkippedBlocks.latest_block_number() == -1 |
||||||
end |
end |
||||||
end |
end |
||||||
|
|
||||||
describe "get_last_block_number/0 when there is a block" do |
describe "latest_block_number/0 when there is a block" do |
||||||
test "returns the number of the block" do |
test "returns the number of the block" do |
||||||
insert(:block, %{number: 1}) |
insert(:block, %{number: 1}) |
||||||
assert SkippedBlocks.get_last_block_number() == 1 |
assert SkippedBlocks.latest_block_number() == 1 |
||||||
end |
end |
||||||
end |
end |
||||||
end |
end |
||||||
|
@ -0,0 +1,38 @@ |
|||||||
|
defmodule Explorer.Workers.ImportBlockTest do |
||||||
|
use Explorer.DataCase |
||||||
|
alias Explorer.Block |
||||||
|
alias Explorer.Repo |
||||||
|
|
||||||
|
test "perform/1 imports the requested block number as an integer" do |
||||||
|
use_cassette "import_block_perform_1_integer" do |
||||||
|
Explorer.Workers.ImportBlock.perform(1) |
||||||
|
last_block = Block |> order_by(asc: :number) |> Repo.one |
||||||
|
assert last_block.number == 1 |
||||||
|
end |
||||||
|
end |
||||||
|
|
||||||
|
test "perform/1 imports the requested block number as a string" do |
||||||
|
use_cassette "import_block_perform_1_string" do |
||||||
|
Explorer.Workers.ImportBlock.perform("1") |
||||||
|
last_block = Block |> order_by(asc: :number) |> Repo.one |
||||||
|
assert last_block.number == 1 |
||||||
|
end |
||||||
|
end |
||||||
|
|
||||||
|
test "perform/1 imports the earliest block" do |
||||||
|
use_cassette "import_block_perform_1_earliest" do |
||||||
|
Explorer.Workers.ImportBlock.perform("earliest") |
||||||
|
last_block = Block |> order_by(asc: :number) |> Repo.one |
||||||
|
assert last_block.number == 0 |
||||||
|
end |
||||||
|
end |
||||||
|
|
||||||
|
test "perform/1 when there is alaready a block with the requested hash" do |
||||||
|
use_cassette "import_block_perform_1_duplicate" do |
||||||
|
insert(:block, hash: "0x52c867bc0a91e573dc39300143c3bead7408d09d45bdb686749f02684ece72f3") |
||||||
|
Explorer.Workers.ImportBlock.perform("1") |
||||||
|
block_count = Block |> Repo.all |> Enum.count |
||||||
|
assert block_count == 1 |
||||||
|
end |
||||||
|
end |
||||||
|
end |
@ -0,0 +1,23 @@ |
|||||||
|
defmodule Explorer.Workers.ImportSkippedBlocksTest do |
||||||
|
alias Explorer.Block |
||||||
|
alias Explorer.Repo |
||||||
|
alias Explorer.Workers.ImportBlock |
||||||
|
alias Explorer.Workers.ImportSkippedBlocks |
||||||
|
|
||||||
|
import Mock |
||||||
|
|
||||||
|
use Explorer.DataCase |
||||||
|
|
||||||
|
describe "perform/1" do |
||||||
|
test "imports the requested number of skipped blocks" do |
||||||
|
insert(:block, %{number: 2}) |
||||||
|
use_cassette "import_skipped_blocks_perform_1" do |
||||||
|
with_mock ImportBlock, [perform_later: fn (number) -> insert(:block, number: number) end] do |
||||||
|
ImportSkippedBlocks.perform(1) |
||||||
|
last_block = Block |> order_by(asc: :number) |> limit(1) |> Repo.one |
||||||
|
assert last_block.number == 1 |
||||||
|
end |
||||||
|
end |
||||||
|
end |
||||||
|
end |
||||||
|
end |
@ -0,0 +1,11 @@ |
|||||||
|
defmodule ExplorerWeb.ExqTest do |
||||||
|
use ExplorerWeb.FeatureCase, async: true |
||||||
|
|
||||||
|
import Wallaby.Query, only: [css: 2] |
||||||
|
|
||||||
|
test "views the exq dashboard", %{session: session} do |
||||||
|
session |
||||||
|
|> visit("/exq") |
||||||
|
|> assert_has(css(".navbar-brand", text: "Exq")) |
||||||
|
end |
||||||
|
end |
@ -1,21 +0,0 @@ |
|||||||
defmodule Scrape.Backfill do |
|
||||||
use Explorer.DataCase |
|
||||||
alias Explorer.Block |
|
||||||
alias Explorer.Repo |
|
||||||
|
|
||||||
test "backfills previous blocks" do |
|
||||||
insert(:block, %{number: 2}) |
|
||||||
|
|
||||||
use_cassette "backfill" do |
|
||||||
Mix.Tasks.Backfill.run([]) |
|
||||||
|
|
||||||
last_block = Block |
|
||||||
|> order_by(asc: :number) |
|
||||||
|> limit(1) |
|
||||||
|> Repo.all |
|
||||||
|> List.first |
|
||||||
|
|
||||||
assert last_block.number == 1 |
|
||||||
end |
|
||||||
end |
|
||||||
end |
|
@ -1,19 +0,0 @@ |
|||||||
defmodule Scrape.Test do |
|
||||||
use Explorer.DataCase |
|
||||||
alias Explorer.Block |
|
||||||
alias Explorer.Repo |
|
||||||
|
|
||||||
test "it downloads a new block" do |
|
||||||
use_cassette "scrape" do |
|
||||||
Mix.Tasks.Scrape.run([]) |
|
||||||
|
|
||||||
last_block = Block |
|
||||||
|> order_by(desc: :inserted_at) |
|
||||||
|> limit(1) |
|
||||||
|> Repo.all |
|
||||||
|> List.first |
|
||||||
|
|
||||||
assert(last_block.number) |
|
||||||
end |
|
||||||
end |
|
||||||
end |
|
@ -0,0 +1 @@ |
|||||||
|
[] |
@ -0,0 +1,30 @@ |
|||||||
|
[ |
||||||
|
{ |
||||||
|
"request": { |
||||||
|
"body": "{\"params\":[\"1\",true],\"method\":\"eth_getBlockByNumber\",\"jsonrpc\":\"2.0\",\"id\":3}", |
||||||
|
"headers": { |
||||||
|
"Content-Type": "application/json" |
||||||
|
}, |
||||||
|
"method": "post", |
||||||
|
"options": [], |
||||||
|
"request_body": "", |
||||||
|
"url": "https://sokol.poa.network:443" |
||||||
|
}, |
||||||
|
"response": { |
||||||
|
"binary": false, |
||||||
|
"body": "{\"jsonrpc\":\"2.0\",\"result\":{\"author\":\"0xe8ddc5c7a2d2f0d7a9798459c0104fdf5e987aca\",\"difficulty\":\"0xffffffffffffffffffffffffedf58e45\",\"extraData\":\"0xd5830108048650617269747986312e32322e31826c69\",\"gasLimit\":\"0x66556d\",\"gasUsed\":\"0x0\",\"hash\":\"0x52c867bc0a91e573dc39300143c3bead7408d09d45bdb686749f02684ece72f3\",\"logsBloom\":\"0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\",\"miner\":\"0xe8ddc5c7a2d2f0d7a9798459c0104fdf5e987aca\",\"number\":\"0x1\",\"parentHash\":\"0x5b28c1bfd3a15230c9a46b399cd0f9a6920d432e85381cc6a140b06e8410112f\",\"receiptsRoot\":\"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421\",\"sealFields\":[\"0x84120a71ba\",\"0xb8417a5887662f09ac4673af5850d28f3ad6550407b9c814ef563a13320f881b55ef03754f48f2dde027ad4a5abcabcc42780d9ebfc645f183e5252507d6a25bc2ec01\"],\"sha3Uncles\":\"0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347\",\"signature\":\"7a5887662f09ac4673af5850d28f3ad6550407b9c814ef563a13320f881b55ef03754f48f2dde027ad4a5abcabcc42780d9ebfc645f183e5252507d6a25bc2ec01\",\"size\":\"0x240\",\"stateRoot\":\"0xc196ad59d867542ef20b29df5f418d07dc7234f4bc3d25260526620b7958a8fb\",\"step\":\"302674362\",\"timestamp\":\"0x5a3438a2\",\"totalDifficulty\":\"0xffffffffffffffffffffffffedf78e45\",\"transactions\":[],\"transactionsRoot\":\"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421\",\"uncles\":[]},\"id\":3}\n", |
||||||
|
"headers": { |
||||||
|
"Date": "Sun, 04 Feb 2018 07:41:06 GMT", |
||||||
|
"Content-Type": "application/json", |
||||||
|
"Transfer-Encoding": "chunked", |
||||||
|
"Connection": "keep-alive", |
||||||
|
"Set-Cookie": "__cfduid=d9be038a0189dadf6dd2c0f72a4626d271517730066; expires=Mon, 04-Feb-19 07:41:06 GMT; path=/; domain=.poa.network; HttpOnly; Secure", |
||||||
|
"Expect-CT": "max-age=604800, report-uri=\"https://report-uri.cloudflare.com/cdn-cgi/beacon/expect-ct\"", |
||||||
|
"Server": "cloudflare", |
||||||
|
"CF-RAY": "3e7bfc51196092e8-SJC" |
||||||
|
}, |
||||||
|
"status_code": 200, |
||||||
|
"type": "ok" |
||||||
|
} |
||||||
|
} |
||||||
|
] |
@ -0,0 +1,30 @@ |
|||||||
|
[ |
||||||
|
{ |
||||||
|
"request": { |
||||||
|
"body": "{\"params\":[\"earliest\",true],\"method\":\"eth_getBlockByNumber\",\"jsonrpc\":\"2.0\",\"id\":2}", |
||||||
|
"headers": { |
||||||
|
"Content-Type": "application/json" |
||||||
|
}, |
||||||
|
"method": "post", |
||||||
|
"options": [], |
||||||
|
"request_body": "", |
||||||
|
"url": "https://sokol.poa.network:443" |
||||||
|
}, |
||||||
|
"response": { |
||||||
|
"binary": false, |
||||||
|
"body": "{\"jsonrpc\":\"2.0\",\"result\":{\"author\":\"0x0000000000000000000000000000000000000000\",\"difficulty\":\"0x20000\",\"extraData\":\"0x\",\"gasLimit\":\"0x663be0\",\"gasUsed\":\"0x0\",\"hash\":\"0x5b28c1bfd3a15230c9a46b399cd0f9a6920d432e85381cc6a140b06e8410112f\",\"logsBloom\":\"0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\",\"miner\":\"0x0000000000000000000000000000000000000000\",\"number\":\"0x0\",\"parentHash\":\"0x0000000000000000000000000000000000000000000000000000000000000000\",\"receiptsRoot\":\"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421\",\"sealFields\":[\"0x80\",\"0xb8410000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\"],\"sha3Uncles\":\"0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347\",\"signature\":\"0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\",\"size\":\"0x215\",\"stateRoot\":\"0xfad4af258fd11939fae0c6c6eec9d340b1caac0b0196fd9a1bc3f489c5bf00b3\",\"step\":\"0\",\"timestamp\":\"0x0\",\"totalDifficulty\":\"0x20000\",\"transactions\":[],\"transactionsRoot\":\"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421\",\"uncles\":[]},\"id\":2}\n", |
||||||
|
"headers": { |
||||||
|
"Date": "Sun, 04 Feb 2018 01:09:56 GMT", |
||||||
|
"Content-Type": "application/json", |
||||||
|
"Transfer-Encoding": "chunked", |
||||||
|
"Connection": "keep-alive", |
||||||
|
"Set-Cookie": "__cfduid=ddc1b2cd399b32475cbc191f806ff29d61517706596; expires=Mon, 04-Feb-19 01:09:56 GMT; path=/; domain=.poa.network; HttpOnly; Secure", |
||||||
|
"Expect-CT": "max-age=604800, report-uri=\"https://report-uri.cloudflare.com/cdn-cgi/beacon/expect-ct\"", |
||||||
|
"Server": "cloudflare", |
||||||
|
"CF-RAY": "3e79bf530a669601-SJC" |
||||||
|
}, |
||||||
|
"status_code": 200, |
||||||
|
"type": "ok" |
||||||
|
} |
||||||
|
} |
||||||
|
] |
@ -0,0 +1,30 @@ |
|||||||
|
[ |
||||||
|
{ |
||||||
|
"request": { |
||||||
|
"body": "{\"params\":[\"1\",true],\"method\":\"eth_getBlockByNumber\",\"jsonrpc\":\"2.0\",\"id\":0}", |
||||||
|
"headers": { |
||||||
|
"Content-Type": "application/json" |
||||||
|
}, |
||||||
|
"method": "post", |
||||||
|
"options": [], |
||||||
|
"request_body": "", |
||||||
|
"url": "https://sokol.poa.network:443" |
||||||
|
}, |
||||||
|
"response": { |
||||||
|
"binary": false, |
||||||
|
"body": "{\"jsonrpc\":\"2.0\",\"result\":{\"author\":\"0xe8ddc5c7a2d2f0d7a9798459c0104fdf5e987aca\",\"difficulty\":\"0xffffffffffffffffffffffffedf58e45\",\"extraData\":\"0xd5830108048650617269747986312e32322e31826c69\",\"gasLimit\":\"0x66556d\",\"gasUsed\":\"0x0\",\"hash\":\"0x52c867bc0a91e573dc39300143c3bead7408d09d45bdb686749f02684ece72f3\",\"logsBloom\":\"0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\",\"miner\":\"0xe8ddc5c7a2d2f0d7a9798459c0104fdf5e987aca\",\"number\":\"0x1\",\"parentHash\":\"0x5b28c1bfd3a15230c9a46b399cd0f9a6920d432e85381cc6a140b06e8410112f\",\"receiptsRoot\":\"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421\",\"sealFields\":[\"0x84120a71ba\",\"0xb8417a5887662f09ac4673af5850d28f3ad6550407b9c814ef563a13320f881b55ef03754f48f2dde027ad4a5abcabcc42780d9ebfc645f183e5252507d6a25bc2ec01\"],\"sha3Uncles\":\"0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347\",\"signature\":\"7a5887662f09ac4673af5850d28f3ad6550407b9c814ef563a13320f881b55ef03754f48f2dde027ad4a5abcabcc42780d9ebfc645f183e5252507d6a25bc2ec01\",\"size\":\"0x240\",\"stateRoot\":\"0xc196ad59d867542ef20b29df5f418d07dc7234f4bc3d25260526620b7958a8fb\",\"step\":\"302674362\",\"timestamp\":\"0x5a3438a2\",\"totalDifficulty\":\"0xffffffffffffffffffffffffedf78e45\",\"transactions\":[],\"transactionsRoot\":\"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421\",\"uncles\":[]},\"id\":0}\n", |
||||||
|
"headers": { |
||||||
|
"Date": "Sun, 04 Feb 2018 01:09:55 GMT", |
||||||
|
"Content-Type": "application/json", |
||||||
|
"Transfer-Encoding": "chunked", |
||||||
|
"Connection": "keep-alive", |
||||||
|
"Set-Cookie": "__cfduid=dd200d77362e268d446c7df8154111eac1517706595; expires=Mon, 04-Feb-19 01:09:55 GMT; path=/; domain=.poa.network; HttpOnly; Secure", |
||||||
|
"Expect-CT": "max-age=604800, report-uri=\"https://report-uri.cloudflare.com/cdn-cgi/beacon/expect-ct\"", |
||||||
|
"Server": "cloudflare", |
||||||
|
"CF-RAY": "3e79bf4df8849601-SJC" |
||||||
|
}, |
||||||
|
"status_code": 200, |
||||||
|
"type": "ok" |
||||||
|
} |
||||||
|
} |
||||||
|
] |
@ -0,0 +1,30 @@ |
|||||||
|
[ |
||||||
|
{ |
||||||
|
"request": { |
||||||
|
"body": "{\"params\":[\"1\",true],\"method\":\"eth_getBlockByNumber\",\"jsonrpc\":\"2.0\",\"id\":1}", |
||||||
|
"headers": { |
||||||
|
"Content-Type": "application/json" |
||||||
|
}, |
||||||
|
"method": "post", |
||||||
|
"options": [], |
||||||
|
"request_body": "", |
||||||
|
"url": "https://sokol.poa.network:443" |
||||||
|
}, |
||||||
|
"response": { |
||||||
|
"binary": false, |
||||||
|
"body": "{\"jsonrpc\":\"2.0\",\"result\":{\"author\":\"0xe8ddc5c7a2d2f0d7a9798459c0104fdf5e987aca\",\"difficulty\":\"0xffffffffffffffffffffffffedf58e45\",\"extraData\":\"0xd5830108048650617269747986312e32322e31826c69\",\"gasLimit\":\"0x66556d\",\"gasUsed\":\"0x0\",\"hash\":\"0x52c867bc0a91e573dc39300143c3bead7408d09d45bdb686749f02684ece72f3\",\"logsBloom\":\"0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000\",\"miner\":\"0xe8ddc5c7a2d2f0d7a9798459c0104fdf5e987aca\",\"number\":\"0x1\",\"parentHash\":\"0x5b28c1bfd3a15230c9a46b399cd0f9a6920d432e85381cc6a140b06e8410112f\",\"receiptsRoot\":\"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421\",\"sealFields\":[\"0x84120a71ba\",\"0xb8417a5887662f09ac4673af5850d28f3ad6550407b9c814ef563a13320f881b55ef03754f48f2dde027ad4a5abcabcc42780d9ebfc645f183e5252507d6a25bc2ec01\"],\"sha3Uncles\":\"0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347\",\"signature\":\"7a5887662f09ac4673af5850d28f3ad6550407b9c814ef563a13320f881b55ef03754f48f2dde027ad4a5abcabcc42780d9ebfc645f183e5252507d6a25bc2ec01\",\"size\":\"0x240\",\"stateRoot\":\"0xc196ad59d867542ef20b29df5f418d07dc7234f4bc3d25260526620b7958a8fb\",\"step\":\"302674362\",\"timestamp\":\"0x5a3438a2\",\"totalDifficulty\":\"0xffffffffffffffffffffffffedf78e45\",\"transactions\":[],\"transactionsRoot\":\"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421\",\"uncles\":[]},\"id\":1}\n", |
||||||
|
"headers": { |
||||||
|
"Date": "Sun, 04 Feb 2018 01:09:56 GMT", |
||||||
|
"Content-Type": "application/json", |
||||||
|
"Transfer-Encoding": "chunked", |
||||||
|
"Connection": "keep-alive", |
||||||
|
"Set-Cookie": "__cfduid=dd200d77362e268d446c7df8154111eac1517706595; expires=Mon, 04-Feb-19 01:09:55 GMT; path=/; domain=.poa.network; HttpOnly; Secure", |
||||||
|
"Expect-CT": "max-age=604800, report-uri=\"https://report-uri.cloudflare.com/cdn-cgi/beacon/expect-ct\"", |
||||||
|
"Server": "cloudflare", |
||||||
|
"CF-RAY": "3e79bf4fa9299601-SJC" |
||||||
|
}, |
||||||
|
"status_code": 200, |
||||||
|
"type": "ok" |
||||||
|
} |
||||||
|
} |
||||||
|
] |
Loading…
Reference in new issue