diff --git a/bchain/coins/blockchain.go b/bchain/coins/blockchain.go index 5c906bd5fd..ea675bb6f3 100644 --- a/bchain/coins/blockchain.go +++ b/bchain/coins/blockchain.go @@ -30,6 +30,7 @@ import ( "github.com/trezor/blockbook/bchain/coins/dogecoin" "github.com/trezor/blockbook/bchain/coins/ecash" "github.com/trezor/blockbook/bchain/coins/eth" + "github.com/trezor/blockbook/bchain/coins/ethw" "github.com/trezor/blockbook/bchain/coins/firo" "github.com/trezor/blockbook/bchain/coins/flo" "github.com/trezor/blockbook/bchain/coins/fujicoin" @@ -84,6 +85,8 @@ func init() { BlockChainFactories["Ethereum Testnet Holesky Archive"] = eth.NewEthereumRPC BlockChainFactories["Ethereum Testnet Hoodi"] = eth.NewEthereumRPC BlockChainFactories["Ethereum Testnet Hoodi Archive"] = eth.NewEthereumRPC + BlockChainFactories["Ethereum PoW"] = ethw.NewEthereumPoWRPC + BlockChainFactories["Ethereum PoW Archive"] = ethw.NewEthereumPoWRPC BlockChainFactories["Bcash"] = bch.NewBCashRPC BlockChainFactories["Bcash Testnet"] = bch.NewBCashRPC BlockChainFactories["Bgold"] = btg.NewBGoldRPC diff --git a/bchain/coins/ethw/ethwrpc.go b/bchain/coins/ethw/ethwrpc.go new file mode 100644 index 0000000000..ac3b111023 --- /dev/null +++ b/bchain/coins/ethw/ethwrpc.go @@ -0,0 +1,79 @@ +package ethw + +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 = 10001 +) + +// EthereumPoWRPC is an interface to JSON-RPC eth service for Ethereum PoW (ETHW). +// ETHW is a geth-based PoW fork of Ethereum; it reuses the EthereumType machinery +// unchanged and only differs in the network id reported by the backend. +type EthereumPoWRPC struct { + *eth.EthereumRPC +} + +// NewEthereumPoWRPC returns new EthereumPoWRPC instance. +func NewEthereumPoWRPC(config json.RawMessage, pushHandler func(bchain.NotificationType)) (bchain.BlockChain, error) { + c, err := eth.NewEthereumRPC(config, pushHandler) + if err != nil { + return nil, err + } + + s := &EthereumPoWRPC{ + EthereumRPC: c.(*eth.EthereumRPC), + } + + return s, nil +} + +// Initialize ethereum pow rpc interface +func (b *EthereumPoWRPC) Initialize() error { + b.OpenRPC = eth.OpenRPC + + rc, ec, err := b.OpenRPC(b.ChainConfig.RPCURL, b.ChainConfig.RPCURLWS) + 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) + } + + if err = b.InitAlternativeProviders(); err != nil { + return err + } + + glog.Info("rpc: block chain ", b.Network) + + return nil +} diff --git a/configs/coins/ethw.json b/configs/coins/ethw.json new file mode 100644 index 0000000000..efa3699eef --- /dev/null +++ b/configs/coins/ethw.json @@ -0,0 +1,73 @@ +{ + "coin": { + "name": "Ethereum PoW", + "shortcut": "ETHW", + "network": "ETHW", + "label": "Ethereum PoW", + "alias": "ethw" + }, + "ports": { + "backend_rpc": 8063, + "backend_message_queue": 0, + "backend_p2p": 38363, + "backend_http": 8163, + "blockbook_internal": 9063, + "blockbook_public": 9163 + }, + "ipc": { + "rpc_url_template": "http://127.0.0.1:{{.Ports.BackendRPC}}", + "rpc_url_ws_template": "ws://127.0.0.1:{{.Ports.BackendRPC}}", + "rpc_timeout": 25 + }, + "backend": { + "package_name": "backend-ethw", + "package_revision": "satoshilabs-1", + "system_user": "ethw", + "version": "1.10.23.1", + "binary_url": "https://github.com/ethereumpow/go-ethereum/releases/download/v1.10.23.1/geth_linux_amd64_1.10.23_2a4c42d43eb7ea0a20ec096946e8a80c52f4000c75001d115c29395abafe2a7c.zip", + "verification_type": "sha256", + "verification_source": "2a4c42d43eb7ea0a20ec096946e8a80c52f4000c75001d115c29395abafe2a7c", + "extract_command": "unzip -d backend", + "exclude_files": [ + "checksum.txt" + ], + "exec_command_template": "/bin/sh -c '{{.Env.BackendInstallPath}}/{{.Coin.Alias}}/geth --ipcdisable --txlookuplimit 0 --cache 1024 --nat none --datadir {{.Env.BackendDataPath}}/{{.Coin.Alias}}/backend --port {{.Ports.BackendP2P}} --ws --ws.addr {{.Env.RPCBindHost}} --ws.port {{.Ports.BackendRPC}} --ws.origins \"*\" --ws.api \"eth,net,web3,debug,txpool\" --http --http.port {{.Ports.BackendRPC}} --http.addr {{.Env.RPCBindHost}} --http.corsdomain \"*\" --http.vhosts \"*\" --http.api \"eth,net,web3,debug,txpool\" 2>>{{.Env.BackendDataPath}}/{{.Coin.Alias}}/backend/{{.Coin.Alias}}.log'", + "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": "" + }, + "blockbook": { + "package_name": "blockbook-ethw", + "system_user": "blockbook-ethw", + "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": { + "averageBlockTimeMs": 13000, + "address_aliases": true, + "eip1559Fees": true, + "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-pow-iou\",\"platformIdentifier\": \"ethereum\",\"platformVsCurrency\": \"usd\",\"periodSeconds\": 900}", + "fourByteSignatures": "https://www.4byte.directory/api/v1/signatures/" + } + } + }, + "meta": { + "package_maintainer": "IT", + "package_maintainer_email": "it@satoshilabs.com" + } +} diff --git a/docs/ports.md b/docs/ports.md index 48519ea88f..7816fd4dba 100644 --- a/docs/ports.md +++ b/docs/ports.md @@ -11,6 +11,7 @@ | Bitcoin Gold | 9135 | 9035 | 8035 | 38335 | | Ethereum | 9136 | 9036 | 8036 | 38336 p2p, 8136 http, 8536 authrpc | | Ethereum Classic | 9137 | 9037 | 8037 | 38337 p2p, 8137 http | +| Ethereum PoW | 9163 | 9063 | 8063 | 38363 p2p, 8163 http | | Dogecoin | 9138 | 9038 | 8038 | 38338 | | Namecoin | 9139 | 9039 | 8039 | 38339 | | Vertcoin | 9140 | 9040 | 8040 | 38340 | diff --git a/tests/rpc/testdata/ethw.json b/tests/rpc/testdata/ethw.json new file mode 100644 index 0000000000..5062c8fc3a --- /dev/null +++ b/tests/rpc/testdata/ethw.json @@ -0,0 +1,79 @@ +{ + "blockHeight": 16033808, + "blockHash": "0x2a2bec19cba714fcc10c873930e040be0e06df4f9e81913973d7efde3d0708b6", + "blockTime": 1669804588, + "blockSize": 15015, + "blockTxs": [ + "0x8e727991b6cac991f5de239d9ac52bf35a34344c3715f52b4680fd76736c00f5", + "0xc77ccf22ce47fe5189c070c838c748bc84c6909a980acbf22a15741a70939197", + "0xea31f202a45fee2a21a4f8d975225dbf0ba75f56fa5fb10bee256047e6c6dd3c", + "0xc242a71e6f8aff873035c12c3f9e03ac833ad3b1dc150846210865f79530eafa", + "0xdc10c9d50c3ed1616029b8c404448707a530f63ffb568c2d8c2bda14bd043d00", + "0x0e7f33caf918789dfb06d91d7d7d282cc8a1a140c9efd84104cdffbbd74c76a1", + "0x68c877530b42f04bd0aa6b1b4588b3b8592758875704ba2619a2b9b7d3200131", + "0xdf02f85ce4638db61b3f5f59442f0e822279970c78f36fa8e318477c74ee861d", + "0xee6663edad099576344ee2814c7a2946c4439b807a6d135ef25c43f724a4b5ff", + "0x84891cc5be64f0ca5810711e84dc484c214c40ba46f4db9b59bee470fc3e4cf9", + "0x736036446d2d38907232ada5385937de679d7be814f3927171bc9483f38ebaa7", + "0x283b511fb76e4102e275cd6475958df88acb51809c78f9fb7845198246f6be34", + "0xd6ec5e47b1f3bb4b9af654d45b7a2d6949bd2088d6833f38858d8ca8441fe57d", + "0x3e00f8eeee82073bcbfc36335cab0af6a668aa95a785d801ff0ce341fc32556f", + "0x72e23486f1059bc6474ec7085d5692b2a7ef82a54b06d6a6781eaa6bee61b87f", + "0x0b243cc8c8406f17117a5e955455a7a66a72118e3cabda1fa4a8c78ad0188771", + "0xb3d3eea05501c639ead85d2a2d9e3ee0053450b6717765895e8d3ed7e4f097db", + "0x1163aa0469e7bed608ec989b4c0ce57d9e5bafc9912e1d7e86b20eb65ca16aa9", + "0xc6b7b5bcc0dcd23e7f38d74fda9a2d1cb1029b1fcc31d3c11bc2cb21dc57c13c", + "0x614a7c401f053a77df4c47c7ebd5052ff8755415c459b6ba4d8bcdadfad7cd64", + "0x6c2794b4106f0e836082fd0002da11ee3b1db66a769d06fb59caed5d55c677b2", + "0xc15260aa723372f87306797f451e0f7ed0f7918fec30a99658b60a63b2d8d937", + "0x23d875a6b909f2d60eafa1992f0039e583b006d31af07c8579256b049eb9e699", + "0x4e6fc6d49c7e2e9411cfcbb48dedec8819354777183b147545740538ce647d66", + "0x317a0da3268d6ee5fff6bb40bf0ae405357d131a3afd2e1f9349c27deba40851", + "0xe66b5bf48648e5f499192d835c58238ced77baa9b760cf8618e0a4209ed753ca", + "0x6a728f9eb6a2fd21c539f4fb26dc3d25f5eac8a1012af40d870beb97bbdb8b16", + "0x282c3f1ef35fe0e2878393f3cd274f6abe0c40452cf69508e92fae6f041b82d2", + "0xe3988978667db849184e94cbe6a3a3877a4a036818d17365caa9086012f9e579", + "0xf565bf06c038baf0e2b47b1f3d3cb1e9260654900afaa176b63254f06ae15fa0", + "0x7634b8dca0c1108d7647801bd653a85a3464c67e01c440a74e1ee45cb309692e", + "0x68a6c3603578d9f5dec3f6903a110c8df669bdbba616c3621dc0caef481cee51", + "0x443d680ba47e14227d0833616280a71016dc40bf2768018881810daa56ae907c", + "0x0ba22fbbbb3f2f9dba3f6a5188506cc75441d7a76e6fe8df68ef2ddef1888a9e", + "0xf494c3da98c81fba7dfbe2b8d43be753f5633d5a1817f9552548cbd3199379ba", + "0xc4c731efd7045fb67fe2811af4bbfc7b42a75ca93987d66d62ed42c5ac06fb37", + "0xdec2ad3e8823a73f5464e7787d67e21f531b94de951ffa48d6df90c7b8a62555", + "0x7507ed7b50f07f2331bab1bbb3b7251c4f922c1435a1d0c88d2daf82ece2374b", + "0x558bb6f205d8df666b0eeb0772de2b5f39b2199e4723e548a2816862d662e447" + ], + "ethCallBatch": { + "address": "0xa649fFC455AC7C5acc1bc35726FcE54e25Eb59f9", + "contracts": [ + "0x5186c4Fb5752Eb4A952C7EF03fAE3e543f48383e", + "0x79B15430FB29A55fF2297985B9aA5e716Cd7534C", + "0xD021881840fc7a57089Cb4635628658E68c83B2b" + ] + }, + "txDetails": { + "0xea31f202a45fee2a21a4f8d975225dbf0ba75f56fa5fb10bee256047e6c6dd3c": { + "txid": "0xea31f202a45fee2a21a4f8d975225dbf0ba75f56fa5fb10bee256047e6c6dd3c", + "blockTime": 1669804588, + "time": 1669804588, + "vin": [ + { + "addresses": [ + "0x251c4A6AfF8122fA1497cDAb9Bf1D0d51dff834d" + ] + } + ], + "vout": [ + { + "value": 0.0004, + "scriptPubKey": { + "addresses": [ + "0x121655a148E538120E2756428A7b90e59Ec0aedf" + ] + } + } + ] + } + } +} diff --git a/tests/tests.json b/tests/tests.json index 8180af25e7..0818178c95 100644 --- a/tests/tests.json +++ b/tests/tests.json @@ -82,6 +82,13 @@ "WsGetInfo", "WsGetBlockHash", "WsGetTransaction", "WsGetAccountInfoBasicEVM", "WsGetAccountInfoEVM", "WsGetAccountInfoTxidsConsistencyEVM", "WsGetAccountInfoTxsConsistencyEVM", "WsGetAccountInfoContractFilterEVM", "WsPing"], "rpc": ["GetBlock", "GetBlockHash", "GetTransaction", "EstimateFee", "GetBlockHeader", "EthCallBatch"] }, + "ethw": { + "connectivity": ["http", "ws"], + "api": ["Status", "GetBlockIndex", "GetBlockByHeight", "GetBlock", "GetTransaction", "GetTransactionSpecific", + "GetAddress", "GetAddressBasicEVM", "GetAddressTokensEVM", "GetAddressTokenBalances", "GetAddressTxidsPaginationEVM", "GetAddressTxsPaginationEVM", "GetAddressContractFilterEVM", "GetTransactionEVMShape", + "WsGetInfo", "WsGetBlockHash", "WsGetTransaction", "WsGetAccountInfoBasicEVM", "WsGetAccountInfoEVM", "WsGetAccountInfoTxidsConsistencyEVM", "WsGetAccountInfoTxsConsistencyEVM", "WsGetAccountInfoContractFilterEVM", "WsPing"], + "rpc": ["GetBlock", "GetBlockHash", "GetTransaction", "EstimateFee", "GetBlockHeader", "EthCallBatch"] + }, "cpuchain": { "rpc": ["GetBlock", "GetBlockHash", "GetTransaction", "GetTransactionForMempool", "MempoolSync", "EstimateSmartFee", "EstimateFee"],