Skip to content

Commit

Permalink
Merge remote-tracking branch 'dev' into chore/change-order-of-network…
Browse files Browse the repository at this point in the history
…s-1222
  • Loading branch information
Torresmorah committed Jul 27, 2023
2 parents 6a174b6 + 8d58d86 commit f441ad0
Show file tree
Hide file tree
Showing 38 changed files with 590 additions and 350 deletions.
10 changes: 5 additions & 5 deletions .github/workflows/deploy-libre-testnet.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ jobs:
REACT_APP_TITLE: 'Libre Testnet Network Dashboard'
REACT_APP_VERSION: ${{github.ref}}
REACT_APP_DEFAULT_PRODUCER_LOGO: 'https://antelope.tools/images/libre.png'
REACT_APP_FOOTER_LINKS: '[{ "text": "Libre Website", "src": "https://libre.org/" },{ "text": "Libre Block Explorer", "src": "https://libre-testnet-explorer.edenia.cloud/" },{"text": "Documentation","src": "https://libre-chain.gitbook.io/"},{"text": "Libre Network Monitor","src": "https://libre-testnet.antelope.tools"}]'
REACT_APP_FOOTER_LINKS: '[{ "text": "Libre Website", "src": "https://libre.org/" },{ "text": "Libre Block Explorer", "src": "https://testnet.libre.org/v2/explore" },{"text": "Documentation","src": "https://libre-chain.gitbook.io/"},{"text": "Libre Network Monitor","src": "https://libre-testnet.antelope.tools"}]'
REACT_APP_EOS_RATE_LINK: ''
REACT_APP_USE_REWARDS: 'true'
REACT_APP_USE_VOTES: 'true'
Expand All @@ -56,8 +56,8 @@ jobs:
REACT_APP_SYNC_TOLERANCE_INTERVAL: 180000
REACT_APP_TOKEN_SYMBOL: 'LIBRE'
REACT_APP_NETWORK_URL: '[{"label":"EOS","value":"https://eos.antelope.tools","mainnet":true,"pair":"eos","icon":"eos","order":5},{"label":"Proton","value":"https://proton.antelope.tools","mainnet":true,"pair":"proton","icon":"proton","order":3},{"label":"WAX","value":"https://wax.antelope.tools","mainnet":true,"pair":"wax","icon":"wax","order":4},{"label":"Telos","value":"https://telos.antelope.tools","mainnet":true,"pair":"telos","icon":"telos","order":1},{"label":"Libre","value":"https://libre.antelope.tools","mainnet":true,"pair":"libre","icon":"libre","order":2},{"label":"LACChain EOSIO","value":"https://lacchain.antelope.tools","mainnet":true,"pair":null,"icon":"lacchain","order":6},{"label":"Jungle4 Testnet","value":"https://jungle.antelope.tools","mainnet":false,"pair":"eos","icon":"jungle","order":5},{"label":"Proton Testnet","value":"https://proton-testnet.antelope.tools","mainnet":false,"pair":"proton","icon":"proton","order":3},{"label":"WAX Testnet","value":"https://wax-testnet.antelope.tools","mainnet":false,"pair":"wax","icon":"wax","order":4},{"label":"Telos Testnet","value":"https://telos-testnet.antelope.tools","mainnet":false,"pair":"telos","icon":"telos","order":1},{"label":"Libre Testnet","value":"https://libre-testnet.antelope.tools","mainnet":false,"pair":"libre","icon":"libre","order":2},{"label":"Ultra Testnet","value":"https://ultra-testnet.antelope.tools","mainnet":false,"pair":"ultra","icon":"ultra","order":6}]'
REACT_APP_DISABLED_MENU_ITEMS: '["/missed-blocks"]'
REACT_APP_BLOCK_EXPLORER_URL: 'https://libre-testnet-explorer.edenia.cloud/transaction/(transaction)'
REACT_APP_DISABLED_MENU_ITEMS: '[]'
REACT_APP_BLOCK_EXPLORER_URL: 'https://testnet.libre.org/v2/explore/transaction/(transaction)'
REACT_APP_STATE_HISTORY_ENABLED: 'true'
REACT_APP_GOOGLE_ANALITIC_PAGE_ID: 'G-E6Y0EC9FT8'
REACT_APP_PUBLIC_RE_CAPTCHA_KEY: ${{ secrets.REACT_APP_PUBLIC_RE_CAPTCHA_KEY }}
Expand All @@ -83,9 +83,9 @@ jobs:
HAPI_EOS_API_NETWORK_NAME: libre
HAPI_EOS_API_ENDPOINTS: '["https://libre-testnet.edenia.cloud","https://api.testnet.libre.cryptobloks.io","https://libre-testnet.eosphere.io"]'
HAPI_EOS_STATE_HISTORY_PLUGIN_ENDPOINT: 'ws://api-node.libre-testnet:8080'
HAPI_EOS_MISSED_BLOCKS_ENABLED: 'false'
HAPI_EOS_MISSED_BLOCKS_ENABLED: 'true'
HAPI_EOS_BLOCK_HISTORY_DAYS: 90
HAPI_EOS_MAX_CPU_BLOCK: 100000
HAPI_EOS_MAX_CPU_BLOCK: 250000
HAPI_EOS_MAX_NET_BLOCK: 1048576
HAPI_EOS_API_CHAIN_ID: b64646740308df2ee06c6b72f34c0f7fa066d940e831f752db2006fcc2b78dee
HAPI_EOS_BASE_ACCOUNT: ${{ secrets.HAPI_EOS_BASE_ACCOUNT }}
Expand Down
14 changes: 10 additions & 4 deletions .github/workflows/deploy-libre.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,8 @@ jobs:
REACT_APP_DEFAULT_PRODUCER_LOGO: 'https://antelope.tools/images/libre.png'
REACT_APP_FOOTER_LINKS: '[{ "text": "Libre Website", "src": "https://libre.org/" },{ "text": "Libre Block Explorer", "src": "https://www.libreblocks.io/" },{"text": "Documentation","src": "https://libre-chain.gitbook.io/"},{"text": "Libre Network Monitor","src": "https://libre.antelope.tools"}]'
REACT_APP_EOS_RATE_LINK: ''
REACT_APP_USE_REWARDS: 'false'
REACT_APP_USE_VOTES: 'false'
REACT_APP_USE_REWARDS: 'true'
REACT_APP_USE_VOTES: 'true'
REACT_APP_HASURA_URL: 'https://graphql-libre.antelope.tools/v1/graphql'
REACT_APP_EOS_API_NETWORK_NAME: 'libre'
REACT_APP_EOS_API_NETWORK_LABEL: 'Libre Mainnet'
Expand All @@ -56,9 +56,9 @@ jobs:
REACT_APP_SYNC_TOLERANCE_INTERVAL: 180000
REACT_APP_TOKEN_SYMBOL: 'LIBRE'
REACT_APP_NETWORK_URL: '[{"label":"EOS","value":"https://eos.antelope.tools","mainnet":true,"pair":"eos","icon":"eos","order":5},{"label":"Proton","value":"https://proton.antelope.tools","mainnet":true,"pair":"proton","icon":"proton","order":3},{"label":"WAX","value":"https://wax.antelope.tools","mainnet":true,"pair":"wax","icon":"wax","order":4},{"label":"Telos","value":"https://telos.antelope.tools","mainnet":true,"pair":"telos","icon":"telos","order":1},{"label":"Libre","value":"https://libre.antelope.tools","mainnet":true,"pair":"libre","icon":"libre","order":2},{"label":"LACChain EOSIO","value":"https://lacchain.antelope.tools","mainnet":true,"pair":null,"icon":"lacchain","order":6},{"label":"Jungle4 Testnet","value":"https://jungle.antelope.tools","mainnet":false,"pair":"eos","icon":"jungle","order":5},{"label":"Proton Testnet","value":"https://proton-testnet.antelope.tools","mainnet":false,"pair":"proton","icon":"proton","order":3},{"label":"WAX Testnet","value":"https://wax-testnet.antelope.tools","mainnet":false,"pair":"wax","icon":"wax","order":4},{"label":"Telos Testnet","value":"https://telos-testnet.antelope.tools","mainnet":false,"pair":"telos","icon":"telos","order":1},{"label":"Libre Testnet","value":"https://libre-testnet.antelope.tools","mainnet":false,"pair":"libre","icon":"libre","order":2},{"label":"Ultra Testnet","value":"https://ultra-testnet.antelope.tools","mainnet":false,"pair":"ultra","icon":"ultra","order":6}]'
REACT_APP_DISABLED_MENU_ITEMS: '["/missed-blocks","/block-distribution","/stress-test"]'
REACT_APP_DISABLED_MENU_ITEMS: '["/missed-blocks","/stress-test"]'
REACT_APP_BLOCK_EXPLORER_URL: 'https://www.libreblocks.io/tx/(transaction)'
REACT_APP_STATE_HISTORY_ENABLED=: 'false'
REACT_APP_STATE_HISTORY_ENABLED: 'true'
REACT_APP_GOOGLE_ANALITIC_PAGE_ID: 'G-E6Y0EC9FT8'
REACT_APP_PUBLIC_RE_CAPTCHA_KEY: ${{ secrets.REACT_APP_PUBLIC_RE_CAPTCHA_KEY }}

