mirror of
https://github.com/trezor/blockbook.git
synced 2026-02-20 00:51:39 +01:00
Add Base Support (#1150)
* add base support * backend config * add base archive blockchain factory * add dbProtoAddrContracts flag and default to legacy encoding. fix tests * default cache behavior for dbMaxAddrContracts default value * update to defer func to ensure addressContracts is reset and handle possible error * base config default to use dbProtoAddrContracts * add network config * update op-geth and op-node versions * remove coingecko url * update coingecko platform identifier * token type -> token standard * reduce allocations as pack/unpack addr contracts is primary bottleneck for l2 chains * archive snapshot no longer supported, use fullnode snapshot as best effort * remove proto encoded addr contracts as bench marks indicate there is no performance gain as initially suspected * revert address contract cache changes
This commit is contained in:
@@ -622,25 +622,25 @@ func (w *Worker) GetTransactionFromMempoolTx(mempoolTx *bchain.MempoolTx) (*Tx,
|
||||
return r, nil
|
||||
}
|
||||
|
||||
func (w *Worker) GetContractInfo(contract string, typeFromContext bchain.TokenStandardName) (*bchain.ContractInfo, bool, error) {
|
||||
func (w *Worker) GetContractInfo(contract string, standardFromContext bchain.TokenStandardName) (*bchain.ContractInfo, bool, error) {
|
||||
cd, err := w.chainParser.GetAddrDescFromAddress(contract)
|
||||
if err != nil {
|
||||
return nil, false, err
|
||||
}
|
||||
return w.getContractDescriptorInfo(cd, typeFromContext)
|
||||
return w.getContractDescriptorInfo(cd, standardFromContext)
|
||||
}
|
||||
|
||||
func (w *Worker) getContractDescriptorInfo(cd bchain.AddressDescriptor, typeFromContext bchain.TokenStandardName) (*bchain.ContractInfo, bool, error) {
|
||||
func (w *Worker) getContractDescriptorInfo(cd bchain.AddressDescriptor, standardFromContext bchain.TokenStandardName) (*bchain.ContractInfo, bool, error) {
|
||||
var err error
|
||||
validContract := true
|
||||
contractInfo, err := w.db.GetContractInfo(cd, typeFromContext)
|
||||
contractInfo, err := w.db.GetContractInfo(cd, standardFromContext)
|
||||
if err != nil {
|
||||
return nil, false, err
|
||||
}
|
||||
if contractInfo == nil {
|
||||
// log warning only if the contract should have been known from processing of the internal data
|
||||
if eth.ProcessInternalTransactions {
|
||||
glog.Warningf("Contract %v %v not found in DB", cd, typeFromContext)
|
||||
glog.Warningf("Contract %v %v not found in DB", cd, standardFromContext)
|
||||
}
|
||||
contractInfo, err = w.chain.GetContractInfo(cd)
|
||||
if err != nil {
|
||||
@@ -655,9 +655,9 @@ func (w *Worker) getContractDescriptorInfo(cd bchain.AddressDescriptor, typeFrom
|
||||
|
||||
validContract = false
|
||||
} else {
|
||||
if typeFromContext != bchain.UnknownTokenStandard && contractInfo.Standard == bchain.UnknownTokenStandard {
|
||||
contractInfo.Standard = typeFromContext
|
||||
contractInfo.Type = typeFromContext
|
||||
if standardFromContext != bchain.UnknownTokenStandard && contractInfo.Standard == bchain.UnknownTokenStandard {
|
||||
contractInfo.Standard = standardFromContext
|
||||
contractInfo.Type = standardFromContext
|
||||
}
|
||||
if err = w.db.StoreContractInfo(contractInfo); err != nil {
|
||||
glog.Errorf("StoreContractInfo error %v, contract %v", err, cd)
|
||||
@@ -683,9 +683,9 @@ func (w *Worker) getContractDescriptorInfo(cd bchain.AddressDescriptor, typeFrom
|
||||
contractInfo.Decimals = blockchainContractInfo.Decimals
|
||||
}
|
||||
if contractInfo.Standard == bchain.UnhandledTokenStandard {
|
||||
glog.Infof("Contract %v %v [%s] handled", cd, typeFromContext, contractInfo.Name)
|
||||
contractInfo.Standard = typeFromContext
|
||||
contractInfo.Type = typeFromContext
|
||||
glog.Infof("Contract %v %v [%s] handled", cd, standardFromContext, contractInfo.Name)
|
||||
contractInfo.Standard = standardFromContext
|
||||
contractInfo.Type = standardFromContext
|
||||
}
|
||||
if err = w.db.StoreContractInfo(contractInfo); err != nil {
|
||||
glog.Errorf("StoreContractInfo error %v, contract %v", err, cd)
|
||||
|
||||
73
bchain/coins/base/baserpc.go
Normal file
73
bchain/coins/base/baserpc.go
Normal file
@@ -0,0 +1,73 @@
|
||||
package base
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
|
||||
"github.com/golang/glog"
|
||||
"github.com/juju/errors"
|
||||
"github.com/trezor/blockbook/bchain"
|
||||
"github.com/trezor/blockbook/bchain/coins/eth"
|
||||
)
|
||||
|
||||
const (
|
||||
// MainNet is production network
|
||||
MainNet eth.Network = 8453
|
||||
)
|
||||
|
||||
// BaseRPC is an interface to JSON-RPC base service.
|
||||
type BaseRPC struct {
|
||||
*eth.EthereumRPC
|
||||
}
|
||||
|
||||
// NewBaseRPC returns new BaseRPC instance.
|
||||
func NewBaseRPC(config json.RawMessage, pushHandler func(bchain.NotificationType)) (bchain.BlockChain, error) {
|
||||
c, err := eth.NewEthereumRPC(config, pushHandler)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
s := &BaseRPC{
|
||||
EthereumRPC: c.(*eth.EthereumRPC),
|
||||
}
|
||||
|
||||
return s, nil
|
||||
}
|
||||
|
||||
// Initialize base rpc interface
|
||||
func (b *BaseRPC) Initialize() error {
|
||||
b.OpenRPC = eth.OpenRPC
|
||||
|
||||
rc, ec, err := b.OpenRPC(b.ChainConfig.RPCURL)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// set chain specific
|
||||
b.Client = ec
|
||||
b.RPC = rc
|
||||
b.MainNetChainID = MainNet
|
||||
b.NewBlock = eth.NewEthereumNewBlock()
|
||||
b.NewTx = eth.NewEthereumNewTx()
|
||||
|
||||
ctx, cancel := context.WithTimeout(context.Background(), b.Timeout)
|
||||
defer cancel()
|
||||
|
||||
id, err := b.Client.NetworkID(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// parameters for getInfo request
|
||||
switch eth.Network(id.Uint64()) {
|
||||
case MainNet:
|
||||
b.Testnet = false
|
||||
b.Network = "livenet"
|
||||
default:
|
||||
return errors.Errorf("Unknown network id %v", id)
|
||||
}
|
||||
|
||||
glog.Info("rpc: block chain ", b.Network)
|
||||
|
||||
return nil
|
||||
}
|
||||
@@ -13,6 +13,7 @@ import (
|
||||
"github.com/trezor/blockbook/bchain"
|
||||
"github.com/trezor/blockbook/bchain/coins/arbitrum"
|
||||
"github.com/trezor/blockbook/bchain/coins/avalanche"
|
||||
"github.com/trezor/blockbook/bchain/coins/base"
|
||||
"github.com/trezor/blockbook/bchain/coins/bch"
|
||||
"github.com/trezor/blockbook/bchain/coins/bellcoin"
|
||||
"github.com/trezor/blockbook/bchain/coins/bitcore"
|
||||
@@ -147,6 +148,8 @@ func init() {
|
||||
BlockChainFactories["Arbitrum Archive"] = arbitrum.NewArbitrumRPC
|
||||
BlockChainFactories["Arbitrum Nova"] = arbitrum.NewArbitrumRPC
|
||||
BlockChainFactories["Arbitrum Nova Archive"] = arbitrum.NewArbitrumRPC
|
||||
BlockChainFactories["Base"] = base.NewBaseRPC
|
||||
BlockChainFactories["Base Archive"] = base.NewBaseRPC
|
||||
}
|
||||
|
||||
// NewBlockChain creates bchain.BlockChain and bchain.Mempool for the coin passed by the parameter coin
|
||||
|
||||
@@ -14,7 +14,7 @@ const (
|
||||
// MainNet is production network
|
||||
MainNet eth.Network = 56
|
||||
|
||||
// bsc token type names
|
||||
// bsc token standard names
|
||||
BEP20TokenStandard bchain.TokenStandardName = "BEP20"
|
||||
BEP721TokenStandard bchain.TokenStandardName = "BEP721"
|
||||
BEP1155TokenStandard bchain.TokenStandardName = "BEP1155"
|
||||
@@ -32,7 +32,7 @@ func NewBNBSmartChainRPC(config json.RawMessage, pushHandler func(bchain.Notific
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// overwrite EthereumTokenTypeMap with bsc specific token type names
|
||||
// overwrite EthereumTokenStandardMap with bsc specific token standard names
|
||||
bchain.EthereumTokenStandardMap = []bchain.TokenStandardName{BEP20TokenStandard, BEP721TokenStandard, BEP1155TokenStandard}
|
||||
|
||||
s := &BNBSmartChainRPC{
|
||||
|
||||
@@ -116,9 +116,6 @@ type MempoolTx struct {
|
||||
CoinSpecificData interface{} `json:"-"`
|
||||
}
|
||||
|
||||
// // Deprecated: Use TokenStandard instead.
|
||||
// type TokenType int
|
||||
|
||||
// TokenStandard - standard of token
|
||||
type TokenStandard int
|
||||
|
||||
@@ -129,10 +126,10 @@ const (
|
||||
MultiToken // ERC1155/BEP1155
|
||||
)
|
||||
|
||||
// TokenStandardName specifies type of token
|
||||
// TokenStandardName specifies standard of token
|
||||
type TokenStandardName string
|
||||
|
||||
// Token types
|
||||
// Token standards
|
||||
const (
|
||||
UnknownTokenStandard TokenStandardName = ""
|
||||
UnhandledTokenStandard TokenStandardName = "-"
|
||||
|
||||
@@ -70,15 +70,15 @@ type ContractInfo struct {
|
||||
DestructedInBlock uint32 `json:"destructedInBlock,omitempty"`
|
||||
}
|
||||
|
||||
// Ethereum token type names
|
||||
// Ethereum token standard names
|
||||
const (
|
||||
ERC20TokenStandard TokenStandardName = "ERC20"
|
||||
ERC771TokenStandard TokenStandardName = "ERC721"
|
||||
ERC1155TokenStandard TokenStandardName = "ERC1155"
|
||||
)
|
||||
|
||||
// EthereumTokenTypeMap maps bchain.TokenType to TokenTypeName
|
||||
// the map must match all bchain.TokenType to avoid index out of range panic
|
||||
// EthereumTokenStandardMap maps bchain.TokenStandard to TokenStandardName
|
||||
// the map must match all bchain.TokenStandard to avoid index out of range panic
|
||||
var EthereumTokenStandardMap = []TokenStandardName{ERC20TokenStandard, ERC771TokenStandard, ERC1155TokenStandard}
|
||||
|
||||
type MultiTokenValue struct {
|
||||
|
||||
45
build/templates/backend/scripts/base.sh
Normal file
45
build/templates/backend/scripts/base.sh
Normal file
@@ -0,0 +1,45 @@
|
||||
#!/bin/sh
|
||||
|
||||
{{define "main" -}}
|
||||
|
||||
set -e
|
||||
|
||||
GETH_BIN={{.Env.BackendInstallPath}}/{{.Coin.Alias}}/geth
|
||||
DATA_DIR={{.Env.BackendDataPath}}/{{.Coin.Alias}}/backend
|
||||
|
||||
CHAINDATA_DIR=$DATA_DIR/geth/chaindata
|
||||
SNAPSHOT=https://mainnet-full-snapshots.base.org/$(curl https://mainnet-full-snapshots.base.org/latest)
|
||||
|
||||
if [ ! -d "$CHAINDATA_DIR" ]; then
|
||||
wget -c $SNAPSHOT -O - | zstd -cd | tar xf - --strip-components=1 -C $DATA_DIR
|
||||
fi
|
||||
|
||||
$GETH_BIN \
|
||||
--op-network base-mainnet \
|
||||
--datadir $DATA_DIR \
|
||||
--authrpc.jwtsecret $DATA_DIR/jwtsecret \
|
||||
--authrpc.addr 127.0.0.1 \
|
||||
--authrpc.port {{.Ports.BackendAuthRpc}} \
|
||||
--authrpc.vhosts "*" \
|
||||
--port {{.Ports.BackendP2P}} \
|
||||
--http \
|
||||
--http.port {{.Ports.BackendHttp}} \
|
||||
--http.addr 127.0.0.1 \
|
||||
--http.api eth,net,web3,debug,txpool,engine \
|
||||
--http.vhosts "*" \
|
||||
--http.corsdomain "*" \
|
||||
--ws \
|
||||
--ws.port {{.Ports.BackendRPC}} \
|
||||
--ws.addr 127.0.0.1 \
|
||||
--ws.api eth,net,web3,debug,txpool,engine \
|
||||
--ws.origins "*" \
|
||||
--rollup.disabletxpoolgossip=true \
|
||||
--rollup.sequencerhttp https://mainnet-sequencer.base.io \
|
||||
--state.scheme hash \
|
||||
--history.transactions 0 \
|
||||
--cache 4096 \
|
||||
--syncmode full \
|
||||
--maxpeers 0 \
|
||||
--nodiscover
|
||||
|
||||
{{end}}
|
||||
47
build/templates/backend/scripts/base_archive.sh
Normal file
47
build/templates/backend/scripts/base_archive.sh
Normal file
@@ -0,0 +1,47 @@
|
||||
#!/bin/sh
|
||||
|
||||
{{define "main" -}}
|
||||
|
||||
set -e
|
||||
|
||||
GETH_BIN={{.Env.BackendInstallPath}}/{{.Coin.Alias}}/geth
|
||||
DATA_DIR={{.Env.BackendDataPath}}/{{.Coin.Alias}}/backend
|
||||
|
||||
CHAINDATA_DIR=$DATA_DIR/geth/chaindata
|
||||
SNAPSHOT=https://mainnet-full-snapshots.base.org/$(curl https://mainnet-full-snapshots.base.org/latest)
|
||||
|
||||
if [ ! -d "$CHAINDATA_DIR" ]; then
|
||||
wget -c $SNAPSHOT -O - | zstd -cd | tar xf - --strip-components=1 -C $DATA_DIR
|
||||
fi
|
||||
|
||||
$GETH_BIN \
|
||||
--op-network base-mainnet \
|
||||
--datadir $DATA_DIR \
|
||||
--authrpc.jwtsecret $DATA_DIR/jwtsecret \
|
||||
--authrpc.addr 127.0.0.1 \
|
||||
--authrpc.port {{.Ports.BackendAuthRpc}} \
|
||||
--authrpc.vhosts "*" \
|
||||
--port {{.Ports.BackendP2P}} \
|
||||
--http \
|
||||
--http.port {{.Ports.BackendHttp}} \
|
||||
--http.addr 127.0.0.1 \
|
||||
--http.api eth,net,web3,debug,txpool,engine \
|
||||
--http.vhosts "*" \
|
||||
--http.corsdomain "*" \
|
||||
--ws \
|
||||
--ws.port {{.Ports.BackendRPC}} \
|
||||
--ws.addr 127.0.0.1 \
|
||||
--ws.api eth,net,web3,debug,txpool,engine \
|
||||
--ws.origins "*" \
|
||||
--rollup.disabletxpoolgossip=true \
|
||||
--rollup.sequencerhttp https://mainnet.sequencer.optimism.io \
|
||||
--cache 4096 \
|
||||
--cache.gc 0 \
|
||||
--cache.trie 30 \
|
||||
--cache.snapshot 20 \
|
||||
--syncmode full \
|
||||
--gcmode archive \
|
||||
--maxpeers 0 \
|
||||
--nodiscover
|
||||
|
||||
{{end}}
|
||||
24
build/templates/backend/scripts/base_archive_op_node.sh
Normal file
24
build/templates/backend/scripts/base_archive_op_node.sh
Normal file
@@ -0,0 +1,24 @@
|
||||
#!/bin/sh
|
||||
|
||||
{{define "main" -}}
|
||||
|
||||
set -e
|
||||
|
||||
BIN={{.Env.BackendInstallPath}}/{{.Coin.Alias}}/op-node
|
||||
|
||||
$BIN \
|
||||
--network base-mainnet \
|
||||
--l1 http://127.0.0.1:8116 \
|
||||
--l1.beacon http://127.0.0.1:7516 \
|
||||
--l1.trustrpc \
|
||||
--l1.rpckind=debug_geth \
|
||||
--l2 http://127.0.0.1:8411 \
|
||||
--rpc.addr 127.0.0.1 \
|
||||
--rpc.port {{.Ports.BackendRPC}} \
|
||||
--l2.jwt-secret {{.Env.BackendDataPath}}/base_archive/backend/jwtsecret \
|
||||
--p2p.bootnodes enr:-J24QNz9lbrKbN4iSmmjtnr7SjUMk4zB7f1krHZcTZx-JRKZd0kA2gjufUROD6T3sOWDVDnFJRvqBBo62zuF-hYCohOGAYiOoEyEgmlkgnY0gmlwhAPniryHb3BzdGFja4OFQgCJc2VjcDI1NmsxoQKNVFlCxh_B-716tTs-h1vMzZkSs1FTu_OYTNjgufplG4N0Y3CCJAaDdWRwgiQG,enr:-J24QH-f1wt99sfpHy4c0QJM-NfmsIfmlLAMMcgZCUEgKG_BBYFc6FwYgaMJMQN5dsRBJApIok0jFn-9CS842lGpLmqGAYiOoDRAgmlkgnY0gmlwhLhIgb2Hb3BzdGFja4OFQgCJc2VjcDI1NmsxoQJ9FTIv8B9myn1MWaC_2lJ-sMoeCDkusCsk4BYHjjCq04N0Y3CCJAaDdWRwgiQG,enr:-J24QDXyyxvQYsd0yfsN0cRr1lZ1N11zGTplMNlW4xNEc7LkPXh0NAJ9iSOVdRO95GPYAIc6xmyoCCG6_0JxdL3a0zaGAYiOoAjFgmlkgnY0gmlwhAPckbGHb3BzdGFja4OFQgCJc2VjcDI1NmsxoQJwoS7tzwxqXSyFL7g0JM-KWVbgvjfB8JA__T7yY_cYboN0Y3CCJAaDdWRwgiQG,enr:-J24QHmGyBwUZXIcsGYMaUqGGSl4CFdx9Tozu-vQCn5bHIQbR7On7dZbU61vYvfrJr30t0iahSqhc64J46MnUO2JvQaGAYiOoCKKgmlkgnY0gmlwhAPnCzSHb3BzdGFja4OFQgCJc2VjcDI1NmsxoQINc4fSijfbNIiGhcgvwjsjxVFJHUstK9L1T8OTKUjgloN0Y3CCJAaDdWRwgiQG,enr:-J24QG3ypT4xSu0gjb5PABCmVxZqBjVw9ca7pvsI8jl4KATYAnxBmfkaIuEqy9sKvDHKuNCsy57WwK9wTt2aQgcaDDyGAYiOoGAXgmlkgnY0gmlwhDbGmZaHb3BzdGFja4OFQgCJc2VjcDI1NmsxoQIeAK_--tcLEiu7HvoUlbV52MspE0uCocsx1f_rYvRenIN0Y3CCJAaDdWRwgiQG \
|
||||
--p2p.useragent base \
|
||||
--rollup.load-protocol-versions=true \
|
||||
--verifier.l1-confs 4
|
||||
|
||||
{{end}}
|
||||
24
build/templates/backend/scripts/base_op_node.sh
Normal file
24
build/templates/backend/scripts/base_op_node.sh
Normal file
@@ -0,0 +1,24 @@
|
||||
#!/bin/sh
|
||||
|
||||
{{define "main" -}}
|
||||
|
||||
set -e
|
||||
|
||||
BIN={{.Env.BackendInstallPath}}/{{.Coin.Alias}}/op-node
|
||||
|
||||
$BIN \
|
||||
--network base-mainnet \
|
||||
--l1 http://127.0.0.1:8136 \
|
||||
--l1.beacon http://127.0.0.1:7536 \
|
||||
--l1.trustrpc \
|
||||
--l1.rpckind debug_geth \
|
||||
--l2 http://127.0.0.1:8409 \
|
||||
--rpc.addr 127.0.0.1 \
|
||||
--rpc.port {{.Ports.BackendRPC}} \
|
||||
--l2.jwt-secret {{.Env.BackendDataPath}}/base/backend/jwtsecret \
|
||||
--p2p.bootnodes enr:-J24QNz9lbrKbN4iSmmjtnr7SjUMk4zB7f1krHZcTZx-JRKZd0kA2gjufUROD6T3sOWDVDnFJRvqBBo62zuF-hYCohOGAYiOoEyEgmlkgnY0gmlwhAPniryHb3BzdGFja4OFQgCJc2VjcDI1NmsxoQKNVFlCxh_B-716tTs-h1vMzZkSs1FTu_OYTNjgufplG4N0Y3CCJAaDdWRwgiQG,enr:-J24QH-f1wt99sfpHy4c0QJM-NfmsIfmlLAMMcgZCUEgKG_BBYFc6FwYgaMJMQN5dsRBJApIok0jFn-9CS842lGpLmqGAYiOoDRAgmlkgnY0gmlwhLhIgb2Hb3BzdGFja4OFQgCJc2VjcDI1NmsxoQJ9FTIv8B9myn1MWaC_2lJ-sMoeCDkusCsk4BYHjjCq04N0Y3CCJAaDdWRwgiQG,enr:-J24QDXyyxvQYsd0yfsN0cRr1lZ1N11zGTplMNlW4xNEc7LkPXh0NAJ9iSOVdRO95GPYAIc6xmyoCCG6_0JxdL3a0zaGAYiOoAjFgmlkgnY0gmlwhAPckbGHb3BzdGFja4OFQgCJc2VjcDI1NmsxoQJwoS7tzwxqXSyFL7g0JM-KWVbgvjfB8JA__T7yY_cYboN0Y3CCJAaDdWRwgiQG,enr:-J24QHmGyBwUZXIcsGYMaUqGGSl4CFdx9Tozu-vQCn5bHIQbR7On7dZbU61vYvfrJr30t0iahSqhc64J46MnUO2JvQaGAYiOoCKKgmlkgnY0gmlwhAPnCzSHb3BzdGFja4OFQgCJc2VjcDI1NmsxoQINc4fSijfbNIiGhcgvwjsjxVFJHUstK9L1T8OTKUjgloN0Y3CCJAaDdWRwgiQG,enr:-J24QG3ypT4xSu0gjb5PABCmVxZqBjVw9ca7pvsI8jl4KATYAnxBmfkaIuEqy9sKvDHKuNCsy57WwK9wTt2aQgcaDDyGAYiOoGAXgmlkgnY0gmlwhDbGmZaHb3BzdGFja4OFQgCJc2VjcDI1NmsxoQIeAK_--tcLEiu7HvoUlbV52MspE0uCocsx1f_rYvRenIN0Y3CCJAaDdWRwgiQG \
|
||||
--p2p.useragent base \
|
||||
--rollup.load-protocol-versions=true \
|
||||
--verifier.l1-confs 4
|
||||
|
||||
{{end}}
|
||||
67
configs/coins/base.json
Normal file
67
configs/coins/base.json
Normal file
@@ -0,0 +1,67 @@
|
||||
{
|
||||
"coin": {
|
||||
"name": "Base",
|
||||
"shortcut": "ETH",
|
||||
"network": "BASE",
|
||||
"label": "Base",
|
||||
"alias": "base"
|
||||
},
|
||||
"ports": {
|
||||
"backend_rpc": 8309,
|
||||
"backend_p2p": 38409,
|
||||
"backend_http": 8209,
|
||||
"backend_authrpc": 8409,
|
||||
"blockbook_internal": 9209,
|
||||
"blockbook_public": 9309
|
||||
},
|
||||
"ipc": {
|
||||
"rpc_url_template": "ws://127.0.0.1:{{.Ports.BackendRPC}}",
|
||||
"rpc_timeout": 25
|
||||
},
|
||||
"backend": {
|
||||
"package_name": "backend-base",
|
||||
"package_revision": "satoshilabs-1",
|
||||
"system_user": "base",
|
||||
"version": "1.101411.3",
|
||||
"docker_image": "us-docker.pkg.dev/oplabs-tools-artifacts/images/op-geth:v1.101411.3",
|
||||
"verification_type": "docker",
|
||||
"verification_source": "aefecdb139d8e3ed3128e7e3c87abb71198dc6a44ef21f012f391af52679e2c5",
|
||||
"extract_command": "docker cp extract:/usr/local/bin/geth backend/geth",
|
||||
"exclude_files": [],
|
||||
"exec_command_template": "/bin/sh -c '{{.Env.BackendInstallPath}}/{{.Coin.Alias}}/base_exec.sh 2>> {{.Env.BackendDataPath}}/{{.Coin.Alias}}/backend/{{.Coin.Alias}}.log'",
|
||||
"exec_script": "base.sh",
|
||||
"logrotate_files_template": "{{.Env.BackendDataPath}}/{{.Coin.Alias}}/backend/{{.Coin.Alias}}.log",
|
||||
"postinst_script_template": "openssl rand -hex 32 > {{.Env.BackendDataPath}}/{{.Coin.Alias}}/backend/jwtsecret",
|
||||
"service_type": "simple",
|
||||
"service_additional_params_template": "",
|
||||
"protect_memory": true,
|
||||
"mainnet": true,
|
||||
"server_config_file": "",
|
||||
"client_config_file": ""
|
||||
},
|
||||
"blockbook": {
|
||||
"package_name": "blockbook-base",
|
||||
"system_user": "blockbook-base",
|
||||
"internal_binding_template": ":{{.Ports.BlockbookInternal}}",
|
||||
"public_binding_template": ":{{.Ports.BlockbookPublic}}",
|
||||
"explorer_url": "",
|
||||
"additional_params": "",
|
||||
"block_chain": {
|
||||
"parse": true,
|
||||
"mempool_workers": 8,
|
||||
"mempool_sub_workers": 2,
|
||||
"block_addresses_to_keep": 300,
|
||||
"additional_params": {
|
||||
"mempoolTxTimeoutHours": 48,
|
||||
"queryBackendOnMempoolResync": false,
|
||||
"fiat_rates": "coingecko",
|
||||
"fiat_rates_vs_currencies": "AED,ARS,AUD,BDT,BHD,BMD,BRL,CAD,CHF,CLP,CNY,CZK,DKK,EUR,GBP,HKD,HUF,IDR,ILS,INR,JPY,KRW,KWD,LKR,MMK,MXN,MYR,NGN,NOK,NZD,PHP,PKR,PLN,RUB,SAR,SEK,SGD,THB,TRY,TWD,UAH,USD,VEF,VND,ZAR,BTC,ETH",
|
||||
"fiat_rates_params": "{\"coin\": \"ethereum\",\"platformIdentifier\": \"base\",\"platformVsCurrency\": \"eth\",\"periodSeconds\": 900}"
|
||||
}
|
||||
}
|
||||
},
|
||||
"meta": {
|
||||
"package_maintainer": "IT",
|
||||
"package_maintainer_email": "it@satoshilabs.com"
|
||||
}
|
||||
}
|
||||
70
configs/coins/base_archive.json
Normal file
70
configs/coins/base_archive.json
Normal file
@@ -0,0 +1,70 @@
|
||||
{
|
||||
"coin": {
|
||||
"name": "Base Archive",
|
||||
"shortcut": "ETH",
|
||||
"network": "BASE",
|
||||
"label": "Base",
|
||||
"alias": "base_archive"
|
||||
},
|
||||
"ports": {
|
||||
"backend_rpc": 8211,
|
||||
"backend_p2p": 38411,
|
||||
"backend_http": 8311,
|
||||
"backend_authrpc": 8411,
|
||||
"blockbook_internal": 9211,
|
||||
"blockbook_public": 9311
|
||||
},
|
||||
"ipc": {
|
||||
"rpc_url_template": "ws://127.0.0.1:{{.Ports.BackendRPC}}",
|
||||
"rpc_timeout": 25
|
||||
},
|
||||
"backend": {
|
||||
"package_name": "backend-base-archive",
|
||||
"package_revision": "satoshilabs-1",
|
||||
"system_user": "base",
|
||||
"version": "1.101411.3",
|
||||
"docker_image": "us-docker.pkg.dev/oplabs-tools-artifacts/images/op-geth:v1.101411.3",
|
||||
"verification_type": "docker",
|
||||
"verification_source": "aefecdb139d8e3ed3128e7e3c87abb71198dc6a44ef21f012f391af52679e2c5",
|
||||
"extract_command": "docker cp extract:/usr/local/bin/geth backend/geth",
|
||||
"exclude_files": [],
|
||||
"exec_command_template": "/bin/sh -c '{{.Env.BackendInstallPath}}/{{.Coin.Alias}}/base_archive_exec.sh 2>> {{.Env.BackendDataPath}}/{{.Coin.Alias}}/backend/{{.Coin.Alias}}.log'",
|
||||
"exec_script": "base_archive.sh",
|
||||
"logrotate_files_template": "{{.Env.BackendDataPath}}/{{.Coin.Alias}}/backend/{{.Coin.Alias}}.log",
|
||||
"postinst_script_template": "openssl rand -hex 32 > {{.Env.BackendDataPath}}/{{.Coin.Alias}}/backend/jwtsecret",
|
||||
"service_type": "simple",
|
||||
"service_additional_params_template": "",
|
||||
"protect_memory": true,
|
||||
"mainnet": true,
|
||||
"server_config_file": "",
|
||||
"client_config_file": ""
|
||||
},
|
||||
"blockbook": {
|
||||
"package_name": "blockbook-base-archive",
|
||||
"system_user": "blockbook-base",
|
||||
"internal_binding_template": ":{{.Ports.BlockbookInternal}}",
|
||||
"public_binding_template": ":{{.Ports.BlockbookPublic}}",
|
||||
"explorer_url": "",
|
||||
"additional_params": "-workers=16",
|
||||
"block_chain": {
|
||||
"parse": true,
|
||||
"mempool_workers": 8,
|
||||
"mempool_sub_workers": 2,
|
||||
"block_addresses_to_keep": 600,
|
||||
"additional_params": {
|
||||
"address_aliases": true,
|
||||
"mempoolTxTimeoutHours": 48,
|
||||
"processInternalTransactions": true,
|
||||
"queryBackendOnMempoolResync": false,
|
||||
"fiat_rates": "coingecko",
|
||||
"fiat_rates_vs_currencies": "AED,ARS,AUD,BDT,BHD,BMD,BRL,CAD,CHF,CLP,CNY,CZK,DKK,EUR,GBP,HKD,HUF,IDR,ILS,INR,JPY,KRW,KWD,LKR,MMK,MXN,MYR,NGN,NOK,NZD,PHP,PKR,PLN,RUB,SAR,SEK,SGD,THB,TRY,TWD,UAH,USD,VEF,VND,ZAR,BTC,ETH",
|
||||
"fiat_rates_params": "{\"coin\": \"ethereum\",\"platformIdentifier\": \"base\",\"platformVsCurrency\": \"eth\",\"periodSeconds\": 900}",
|
||||
"fourByteSignatures": "https://www.4byte.directory/api/v1/signatures/"
|
||||
}
|
||||
}
|
||||
},
|
||||
"meta": {
|
||||
"package_maintainer": "IT",
|
||||
"package_maintainer_email": "it@satoshilabs.com"
|
||||
}
|
||||
}
|
||||
38
configs/coins/base_archive_op_node.json
Normal file
38
configs/coins/base_archive_op_node.json
Normal file
@@ -0,0 +1,38 @@
|
||||
{
|
||||
"coin": {
|
||||
"name": "Base Archive Op-Node",
|
||||
"shortcut": "ETH",
|
||||
"label": "Base",
|
||||
"alias": "base_archive_op_node"
|
||||
},
|
||||
"ports": {
|
||||
"backend_rpc": 8212,
|
||||
"blockbook_internal": 9212,
|
||||
"blockbook_public": 9312
|
||||
},
|
||||
"backend": {
|
||||
"package_name": "backend-base-archive-op-node",
|
||||
"package_revision": "satoshilabs-1",
|
||||
"system_user": "base",
|
||||
"version": "1.10.1",
|
||||
"docker_image": "us-docker.pkg.dev/oplabs-tools-artifacts/images/op-node:v1.10.1",
|
||||
"verification_type": "docker",
|
||||
"verification_source": "8f40714868fbdc788f67251383a0c0b78a3a937f07b2303bc7d33df5df6297d9",
|
||||
"extract_command": "docker cp extract:/usr/local/bin/op-node backend/op-node",
|
||||
"exclude_files": [],
|
||||
"exec_command_template": "/bin/sh -c '{{.Env.BackendInstallPath}}/{{.Coin.Alias}}/base_archive_op_node_exec.sh 2>&1 >> {{.Env.BackendDataPath}}/{{.Coin.Alias}}/backend/{{.Coin.Alias}}.log'",
|
||||
"exec_script": "base_archive_op_node.sh",
|
||||
"logrotate_files_template": "{{.Env.BackendDataPath}}/{{.Coin.Alias}}/backend/{{.Coin.Alias}}.log",
|
||||
"postinst_script_template": "",
|
||||
"service_type": "simple",
|
||||
"service_additional_params_template": "",
|
||||
"protect_memory": true,
|
||||
"mainnet": true,
|
||||
"server_config_file": "",
|
||||
"client_config_file": ""
|
||||
},
|
||||
"meta": {
|
||||
"package_maintainer": "IT",
|
||||
"package_maintainer_email": "it@satoshilabs.com"
|
||||
}
|
||||
}
|
||||
38
configs/coins/base_op_node.json
Normal file
38
configs/coins/base_op_node.json
Normal file
@@ -0,0 +1,38 @@
|
||||
{
|
||||
"coin": {
|
||||
"name": "Base Op-Node",
|
||||
"shortcut": "ETH",
|
||||
"label": "Base",
|
||||
"alias": "base_op_node"
|
||||
},
|
||||
"ports": {
|
||||
"backend_rpc": 8210,
|
||||
"blockbook_internal": 9210,
|
||||
"blockbook_public": 9310
|
||||
},
|
||||
"backend": {
|
||||
"package_name": "backend-base-op-node",
|
||||
"package_revision": "satoshilabs-1",
|
||||
"system_user": "base",
|
||||
"version": "1.10.1",
|
||||
"docker_image": "us-docker.pkg.dev/oplabs-tools-artifacts/images/op-node:v1.10.1",
|
||||
"verification_type": "docker",
|
||||
"verification_source": "8f40714868fbdc788f67251383a0c0b78a3a937f07b2303bc7d33df5df6297d9",
|
||||
"extract_command": "docker cp extract:/usr/local/bin/op-node backend/op-node",
|
||||
"exclude_files": [],
|
||||
"exec_command_template": "/bin/sh -c '{{.Env.BackendInstallPath}}/{{.Coin.Alias}}/base_op_node_exec.sh 2>&1 >> {{.Env.BackendDataPath}}/{{.Coin.Alias}}/backend/{{.Coin.Alias}}.log'",
|
||||
"exec_script": "base_op_node.sh",
|
||||
"logrotate_files_template": "{{.Env.BackendDataPath}}/{{.Coin.Alias}}/backend/{{.Coin.Alias}}.log",
|
||||
"postinst_script_template": "",
|
||||
"service_type": "simple",
|
||||
"service_additional_params_template": "",
|
||||
"protect_memory": true,
|
||||
"mainnet": true,
|
||||
"server_config_file": "",
|
||||
"client_config_file": ""
|
||||
},
|
||||
"meta": {
|
||||
"package_maintainer": "IT",
|
||||
"package_maintainer_email": "it@satoshilabs.com"
|
||||
}
|
||||
}
|
||||
@@ -177,21 +177,21 @@ func unpackAddrContracts(buf []byte, addrDesc bchain.AddressDescriptor) (*AddrCo
|
||||
contract := append(bchain.AddressDescriptor(nil), buf[:eth.EthereumTypeAddressDescriptorLen]...)
|
||||
txs, l := unpackVaruint(buf[eth.EthereumTypeAddressDescriptorLen:])
|
||||
buf = buf[eth.EthereumTypeAddressDescriptorLen+l:]
|
||||
ttt := bchain.TokenStandard(txs & 3)
|
||||
standard := bchain.TokenStandard(txs & 3)
|
||||
txs >>= 2
|
||||
ac := AddrContract{
|
||||
Standard: ttt,
|
||||
Standard: standard,
|
||||
Contract: contract,
|
||||
Txs: txs,
|
||||
}
|
||||
if ttt == bchain.FungibleToken {
|
||||
if standard == bchain.FungibleToken {
|
||||
b, ll := unpackBigint(buf)
|
||||
buf = buf[ll:]
|
||||
ac.Value = b
|
||||
} else {
|
||||
len, ll := unpackVaruint(buf)
|
||||
buf = buf[ll:]
|
||||
if ttt == bchain.NonFungibleToken {
|
||||
if standard == bchain.NonFungibleToken {
|
||||
ac.Ids = make(Ids, len)
|
||||
for i := uint(0); i < len; i++ {
|
||||
b, ll := unpackBigint(buf)
|
||||
@@ -391,7 +391,7 @@ func (d *RocksDB) addToAddressesAndContractsEthereumType(addrDesc bchain.Address
|
||||
|
||||
type ethBlockTxContract struct {
|
||||
from, to, contract bchain.AddressDescriptor
|
||||
transferType bchain.TokenStandard
|
||||
transferStandard bchain.TokenStandard
|
||||
value big.Int
|
||||
idValues []bchain.MultiTokenValue
|
||||
}
|
||||
@@ -566,7 +566,7 @@ func (d *RocksDB) processContractTransfers(blockTx *ethBlockTx, tx *bchain.Tx, a
|
||||
return err
|
||||
}
|
||||
bc := &blockTx.contracts[i]
|
||||
bc.transferType = t.Standard
|
||||
bc.transferStandard = t.Standard
|
||||
bc.from = from
|
||||
bc.to = to
|
||||
bc.contract = contract
|
||||
@@ -890,9 +890,9 @@ func (d *RocksDB) GetContractInfoForAddress(address string) (*bchain.ContractInf
|
||||
return d.GetContractInfo(contract, "")
|
||||
}
|
||||
|
||||
// GetContractInfo gets contract from cache or DB and possibly updates the type from typeFromContext
|
||||
// it is hard to guess the type of the contract using API, it is easier to set it the first time the contract is processed in a tx
|
||||
func (d *RocksDB) GetContractInfo(contract bchain.AddressDescriptor, typeFromContext bchain.TokenStandardName) (*bchain.ContractInfo, error) {
|
||||
// GetContractInfo gets contract from cache or DB and possibly updates the standard from standardFromContext
|
||||
// it is hard to guess the standard of the contract using API, it is easier to set it the first time the contract is processed in a tx
|
||||
func (d *RocksDB) GetContractInfo(contract bchain.AddressDescriptor, standardFromContext bchain.TokenStandardName) (*bchain.ContractInfo, error) {
|
||||
cacheKey := string(contract)
|
||||
cachedContractsMux.Lock()
|
||||
contractInfo, found := cachedContracts[cacheKey]
|
||||
@@ -912,10 +912,10 @@ func (d *RocksDB) GetContractInfo(contract bchain.AddressDescriptor, typeFromCon
|
||||
if len(addresses) > 0 {
|
||||
contractInfo.Contract = addresses[0]
|
||||
}
|
||||
// if the type is specified and stored contractInfo has unknown type, set and store it
|
||||
if typeFromContext != bchain.UnknownTokenStandard && contractInfo.Standard == bchain.UnknownTokenStandard {
|
||||
contractInfo.Standard = typeFromContext
|
||||
contractInfo.Type = typeFromContext
|
||||
// if the standard is specified and stored contractInfo has unknown standard, set and store it
|
||||
if standardFromContext != bchain.UnknownTokenStandard && contractInfo.Standard == bchain.UnknownTokenStandard {
|
||||
contractInfo.Standard = standardFromContext
|
||||
contractInfo.Type = standardFromContext
|
||||
err = d.db.PutCF(d.wo, d.cfh[cfContracts], contract, packContractInfo(contractInfo))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -980,9 +980,9 @@ func packBlockTx(buf []byte, blockTx *ethBlockTx) []byte {
|
||||
buf = appendAddress(buf, c.from)
|
||||
buf = appendAddress(buf, c.to)
|
||||
buf = appendAddress(buf, c.contract)
|
||||
l = packVaruint(uint(c.transferType), varBuf)
|
||||
l = packVaruint(uint(c.transferStandard), varBuf)
|
||||
buf = append(buf, varBuf[:l]...)
|
||||
if c.transferType == bchain.MultiToken {
|
||||
if c.transferStandard == bchain.MultiToken {
|
||||
l = packVaruint(uint(len(c.idValues)), varBuf)
|
||||
buf = append(buf, varBuf[:l]...)
|
||||
for i := range c.idValues {
|
||||
@@ -1144,9 +1144,9 @@ func unpackBlockTx(buf []byte, pos int) (*ethBlockTx, int, error) {
|
||||
return nil, 0, err
|
||||
}
|
||||
cc, l = unpackVaruint(buf[pos:])
|
||||
c.transferType = bchain.TokenStandard(cc)
|
||||
c.transferStandard = bchain.TokenStandard(cc)
|
||||
pos += l
|
||||
if c.transferType == bchain.MultiToken {
|
||||
if c.transferStandard == bchain.MultiToken {
|
||||
cc, l = unpackVaruint(buf[pos:])
|
||||
pos += l
|
||||
c.idValues = make([]bchain.MultiTokenValue, cc)
|
||||
@@ -1259,7 +1259,7 @@ func (d *RocksDB) disconnectAddress(btxID []byte, internal bool, addrDesc bchain
|
||||
index = transferTo
|
||||
}
|
||||
addToContract(addrContract, contractIndex, index, btxContract.contract, &bchain.TokenTransfer{
|
||||
Standard: btxContract.transferType,
|
||||
Standard: btxContract.transferStandard,
|
||||
Value: btxContract.value,
|
||||
MultiTokenValues: btxContract.idValues,
|
||||
}, false)
|
||||
|
||||
@@ -1150,11 +1150,11 @@ func Test_packUnpackBlockTx(t *testing.T) {
|
||||
to: addressToAddrDesc(dbtestdata.EthAddr55, parser),
|
||||
contracts: []ethBlockTxContract{
|
||||
{
|
||||
from: addressToAddrDesc(dbtestdata.EthAddr20, parser),
|
||||
to: addressToAddrDesc(dbtestdata.EthAddr5d, parser),
|
||||
contract: addressToAddrDesc(dbtestdata.EthAddrContract4a, parser),
|
||||
transferType: bchain.FungibleToken,
|
||||
value: *big.NewInt(10000),
|
||||
from: addressToAddrDesc(dbtestdata.EthAddr20, parser),
|
||||
to: addressToAddrDesc(dbtestdata.EthAddr5d, parser),
|
||||
contract: addressToAddrDesc(dbtestdata.EthAddrContract4a, parser),
|
||||
transferStandard: bchain.FungibleToken,
|
||||
value: *big.NewInt(10000),
|
||||
},
|
||||
},
|
||||
},
|
||||
@@ -1168,24 +1168,24 @@ func Test_packUnpackBlockTx(t *testing.T) {
|
||||
to: addressToAddrDesc(dbtestdata.EthAddr55, parser),
|
||||
contracts: []ethBlockTxContract{
|
||||
{
|
||||
from: addressToAddrDesc(dbtestdata.EthAddr20, parser),
|
||||
to: addressToAddrDesc(dbtestdata.EthAddr3e, parser),
|
||||
contract: addressToAddrDesc(dbtestdata.EthAddrContract4a, parser),
|
||||
transferType: bchain.FungibleToken,
|
||||
value: *big.NewInt(987654321),
|
||||
from: addressToAddrDesc(dbtestdata.EthAddr20, parser),
|
||||
to: addressToAddrDesc(dbtestdata.EthAddr3e, parser),
|
||||
contract: addressToAddrDesc(dbtestdata.EthAddrContract4a, parser),
|
||||
transferStandard: bchain.FungibleToken,
|
||||
value: *big.NewInt(987654321),
|
||||
},
|
||||
{
|
||||
from: addressToAddrDesc(dbtestdata.EthAddr4b, parser),
|
||||
to: addressToAddrDesc(dbtestdata.EthAddr55, parser),
|
||||
contract: addressToAddrDesc(dbtestdata.EthAddrContract6f, parser),
|
||||
transferType: bchain.NonFungibleToken,
|
||||
value: *big.NewInt(13),
|
||||
from: addressToAddrDesc(dbtestdata.EthAddr4b, parser),
|
||||
to: addressToAddrDesc(dbtestdata.EthAddr55, parser),
|
||||
contract: addressToAddrDesc(dbtestdata.EthAddrContract6f, parser),
|
||||
transferStandard: bchain.NonFungibleToken,
|
||||
value: *big.NewInt(13),
|
||||
},
|
||||
{
|
||||
from: addressToAddrDesc(dbtestdata.EthAddr5d, parser),
|
||||
to: addressToAddrDesc(dbtestdata.EthAddr7b, parser),
|
||||
contract: addressToAddrDesc(dbtestdata.EthAddrContractCd, parser),
|
||||
transferType: bchain.MultiToken,
|
||||
from: addressToAddrDesc(dbtestdata.EthAddr5d, parser),
|
||||
to: addressToAddrDesc(dbtestdata.EthAddr7b, parser),
|
||||
contract: addressToAddrDesc(dbtestdata.EthAddrContractCd, parser),
|
||||
transferStandard: bchain.MultiToken,
|
||||
idValues: []bchain.MultiTokenValue{
|
||||
{
|
||||
Id: *big.NewInt(1234),
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
# Registry of ports
|
||||
|
||||
| coin | blockbook public | blockbook internal | backend rpc | backend service ports (zmq) |
|
||||
| -------------------------------- | ---------------- | ------------------ | ----------- | --------------------------------------------------- |
|
||||
|----------------------------------|------------------|--------------------|-------------|-----------------------------------------------------|
|
||||
| Ethereum Archive | 9116 | 9016 | 8016 | 38316 p2p, 8116 http, 8516 authrpc |
|
||||
| Bitcoin | 9130 | 9030 | 8030 | 38330 |
|
||||
| Bitcoin Cash | 9131 | 9031 | 8031 | 38331 |
|
||||
@@ -59,6 +59,8 @@
|
||||
| Arbitrum Archive | 9306 | 9206 | 8306 | 38406 p2p |
|
||||
| Arbitrum Nova | 9307 | 9207 | 8207 | 38407 p2p, 8307 http |
|
||||
| Arbitrum Nova Archive | 9308 | 9208 | 8308 | 38408 p2p |
|
||||
| Base | 9309 | 9209 | 8309 | 38409 p2p, 8209 http, 8409 authrpc |
|
||||
| Base Archive | 9311 | 9211 | 8211 | 38411 p2p, 8311 http, 8411 authrpc |
|
||||
| Ethereum Testnet Holesky | 19116 | 19016 | 18016 | 18116 http, 18516 authrpc, 48316 p2p |
|
||||
| Bitcoin Signet | 19120 | 19020 | 18020 | 48320 |
|
||||
| Bitcoin Regtest | 19121 | 19021 | 18021 | 48321 |
|
||||
|
||||
@@ -745,7 +745,7 @@ func isOwnAddress(td *TemplateData, a string) bool {
|
||||
func tokenTransfersCount(tx *api.Tx, t bchain.TokenStandardName) int {
|
||||
count := 0
|
||||
for i := range tx.TokenTransfers {
|
||||
if tx.TokenTransfers[i].Type == t {
|
||||
if tx.TokenTransfers[i].Standard == t {
|
||||
count++
|
||||
}
|
||||
}
|
||||
@@ -756,7 +756,7 @@ func tokenTransfersCount(tx *api.Tx, t bchain.TokenStandardName) int {
|
||||
func tokenCount(tokens []api.Token, t bchain.TokenStandardName) int {
|
||||
count := 0
|
||||
for i := range tokens {
|
||||
if tokens[i].Type == t {
|
||||
if tokens[i].Standard == t {
|
||||
count++
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user