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:
kevin
2025-02-20 14:55:15 -07:00
committed by GitHub
parent 397789b130
commit 7d4872e830
18 changed files with 489 additions and 61 deletions

View File

@@ -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)

View 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
}

View File

@@ -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

View File

@@ -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{

View File

@@ -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 = "-"

View File

@@ -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 {

View 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}}

View 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}}

View 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}}

View 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
View 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"
}
}

View 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"
}
}

View 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"
}
}

View 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"
}
}

View File

@@ -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)

View File

@@ -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),

View File

@@ -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 |

View File

@@ -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++
}
}