Expand All @@ -82,6 +82,11 @@ jobs:
# hapi
HAPI_EOS_API_NETWORK_NAME: libre
HAPI_EOS_API_ENDPOINTS: '["https://libre.edenia.cloud","https://libre.eosusa.io","https://api.libre.cryptolions.io"]'
HAPI_EOS_STATE_HISTORY_PLUGIN_ENDPOINT: 'ws://api-node.libre:8080'
HAPI_EOS_MISSED_BLOCKS_ENABLED: 'false'
HAPI_EOS_BLOCK_HISTORY_DAYS: 90
HAPI_EOS_MAX_CPU_BLOCK: 100000
HAPI_EOS_MAX_NET_BLOCK: 1048576
HAPI_EOS_API_CHAIN_ID: 38b1d7815474d0c60683ecbea321d723e83f5da6ae5f1c1f9fecc69d9ba96465
HAPI_EOS_BASE_ACCOUNT: ${{ secrets.HAPI_EOS_BASE_ACCOUNT }}
HAPI_EOS_BASE_ACCOUNT_PASSWORD: ${{ secrets.HAPI_EOS_BASE_ACCOUNT_PASSWORD }}
Expand All @@ -104,6 +109,7 @@ jobs:
HAPI_SYNC_PRODUCER_CPU_INTERVAL: '6'
HAPI_SYNC_PRODUCER_INFO_INTERVAL: '1'
HAPI_SYNC_SCHEDULE_HISTORY_INTERVAL: 86400
HAPI_SYNC_STATS_INTERVAL: 3600
HAPI_EOS_EXCHANGE_RATE_API: 'https://dashboard-api.libre.org/exchange-rates'
HAPI_COINGECKO_API_TOKEN_ID: LIBRE
HAPI_REWARDS_TOKEN: LIBRE
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/deploy-wax-testnet.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ jobs:
REACT_APP_DEFAULT_PRODUCER_LOGO: 'https://antelope.tools/images/wax.jpg'
REACT_APP_FOOTER_LINKS: '[{ "text": "WAX Website", "src": "https://www.wax.io/" },{ "text": "WAX Block Explorer", "src": "https://wax-test.bloks.io/" },{"text": "Developer Guidelines","src": "https://developer.wax.io/"},{"text": "WAX Network Monitor","src": "https://antelope.tools"}]'
REACT_APP_EOS_RATE_LINK: ''
REACT_APP_USE_REWARDS: 'false'
REACT_APP_USE_REWARDS: 'true'
REACT_APP_USE_VOTES: 'true'
REACT_APP_HASURA_URL: 'https://graphql-wax-testnet.antelope.tools/v1/graphql'
REACT_APP_EOS_API_NETWORK_NAME: 'wax-testnet'
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/deploy-wax.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ jobs:
REACT_APP_DEFAULT_PRODUCER_LOGO: 'https://antelope.tools/images/wax.jpg'
REACT_APP_FOOTER_LINKS: '[{ "text": "WAX Website", "src": "https://www.wax.io/" },{ "text": "WAX Block Explorer", "src": "https://wax.bloks.io" },{"text": "Developer Guidelines","src": "https://developer.wax.io/"},{"text": "WAX Network Monitor","src": "https://antelope.tools"}]'
REACT_APP_EOS_RATE_LINK: ''
REACT_APP_USE_REWARDS: 'false'
REACT_APP_USE_REWARDS: 'true'
REACT_APP_USE_VOTES: 'true'
REACT_APP_HASURA_URL: 'https://graphql-wax.antelope.tools/v1/graphql'
REACT_APP_EOS_API_NETWORK_NAME: 'wax'
Expand Down
35 changes: 23 additions & 12 deletions hapi/src/routes/create-faucet-account.route.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@ const {
eosUtil,
axiosUtil,
googleRecaptchaEnterpriseUtil,
getCreateAccountDataUtil
getCreateAccountDataUtil,
sleepFor
} = require('../utils')

