commit
302ac49553
@ -1,28 +0,0 @@ |
||||
import $ from 'jquery' |
||||
|
||||
$(function () { |
||||
$('.js-btn-add-contract-libraries').on('click', function () { |
||||
$('.js-smart-contract-libraries-wrapper').show() |
||||
$(this).hide() |
||||
}) |
||||
|
||||
$('.js-smart-contract-form-reset').on('click', function () { |
||||
$('.js-contract-library-form-group').removeClass('active') |
||||
$('.js-contract-library-form-group').first().addClass('active') |
||||
$('.js-smart-contract-libraries-wrapper').hide() |
||||
$('.js-btn-add-contract-libraries').show() |
||||
$('.js-add-contract-library-wrapper').show() |
||||
}) |
||||
|
||||
$('.js-btn-add-contract-library').on('click', function () { |
||||
let nextContractLibrary = $('.js-contract-library-form-group.active').next('.js-contract-library-form-group') |
||||
|
||||
if (nextContractLibrary) { |
||||
nextContractLibrary.addClass('active') |
||||
} |
||||
|
||||
if ($('.js-contract-library-form-group.active').length === $('.js-contract-library-form-group').length) { |
||||
$('.js-add-contract-library-wrapper').hide() |
||||
} |
||||
}) |
||||
}) |
@ -0,0 +1,144 @@ |
||||
import $ from 'jquery' |
||||
import _ from 'lodash' |
||||
import URI from 'urijs' |
||||
import humps from 'humps' |
||||
import { subscribeChannel } from '../socket' |
||||
import { createStore, connectElements } from '../lib/redux_helpers.js' |
||||
|
||||
export const initialState = { |
||||
channelDisconnected: false, |
||||
addressHash: null, |
||||
newForm: null |
||||
} |
||||
|
||||
export function reducer (state = initialState, action) { |
||||
switch (action.type) { |
||||
case 'PAGE_LOAD': |
||||
case 'ELEMENTS_LOAD': { |
||||
return Object.assign({}, state, _.omit(action, 'type')) |
||||
} |
||||
case 'CHANNEL_DISCONNECTED': { |
||||
if (state.beyondPageOne) return state |
||||
|
||||
return Object.assign({}, state, { |
||||
channelDisconnected: true |
||||
}) |
||||
} |
||||
case 'RECEIVED_VERIFICATION_RESULT': { |
||||
if (action.msg.verificationResult === 'ok') { |
||||
return window.location.replace(window.location.href.split('/contract_verifications')[0] + '/contracts') |
||||
} else { |
||||
return Object.assign({}, state, { |
||||
newForm: action.msg.verificationResult |
||||
}) |
||||
} |
||||
} |
||||
default: |
||||
return state |
||||
} |
||||
} |
||||
|
||||
const elements = { |
||||
'[data-selector="channel-disconnected-message"]': { |
||||
render ($el, state) { |
||||
if (state.channelDisconnected) $el.show() |
||||
} |
||||
}, |
||||
'[data-page="contract-verification"]': { |
||||
render ($el, state) { |
||||
if (state.newForm) { |
||||
$el.replaceWith(state.newForm) |
||||
$('button[data-button-loading="animation"]').click(event => { |
||||
$('#loading').removeClass('d-none') |
||||
}) |
||||
|
||||
$(function () { |
||||
$('.js-btn-add-contract-libraries').on('click', function () { |
||||
$('.js-smart-contract-libraries-wrapper').show() |
||||
$(this).hide() |
||||
}) |
||||
|
||||
$('.js-smart-contract-form-reset').on('click', function () { |
||||
$('.js-contract-library-form-group').removeClass('active') |
||||
$('.js-contract-library-form-group').first().addClass('active') |
||||
$('.js-smart-contract-libraries-wrapper').hide() |
||||
$('.js-btn-add-contract-libraries').show() |
||||
$('.js-add-contract-library-wrapper').show() |
||||
}) |
||||
|
||||
$('.js-btn-add-contract-library').on('click', function () { |
||||
let nextContractLibrary = $('.js-contract-library-form-group.active').next('.js-contract-library-form-group') |
||||
|
||||
if (nextContractLibrary) { |
||||
nextContractLibrary.addClass('active') |
||||
} |
||||
|
||||
if ($('.js-contract-library-form-group.active').length === $('.js-contract-library-form-group').length) { |
||||
$('.js-add-contract-library-wrapper').hide() |
||||
} |
||||
}) |
||||
}) |
||||
|
||||
return $el |
||||
} |
||||
return $el |
||||
} |
||||
} |
||||
} |
||||
|
||||
const $contractVerificationPage = $('[data-page="contract-verification"]') |
||||
|
||||
if ($contractVerificationPage.length) { |
||||
const store = createStore(reducer) |
||||
const addressHash = $('#smart_contract_address_hash').val() |
||||
const { filter, blockNumber } = humps.camelizeKeys(URI(window.location).query(true)) |
||||
|
||||
store.dispatch({ |
||||
type: 'PAGE_LOAD', |
||||
addressHash, |
||||
filter, |
||||
beyondPageOne: !!blockNumber |
||||
}) |
||||
connectElements({ store, elements }) |
||||
|
||||
const addressChannel = subscribeChannel(`addresses:${addressHash}`) |
||||
|
||||
addressChannel.onError(() => store.dispatch({ |
||||
type: 'CHANNEL_DISCONNECTED' |
||||
})) |
||||
addressChannel.on('verification', (msg) => store.dispatch({ |
||||
type: 'RECEIVED_VERIFICATION_RESULT', |
||||
msg: humps.camelizeKeys(msg) |
||||
})) |
||||
|
||||
$('button[data-button-loading="animation"]').click(event => { |
||||
$('#loading').removeClass('d-none') |
||||
}) |
||||
|
||||
$(function () { |
||||
$('.js-btn-add-contract-libraries').on('click', function () { |
||||
$('.js-smart-contract-libraries-wrapper').show() |
||||
$(this).hide() |
||||
}) |
||||
|
||||
$('.js-smart-contract-form-reset').on('click', function () { |
||||
$('.js-contract-library-form-group').removeClass('active') |
||||
$('.js-contract-library-form-group').first().addClass('active') |
||||
$('.js-smart-contract-libraries-wrapper').hide() |
||||
$('.js-btn-add-contract-libraries').show() |
||||
$('.js-add-contract-library-wrapper').show() |
||||
}) |
||||
|
||||
$('.js-btn-add-contract-library').on('click', function () { |
||||
let nextContractLibrary = $('.js-contract-library-form-group.active').next('.js-contract-library-form-group') |
||||
|
||||
if (nextContractLibrary) { |
||||
nextContractLibrary.addClass('active') |
||||
} |
||||
|
||||
if ($('.js-contract-library-form-group.active').length === $('.js-contract-library-form-group').length) { |
||||
$('.js-add-contract-library-wrapper').hide() |
||||
} |
||||
}) |
||||
}) |
||||
} |
@ -1,4 +1,4 @@ |
||||
defmodule Explorer.Chain.BlockCountCache do |
||||
defmodule Explorer.Chain.Cache.BlockCount do |
||||
@moduledoc """ |
||||
Cache for block count. |
||||
""" |
@ -1,4 +1,4 @@ |
||||
defmodule Explorer.Chain.BlockNumberCache do |
||||
defmodule Explorer.Chain.Cache.BlockNumber do |
||||
@moduledoc """ |
||||
Cache for max and min block numbers. |
||||
""" |
@ -1,4 +1,4 @@ |
||||
defmodule Explorer.Chain.BlocksCache do |
||||
defmodule Explorer.Chain.Cache.Blocks do |
||||
@moduledoc """ |
||||
Caches the last imported blocks |
||||
""" |
@ -1,4 +1,4 @@ |
||||
defmodule Explorer.Chain.NetVersionCache do |
||||
defmodule Explorer.Chain.Cache.NetVersion do |
||||
@moduledoc """ |
||||
Caches chain version. |
||||
""" |
@ -1,4 +1,4 @@ |
||||
defmodule Explorer.Chain.TransactionCountCache do |
||||
defmodule Explorer.Chain.Cache.TransactionCount do |
||||
@moduledoc """ |
||||
Cache for estimated transaction count. |
||||
""" |
@ -1,4 +1,4 @@ |
||||
defmodule Explorer.Chain.TransactionsCache do |
||||
defmodule Explorer.Chain.Cache.Transactions do |
||||
@moduledoc """ |
||||
Caches the latest imported transactions |
||||
""" |
@ -0,0 +1,12 @@ |
||||
defmodule Explorer.Chain.SmartContract.ExternalLibrary do |
||||
@moduledoc """ |
||||
The representation of an external library that was used for a smart contract. |
||||
""" |
||||
|
||||
use Ecto.Schema |
||||
|
||||
embedded_schema do |
||||
field(:name) |
||||
field(:address_hash) |
||||
end |
||||
end |
@ -0,0 +1,23 @@ |
||||
defmodule Explorer.SmartContract.PublisherWorker do |
||||
@moduledoc """ |
||||
Background smart contract verification worker. |
||||
""" |
||||
|
||||
use Que.Worker, concurrency: 5 |
||||
|
||||
alias Explorer.Chain.Events.Publisher, as: EventsPublisher |
||||
alias Explorer.SmartContract.Publisher |
||||
|
||||
def perform({address_hash, params, external_libraries, conn}) do |
||||
result = |
||||
case Publisher.publish(address_hash, params, external_libraries) do |
||||
{:ok, _contract} = result -> |
||||
result |
||||
|
||||
{:error, changeset} -> |
||||
{:error, changeset} |
||||
end |
||||
|
||||
EventsPublisher.broadcast([{:contract_verification_result, {address_hash, result, conn}}], :on_demand) |
||||
end |
||||
end |
@ -0,0 +1,13 @@ |
||||
defmodule Explorer.Repo.Migrations.AddExternalLibrariesToSmartContracts do |
||||
use Ecto.Migration |
||||
|
||||
def change do |
||||
alter table(:smart_contracts) do |
||||
remove(:external_libraries) |
||||
end |
||||
|
||||
alter table(:smart_contracts) do |
||||
add(:external_libraries, {:array, :map}, default: []) |
||||
end |
||||
end |
||||
end |
@ -1,59 +0,0 @@ |
||||
defmodule Explorer.Chain.BlockNumberCacheTest do |
||||
use Explorer.DataCase |
||||
|
||||
alias Explorer.Chain.BlockNumberCache |
||||
|
||||
setup do |
||||
Application.put_env(:explorer, Explorer.Chain.BlockNumberCache, enabled: true) |
||||
|
||||
on_exit(fn -> |
||||
Application.put_env(:explorer, Explorer.Chain.BlockNumberCache, enabled: false) |
||||
end) |
||||
end |
||||
|
||||
describe "max_number/1" do |
||||
test "returns max number" do |
||||
insert(:block, number: 5) |
||||
|
||||
BlockNumberCache.setup() |
||||
|
||||
assert BlockNumberCache.max_number() == 5 |
||||
end |
||||
end |
||||
|
||||
describe "min_number/1" do |
||||
test "returns max number" do |
||||
insert(:block, number: 2) |
||||
|
||||
BlockNumberCache.setup() |
||||
|
||||
assert BlockNumberCache.max_number() == 2 |
||||
end |
||||
end |
||||
|
||||
describe "update/1" do |
||||
test "updates max number" do |
||||
insert(:block, number: 2) |
||||
|
||||
BlockNumberCache.setup() |
||||
|
||||
assert BlockNumberCache.max_number() == 2 |
||||
|
||||
assert BlockNumberCache.update(3) |
||||
|
||||
assert BlockNumberCache.max_number() == 3 |
||||
end |
||||
|
||||
test "updates min number" do |
||||
insert(:block, number: 2) |
||||
|
||||
BlockNumberCache.setup() |
||||
|
||||
assert BlockNumberCache.min_number() == 2 |
||||
|
||||
assert BlockNumberCache.update(1) |
||||
|
||||
assert BlockNumberCache.min_number() == 1 |
||||
end |
||||
end |
||||
end |
@ -1,55 +1,55 @@ |
||||
defmodule Explorer.Chain.BlockCountCacheTest do |
||||
defmodule Explorer.Chain.Cache.BlockCountTest do |
||||
use Explorer.DataCase |
||||
|
||||
alias Explorer.Chain.BlockCountCache |
||||
alias Explorer.Chain.Cache.BlockCount |
||||
|
||||
test "returns default transaction count" do |
||||
BlockCountCache.start_link(name: BlockTestCache) |
||||
BlockCount.start_link(name: BlockTestCache) |
||||
|
||||
result = BlockCountCache.count(BlockTestCache) |
||||
result = BlockCount.count(BlockTestCache) |
||||
|
||||
assert is_nil(result) |
||||
end |
||||
|
||||
test "updates cache if initial value is zero" do |
||||
BlockCountCache.start_link(name: BlockTestCache) |
||||
BlockCount.start_link(name: BlockTestCache) |
||||
|
||||
insert(:block, consensus: true) |
||||
insert(:block, consensus: true) |
||||
insert(:block, consensus: false) |
||||
|
||||
_result = BlockCountCache.count(BlockTestCache) |
||||
_result = BlockCount.count(BlockTestCache) |
||||
|
||||
Process.sleep(1000) |
||||
|
||||
updated_value = BlockCountCache.count(BlockTestCache) |
||||
updated_value = BlockCount.count(BlockTestCache) |
||||
|
||||
assert updated_value == 2 |
||||
end |
||||
|
||||
test "does not update cache if cache period did not pass" do |
||||
BlockCountCache.start_link(name: BlockTestCache) |
||||
BlockCount.start_link(name: BlockTestCache) |
||||
|
||||
insert(:block, consensus: true) |
||||
insert(:block, consensus: true) |
||||
insert(:block, consensus: false) |
||||
|
||||
_result = BlockCountCache.count(BlockTestCache) |
||||
_result = BlockCount.count(BlockTestCache) |
||||
|
||||
Process.sleep(1000) |
||||
|
||||
updated_value = BlockCountCache.count(BlockTestCache) |
||||
updated_value = BlockCount.count(BlockTestCache) |
||||
|
||||
assert updated_value == 2 |
||||
|
||||
insert(:block, consensus: true) |
||||
insert(:block, consensus: true) |
||||
|
||||
_updated_value = BlockCountCache.count(BlockTestCache) |
||||
_updated_value = BlockCount.count(BlockTestCache) |
||||
|
||||
Process.sleep(1000) |
||||
|
||||
updated_value = BlockCountCache.count(BlockTestCache) |
||||
updated_value = BlockCount.count(BlockTestCache) |
||||
|
||||
assert updated_value == 2 |
||||
end |
@ -0,0 +1,59 @@ |
||||
defmodule Explorer.Chain.Cache.BlockNumberTest do |
||||
use Explorer.DataCase |
||||
|
||||
alias Explorer.Chain.Cache.BlockNumber |
||||
|
||||
setup do |
||||
Application.put_env(:explorer, Explorer.Chain.Cache.BlockNumber, enabled: true) |
||||
|
||||
on_exit(fn -> |
||||
Application.put_env(:explorer, Explorer.Chain.Cache.BlockNumber, enabled: false) |
||||
end) |
||||
end |
||||
|
||||
describe "max_number/1" do |
||||
test "returns max number" do |
||||
insert(:block, number: 5) |
||||
|
||||
BlockNumber.setup() |
||||
|
||||
assert BlockNumber.max_number() == 5 |
||||
end |
||||
end |
||||
|
||||
describe "min_number/1" do |
||||
test "returns max number" do |
||||
insert(:block, number: 2) |
||||
|
||||
BlockNumber.setup() |
||||
|
||||
assert BlockNumber.max_number() == 2 |
||||
end |
||||
end |
||||
|
||||
describe "update/1" do |
||||
test "updates max number" do |
||||
insert(:block, number: 2) |
||||
|
||||
BlockNumber.setup() |
||||
|
||||
assert BlockNumber.max_number() == 2 |
||||
|
||||
assert BlockNumber.update(3) |
||||
|
||||
assert BlockNumber.max_number() == 3 |
||||
end |
||||
|
||||
test "updates min number" do |
||||
insert(:block, number: 2) |
||||
|
||||
BlockNumber.setup() |
||||
|
||||
assert BlockNumber.min_number() == 2 |
||||
|
||||
assert BlockNumber.update(1) |
||||
|
||||
assert BlockNumber.min_number() == 1 |
||||
end |
||||
end |
||||
end |
@ -0,0 +1,54 @@ |
||||
defmodule Explorer.Chain.Cache.TransactionCountTest do |
||||
use Explorer.DataCase |
||||
|
||||
alias Explorer.Chain.Cache.TransactionCount |
||||
|
||||
test "returns default transaction count" do |
||||
TransactionCount.start_link([[], [name: TestCache]]) |
||||
|
||||
result = TransactionCount.value(TestCache) |
||||
|
||||
assert is_nil(result) |
||||
end |
||||
|
||||
test "updates cache if initial value is zero" do |
||||
TransactionCount.start_link([[], [name: TestCache]]) |
||||
|
||||
insert(:transaction) |
||||
insert(:transaction) |
||||
|
||||
_result = TransactionCount.value(TestCache) |
||||
|
||||
Process.sleep(1000) |
||||
|
||||
updated_value = TransactionCount.value(TestCache) |
||||
|
||||
assert updated_value == 2 |
||||
end |
||||
|
||||
test "does not update cache if cache period did not pass" do |
||||
TransactionCount.start_link([[], [name: TestCache]]) |
||||
|
||||
insert(:transaction) |
||||
insert(:transaction) |
||||
|
||||
_result = TransactionCount.value(TestCache) |
||||
|
||||
Process.sleep(1000) |
||||
|
||||
updated_value = TransactionCount.value(TestCache) |
||||
|
||||
assert updated_value == 2 |
||||
|
||||
insert(:transaction) |
||||
insert(:transaction) |
||||
|
||||
_updated_value = TransactionCount.value(TestCache) |
||||
|
||||
Process.sleep(1000) |
||||
|
||||
updated_value = TransactionCount.value(TestCache) |
||||
|
||||
assert updated_value == 2 |
||||
end |
||||
end |
@ -1,54 +0,0 @@ |
||||
defmodule Explorer.Chain.TransactionCountCacheTest do |
||||
use Explorer.DataCase |
||||
|
||||
alias Explorer.Chain.TransactionCountCache |
||||
|
||||
test "returns default transaction count" do |
||||
TransactionCountCache.start_link([[], [name: TestCache]]) |
||||
|
||||
result = TransactionCountCache.value(TestCache) |
||||
|
||||
assert is_nil(result) |
||||
end |
||||
|
||||
test "updates cache if initial value is zero" do |
||||
TransactionCountCache.start_link([[], [name: TestCache]]) |
||||
|
||||
insert(:transaction) |
||||
insert(:transaction) |
||||
|
||||
_result = TransactionCountCache.value(TestCache) |
||||
|
||||
Process.sleep(1000) |
||||
|
||||
updated_value = TransactionCountCache.value(TestCache) |
||||
|
||||
assert updated_value == 2 |
||||
end |
||||
|
||||
test "does not update cache if cache period did not pass" do |
||||
TransactionCountCache.start_link([[], [name: TestCache]]) |
||||
|
||||
insert(:transaction) |
||||
insert(:transaction) |
||||
|
||||
_result = TransactionCountCache.value(TestCache) |
||||
|
||||
Process.sleep(1000) |
||||
|
||||
updated_value = TransactionCountCache.value(TestCache) |
||||
|
||||
assert updated_value == 2 |
||||
|
||||
insert(:transaction) |
||||
insert(:transaction) |
||||
|
||||
_updated_value = TransactionCountCache.value(TestCache) |
||||
|
||||
Process.sleep(1000) |
||||
|
||||
updated_value = TransactionCountCache.value(TestCache) |
||||
|
||||
assert updated_value == 2 |
||||
end |
||||
end |
Loading…
Reference in new issue