module.exports = {
Expand All @@ -21,7 +22,7 @@ module.exports = {
throw Boom.badRequest('Are you a human?')
}

await eosUtil.transact(
const transaction = await eosUtil.transact(
[
{
authorization: [
Expand All @@ -43,25 +44,35 @@ module.exports = {
eosConfig.faucet.password
)

await sleepFor(1)

const {
data: { account_name: account, permissions }
data: { accounts }
} = await axiosUtil.instance.post(
`${eosConfig.apiEndpoint}/v1/chain/get_account`,
`${eosConfig.apiEndpoint}/v1/chain/get_accounts_by_authorizers`,
{
account_name: input.name
keys: [input.public_key]
}
)

const keys = permissions[0]?.required_auth?.keys || []
const key = keys[0]?.key

if (account === input.name && key === input.public_key) {
return { account }
if (!input.name) {
input.name = transaction?.processed?.action_traces[0]?.act?.data?.name
}

return Boom.badData('Wrong key format')
const newAccount = accounts.find(
(account) => account.account_name === input.name || !input.name
)

if (!newAccount) throw new Error('Account creation failed')

return { account: newAccount.account_name }
} catch (err) {
throw Boom.badRequest(err.message)
const errorDetail =
err?.response?.data?.error?.details[0]?.message?.substring(0, 11)

return errorDetail === 'unknown key'
? Boom.badRequest('Account creation failed')
: Boom.badRequest(err.message)
}
},
options: {
Expand Down
93 changes: 64 additions & 29 deletions hapi/src/services/missed-blocks.service.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,14 @@ const {
sequelizeUtil,
hasuraUtil,
sleepFor,
getGranularityFromRange
getGranularityFromRange,
eosUtil
} = require('../utils')

const setScheduleHistory = items => {
const mutation = `
mutation ($items: [schedule_history_insert_input!]!) {
insert_schedule_history(objects: $items, on_conflict: {constraint: schedule_history_version_key, update_columns: [first_block_at, last_block_at, first_block, last_block, producers, current, round_interval]}) {
insert_schedule_history(objects: $items, on_conflict: {constraint: schedule_history_version_key, update_columns: [first_block_at, first_block, producers, round_interval]}) {
affected_rows
}
}
Expand All @@ -36,9 +37,7 @@ const setScheduleByDemux = async (state, payload) => {
SELECT
schedule_version as version,
min(timestamp) as first_block_at,
max(timestamp) as last_block_at,
min(block_num) as first_block,
max(block_num) as last_block
FROM
block_history
WHERE schedule_version = ${currentVersion + 1}
Expand All @@ -56,16 +55,50 @@ const setScheduleByDemux = async (state, payload) => {
await setScheduleHistory(schedules)
}

const getLastRoundInfo = async () => {
const stats = await statsService.getStats()
const getScheduleFirstBlock = async version => {
const [rows] = await sequelizeUtil.query(`
SELECT
block_history.block_num, timestamp, producer
FROM
block_history
INNER JOIN(
SELECT
min(block_num) as block_num
FROM
block_history
WHERE
schedule_version = ${version}
) as first_block
ON block_history.block_num = first_block.block_num`)

// if there is no stats we should try later
if (!stats) {
return null
return rows[0]
}

const syncCurrentSchedule = async () => {
const current = await getCurrentVersion()
const { active: schedule } = await eosUtil.getProducerSchedule()
const producers = schedule.producers.map(producer => producer.producer_name)

if(schedule.version > current) {
const firstBlock = await getScheduleFirstBlock(schedule.version)

if (!firstBlock) return

await setScheduleHistory({
version: schedule.version,
first_block: firstBlock.block_num,
first_block_at: firstBlock.timestamp,
producers,
round_interval: producers.length * 6
})
}
}

const getLastRoundInfo = async () => {
const stats = await statsService.getStats()

// if there is no last block we should try later
if (!stats.last_block_at) {
if (!stats?.last_block_at) {
return null
}

Expand All @@ -76,10 +109,10 @@ const getLastRoundInfo = async () => {
}
}

// if there is no previous round we should start from round 0 and version 0
// if there is no previous round we should start from the first available schedule
const query = `
query {
schedule_history (where: {version: {_eq: 0}}) {
schedule_history (limit: 1, order_by: {version: asc}) {
schedule: version,
first_block_at,
interval: round_interval,
Expand Down Expand Up @@ -126,13 +159,14 @@ const getBlocksInRange = async (start, end) => {
}))
}

const getScheduleByVersion = async version => {
const getNextScheduleByVersion = async version => {
const query = `
query {
schedule_history(where: {version: {_eq: ${version}}}, limit: 1) {
schedule_history(where: {version: {_gte: ${version}}}, order_by: {version: asc}, limit: 1) {
version
producers
round_interval
first_block_at
}
}
`
Expand Down Expand Up @@ -172,35 +206,36 @@ const syncMissedBlocks = async () => {
// if the diference between the
// last block time and the end time
// is less than the round interval
// then wait until the round end
// then wait for block history synchronization
if (
moment(lastRound.last_block_at).diff(end, 'seconds') < lastRound.interval
) {
await sleepFor(60)
await sleepFor(10)
syncMissedBlocks()

return
}

const blocks = await getBlocksInRange(start, end)

// if the first block comes from different schedule_version
// then it's the end of the version in use
if (blocks.length > 0 && blocks[0].schedule_version !== lastRound.schedule) {
const newSchedule = await getScheduleByVersion(lastRound.schedule + 1)
if (!blocks.length || blocks.length > 0 && blocks[0].schedule_version !== lastRound.schedule) {
const newSchedule = await getNextScheduleByVersion(
lastRound.schedule + 1
)

// schedule version no yet in the history
// schedule version no yet in the DB
if (!newSchedule) {
await sleepFor(60)
syncMissedBlocks()

return
}

lastRound.schedule += 1
lastRound.schedule = newSchedule.version
lastRound.number = 0
lastRound.interval = newSchedule.round_interval
lastRound.producers = newSchedule.producers
lastRound.completed_at = newSchedule.first_block_at

await statsService.udpateStats({ last_round: lastRound })
syncMissedBlocks()
Expand All @@ -210,22 +245,21 @@ const syncMissedBlocks = async () => {

lastRound.number += 1
lastRound.completed_at = end.toISOString()
const roundHistory = lastRound.producers.map(producer => {
const producerBlocks = blocks.filter(block => block.producer === producer)
const roundHistory = lastRound.producers.map((producer) => {
const producerBlocks = blocks.filter((block) => block.producer === producer)

return {
schedule: lastRound.schedule,
number: lastRound.number,
account: producer,
started_at: start.toISOString(),
completed_at: end.toISOString(),
missed_blocks: 12 - producerBlocks.length,
produced_blocks: producerBlocks.length
missed_blocks: 12 - producerBlocks.length
}
})

await addRoundHistory(roundHistory)
await statsService.udpateStats({ last_round: lastRound })

syncMissedBlocks()
}

Expand All @@ -244,8 +278,8 @@ const getMissedBlocks = async (range = '3 Hours') => {
interval.value as datetime,
round_history.account,
sum(round_history.missed_blocks) as missed,
sum(round_history.produced_blocks) as produced,
sum(round_history.missed_blocks)+sum(round_history.produced_blocks) as scheduled
count(1) * 12 - sum(round_history.missed_blocks) as produced,
count(1) * 12 as scheduled
FROM
interval
INNER JOIN
Expand All @@ -261,6 +295,7 @@ const getMissedBlocks = async (range = '3 Hours') => {

module.exports = {
syncMissedBlocks,
syncCurrentSchedule,
getMissedBlocks,
setScheduleByDemux
}
5 changes: 4 additions & 1 deletion hapi/src/services/state-history-plugin.service.js
Original file line number Diff line number Diff line change
Expand Up @@ -133,10 +133,10 @@ const handleBlocksResult = async (data) => {

if (blocksData.length === 50) {
await saveBlocks(blocksData)
await statsService.udpateStats({ last_block_at: block.timestamp })
blocksData = []
}

await statsService.udpateStats({ last_block_at: block.timestamp })
send(
serialize('request', ['get_blocks_ack_request_v0', { num_messages: 1 }])
)
Expand All @@ -156,6 +156,9 @@ const cleanOldBlocks = async () => {
delete_block_history (where: {timestamp: {_lt: $date}}) {
affected_rows
}
delete_round_history (where: {completed_at: {_lt: $date}}) {
affected_rows
}
}
`

Expand Down
Loading

0 comments on commit f441ad0

Please sign in to comment.