github.com/theQRL/go-zond@v0.2.1/zondclient/zondclient.go (about) 1 // Copyright 2016 The go-ethereum Authors 2 // This file is part of the go-ethereum library. 3 // 4 // The go-ethereum library is free software: you can redistribute it and/or modify 5 // it under the terms of the GNU Lesser General Public License as published by 6 // the Free Software Foundation, either version 3 of the License, or 7 // (at your option) any later version. 8 // 9 // The go-ethereum library is distributed in the hope that it will be useful, 10 // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 // GNU Lesser General Public License for more details. 13 // 14 // You should have received a copy of the GNU Lesser General Public License 15 // along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>. 16 17 // Package zondclient provides a client for the Zond RPC API. 18 package zondclient 19 20 import ( 21 "context" 22 "encoding/json" 23 "errors" 24 "fmt" 25 "math/big" 26 27 "github.com/theQRL/go-zond" 28 "github.com/theQRL/go-zond/common" 29 "github.com/theQRL/go-zond/common/hexutil" 30 "github.com/theQRL/go-zond/core/types" 31 "github.com/theQRL/go-zond/rpc" 32 ) 33 34 // Client defines typed wrappers for the Zond RPC API. 35 type Client struct { 36 c *rpc.Client 37 } 38 39 // Dial connects a client to the given URL. 40 func Dial(rawurl string) (*Client, error) { 41 return DialContext(context.Background(), rawurl) 42 } 43 44 // DialContext connects a client to the given URL with context. 45 func DialContext(ctx context.Context, rawurl string) (*Client, error) { 46 c, err := rpc.DialContext(ctx, rawurl) 47 if err != nil { 48 return nil, err 49 } 50 return NewClient(c), nil 51 } 52 53 // NewClient creates a client that uses the given RPC client. 54 func NewClient(c *rpc.Client) *Client { 55 return &Client{c} 56 } 57 58 // Close closes the underlying RPC connection. 59 func (ec *Client) Close() { 60 ec.c.Close() 61 } 62 63 // Client gets the underlying RPC client. 64 func (ec *Client) Client() *rpc.Client { 65 return ec.c 66 } 67 68 // Blockchain Access 69 70 // ChainID retrieves the current chain ID for transaction replay protection. 71 func (ec *Client) ChainID(ctx context.Context) (*big.Int, error) { 72 var result hexutil.Big 73 err := ec.c.CallContext(ctx, &result, "zond_chainId") 74 if err != nil { 75 return nil, err 76 } 77 return (*big.Int)(&result), err 78 } 79 80 // BlockByHash returns the given full block. 81 // 82 // Note that loading full blocks requires two requests. Use HeaderByHash 83 // if you don't need all transactions. 84 func (ec *Client) BlockByHash(ctx context.Context, hash common.Hash) (*types.Block, error) { 85 return ec.getBlock(ctx, "zond_getBlockByHash", hash, true) 86 } 87 88 // BlockByNumber returns a block from the current canonical chain. If number is nil, the 89 // latest known block is returned. 90 // 91 // Note that loading full blocks requires two requests. Use HeaderByNumber 92 // if you don't need all transactions. 93 func (ec *Client) BlockByNumber(ctx context.Context, number *big.Int) (*types.Block, error) { 94 return ec.getBlock(ctx, "zond_getBlockByNumber", toBlockNumArg(number), true) 95 } 96 97 // BlockNumber returns the most recent block number 98 func (ec *Client) BlockNumber(ctx context.Context) (uint64, error) { 99 var result hexutil.Uint64 100 err := ec.c.CallContext(ctx, &result, "zond_blockNumber") 101 return uint64(result), err 102 } 103 104 // PeerCount returns the number of p2p peers as reported by the net_peerCount method. 105 func (ec *Client) PeerCount(ctx context.Context) (uint64, error) { 106 var result hexutil.Uint64 107 err := ec.c.CallContext(ctx, &result, "net_peerCount") 108 return uint64(result), err 109 } 110 111 // BlockReceipts returns the receipts of a given block number or hash 112 func (ec *Client) BlockReceipts(ctx context.Context, blockNrOrHash rpc.BlockNumberOrHash) ([]*types.Receipt, error) { 113 var r []*types.Receipt 114 err := ec.c.CallContext(ctx, &r, "zond_getBlockReceipts", blockNrOrHash) 115 if err == nil && r == nil { 116 return nil, zond.NotFound 117 } 118 return r, err 119 } 120 121 type rpcBlock struct { 122 Hash common.Hash `json:"hash"` 123 Transactions []rpcTransaction `json:"transactions"` 124 Withdrawals []*types.Withdrawal `json:"withdrawals,omitempty"` 125 } 126 127 func (ec *Client) getBlock(ctx context.Context, method string, args ...interface{}) (*types.Block, error) { 128 var raw json.RawMessage 129 err := ec.c.CallContext(ctx, &raw, method, args...) 130 if err != nil { 131 return nil, err 132 } 133 134 // Decode header and transactions. 135 var head *types.Header 136 if err := json.Unmarshal(raw, &head); err != nil { 137 return nil, err 138 } 139 // When the block is not found, the API returns JSON null. 140 if head == nil { 141 return nil, zond.NotFound 142 } 143 144 var body rpcBlock 145 if err := json.Unmarshal(raw, &body); err != nil { 146 return nil, err 147 } 148 // Quick-verify transaction list. This mostly helps with debugging the server. 149 if head.TxHash == types.EmptyTxsHash && len(body.Transactions) > 0 { 150 return nil, errors.New("server returned non-empty transaction list but block header indicates no transactions") 151 } 152 if head.TxHash != types.EmptyTxsHash && len(body.Transactions) == 0 { 153 return nil, errors.New("server returned empty transaction list but block header indicates transactions") 154 } 155 // Fill the sender cache of transactions in the block. 156 txs := make([]*types.Transaction, len(body.Transactions)) 157 for i, tx := range body.Transactions { 158 if tx.From != nil { 159 setSenderFromServer(tx.tx, *tx.From, body.Hash) 160 } 161 txs[i] = tx.tx 162 } 163 return types.NewBlockWithHeader(head).WithBody( 164 types.Body{ 165 Transactions: txs, 166 Withdrawals: body.Withdrawals, 167 }), nil 168 } 169 170 // HeaderByHash returns the block header with the given hash. 171 func (ec *Client) HeaderByHash(ctx context.Context, hash common.Hash) (*types.Header, error) { 172 var head *types.Header 173 err := ec.c.CallContext(ctx, &head, "zond_getBlockByHash", hash, false) 174 if err == nil && head == nil { 175 err = zond.NotFound 176 } 177 return head, err 178 } 179 180 // HeaderByNumber returns a block header from the current canonical chain. If number is 181 // nil, the latest known header is returned. 182 func (ec *Client) HeaderByNumber(ctx context.Context, number *big.Int) (*types.Header, error) { 183 var head *types.Header 184 err := ec.c.CallContext(ctx, &head, "zond_getBlockByNumber", toBlockNumArg(number), false) 185 if err == nil && head == nil { 186 err = zond.NotFound 187 } 188 return head, err 189 } 190 191 type rpcTransaction struct { 192 tx *types.Transaction 193 txExtraInfo 194 } 195 196 type txExtraInfo struct { 197 BlockNumber *string `json:"blockNumber,omitempty"` 198 BlockHash *common.Hash `json:"blockHash,omitempty"` 199 From *common.Address `json:"from,omitempty"` 200 } 201 202 func (tx *rpcTransaction) UnmarshalJSON(msg []byte) error { 203 if err := json.Unmarshal(msg, &tx.tx); err != nil { 204 return err 205 } 206 return json.Unmarshal(msg, &tx.txExtraInfo) 207 } 208 209 // TransactionByHash returns the transaction with the given hash. 210 func (ec *Client) TransactionByHash(ctx context.Context, hash common.Hash) (tx *types.Transaction, isPending bool, err error) { 211 var json *rpcTransaction 212 err = ec.c.CallContext(ctx, &json, "zond_getTransactionByHash", hash) 213 if err != nil { 214 return nil, false, err 215 } else if json == nil { 216 return nil, false, zond.NotFound 217 } else if sig := json.tx.RawSignatureValue(); sig == nil { 218 return nil, false, errors.New("server returned transaction without signature") 219 } 220 if json.From != nil && json.BlockHash != nil { 221 setSenderFromServer(json.tx, *json.From, *json.BlockHash) 222 } 223 return json.tx, json.BlockNumber == nil, nil 224 } 225 226 // TransactionSender returns the sender address of the given transaction. The transaction 227 // must be known to the remote node and included in the blockchain at the given block and 228 // index. The sender is the one derived by the protocol at the time of inclusion. 229 // 230 // There is a fast-path for transactions retrieved by TransactionByHash and 231 // TransactionInBlock. Getting their sender address can be done without an RPC interaction. 232 func (ec *Client) TransactionSender(ctx context.Context, tx *types.Transaction, block common.Hash, index uint) (common.Address, error) { 233 // Try to load the address from the cache. 234 sender, err := types.Sender(&senderFromServer{blockhash: block}, tx) 235 if err == nil { 236 return sender, nil 237 } 238 239 // It was not found in cache, ask the server. 240 var meta struct { 241 Hash common.Hash 242 From common.Address 243 } 244 if err = ec.c.CallContext(ctx, &meta, "zond_getTransactionByBlockHashAndIndex", block, hexutil.Uint64(index)); err != nil { 245 return common.Address{}, err 246 } 247 if meta.Hash == (common.Hash{}) || meta.Hash != tx.Hash() { 248 return common.Address{}, errors.New("wrong inclusion block/index") 249 } 250 return meta.From, nil 251 } 252 253 // TransactionCount returns the total number of transactions in the given block. 254 func (ec *Client) TransactionCount(ctx context.Context, blockHash common.Hash) (uint, error) { 255 var num hexutil.Uint 256 err := ec.c.CallContext(ctx, &num, "zond_getBlockTransactionCountByHash", blockHash) 257 return uint(num), err 258 } 259 260 // TransactionInBlock returns a single transaction at index in the given block. 261 func (ec *Client) TransactionInBlock(ctx context.Context, blockHash common.Hash, index uint) (*types.Transaction, error) { 262 var json *rpcTransaction 263 err := ec.c.CallContext(ctx, &json, "zond_getTransactionByBlockHashAndIndex", blockHash, hexutil.Uint64(index)) 264 if err != nil { 265 return nil, err 266 } 267 if json == nil { 268 return nil, zond.NotFound 269 } else if sig := json.tx.RawSignatureValue(); sig == nil { 270 return nil, errors.New("server returned transaction without signature") 271 } 272 if json.From != nil && json.BlockHash != nil { 273 setSenderFromServer(json.tx, *json.From, *json.BlockHash) 274 } 275 return json.tx, err 276 } 277 278 // TransactionReceipt returns the receipt of a transaction by transaction hash. 279 // Note that the receipt is not available for pending transactions. 280 func (ec *Client) TransactionReceipt(ctx context.Context, txHash common.Hash) (*types.Receipt, error) { 281 var r *types.Receipt 282 err := ec.c.CallContext(ctx, &r, "zond_getTransactionReceipt", txHash) 283 if err == nil && r == nil { 284 return nil, zond.NotFound 285 } 286 return r, err 287 } 288 289 // SyncProgress retrieves the current progress of the sync algorithm. If there's 290 // no sync currently running, it returns nil. 291 func (ec *Client) SyncProgress(ctx context.Context) (*zond.SyncProgress, error) { 292 var raw json.RawMessage 293 if err := ec.c.CallContext(ctx, &raw, "zond_syncing"); err != nil { 294 return nil, err 295 } 296 // Handle the possible response types 297 var syncing bool 298 if err := json.Unmarshal(raw, &syncing); err == nil { 299 return nil, nil // Not syncing (always false) 300 } 301 var p *rpcProgress 302 if err := json.Unmarshal(raw, &p); err != nil { 303 return nil, err 304 } 305 return p.toSyncProgress(), nil 306 } 307 308 // SubscribeNewHead subscribes to notifications about the current blockchain head 309 // on the given channel. 310 func (ec *Client) SubscribeNewHead(ctx context.Context, ch chan<- *types.Header) (zond.Subscription, error) { 311 sub, err := ec.c.ZondSubscribe(ctx, ch, "newHeads") 312 if err != nil { 313 // Defensively prefer returning nil interface explicitly on error-path, instead 314 // of letting default golang behavior wrap it with non-nil interface that stores 315 // nil concrete type value. 316 return nil, err 317 } 318 return sub, nil 319 } 320 321 // State Access 322 323 // NetworkID returns the network ID for this client. 324 func (ec *Client) NetworkID(ctx context.Context) (*big.Int, error) { 325 version := new(big.Int) 326 var ver string 327 if err := ec.c.CallContext(ctx, &ver, "net_version"); err != nil { 328 return nil, err 329 } 330 if _, ok := version.SetString(ver, 10); !ok { 331 return nil, fmt.Errorf("invalid net_version result %q", ver) 332 } 333 return version, nil 334 } 335 336 // BalanceAt returns the wei balance of the given account. 337 // The block number can be nil, in which case the balance is taken from the latest known block. 338 func (ec *Client) BalanceAt(ctx context.Context, account common.Address, blockNumber *big.Int) (*big.Int, error) { 339 var result hexutil.Big 340 err := ec.c.CallContext(ctx, &result, "zond_getBalance", account, toBlockNumArg(blockNumber)) 341 return (*big.Int)(&result), err 342 } 343 344 // StorageAt returns the value of key in the contract storage of the given account. 345 // The block number can be nil, in which case the value is taken from the latest known block. 346 func (ec *Client) StorageAt(ctx context.Context, account common.Address, key common.Hash, blockNumber *big.Int) ([]byte, error) { 347 var result hexutil.Bytes 348 err := ec.c.CallContext(ctx, &result, "zond_getStorageAt", account, key, toBlockNumArg(blockNumber)) 349 return result, err 350 } 351 352 // CodeAt returns the contract code of the given account. 353 // The block number can be nil, in which case the code is taken from the latest known block. 354 func (ec *Client) CodeAt(ctx context.Context, account common.Address, blockNumber *big.Int) ([]byte, error) { 355 var result hexutil.Bytes 356 err := ec.c.CallContext(ctx, &result, "zond_getCode", account, toBlockNumArg(blockNumber)) 357 return result, err 358 } 359 360 // NonceAt returns the account nonce of the given account. 361 // The block number can be nil, in which case the nonce is taken from the latest known block. 362 func (ec *Client) NonceAt(ctx context.Context, account common.Address, blockNumber *big.Int) (uint64, error) { 363 var result hexutil.Uint64 364 err := ec.c.CallContext(ctx, &result, "zond_getTransactionCount", account, toBlockNumArg(blockNumber)) 365 return uint64(result), err 366 } 367 368 // Filters 369 370 // FilterLogs executes a filter query. 371 func (ec *Client) FilterLogs(ctx context.Context, q zond.FilterQuery) ([]types.Log, error) { 372 var result []types.Log 373 arg, err := toFilterArg(q) 374 if err != nil { 375 return nil, err 376 } 377 err = ec.c.CallContext(ctx, &result, "zond_getLogs", arg) 378 return result, err 379 } 380 381 // SubscribeFilterLogs subscribes to the results of a streaming filter query. 382 func (ec *Client) SubscribeFilterLogs(ctx context.Context, q zond.FilterQuery, ch chan<- types.Log) (zond.Subscription, error) { 383 arg, err := toFilterArg(q) 384 if err != nil { 385 return nil, err 386 } 387 sub, err := ec.c.ZondSubscribe(ctx, ch, "logs", arg) 388 if err != nil { 389 // Defensively prefer returning nil interface explicitly on error-path, instead 390 // of letting default golang behavior wrap it with non-nil interface that stores 391 // nil concrete type value. 392 return nil, err 393 } 394 return sub, nil 395 } 396 397 func toFilterArg(q zond.FilterQuery) (interface{}, error) { 398 arg := map[string]interface{}{ 399 "address": q.Addresses, 400 "topics": q.Topics, 401 } 402 if q.BlockHash != nil { 403 arg["blockHash"] = *q.BlockHash 404 if q.FromBlock != nil || q.ToBlock != nil { 405 return nil, errors.New("cannot specify both BlockHash and FromBlock/ToBlock") 406 } 407 } else { 408 if q.FromBlock == nil { 409 arg["fromBlock"] = "0x0" 410 } else { 411 arg["fromBlock"] = toBlockNumArg(q.FromBlock) 412 } 413 arg["toBlock"] = toBlockNumArg(q.ToBlock) 414 } 415 return arg, nil 416 } 417 418 // Pending State 419 420 // PendingBalanceAt returns the wei balance of the given account in the pending state. 421 func (ec *Client) PendingBalanceAt(ctx context.Context, account common.Address) (*big.Int, error) { 422 var result hexutil.Big 423 err := ec.c.CallContext(ctx, &result, "zond_getBalance", account, "pending") 424 return (*big.Int)(&result), err 425 } 426 427 // PendingStorageAt returns the value of key in the contract storage of the given account in the pending state. 428 func (ec *Client) PendingStorageAt(ctx context.Context, account common.Address, key common.Hash) ([]byte, error) { 429 var result hexutil.Bytes 430 err := ec.c.CallContext(ctx, &result, "zond_getStorageAt", account, key, "pending") 431 return result, err 432 } 433 434 // PendingCodeAt returns the contract code of the given account in the pending state. 435 func (ec *Client) PendingCodeAt(ctx context.Context, account common.Address) ([]byte, error) { 436 var result hexutil.Bytes 437 err := ec.c.CallContext(ctx, &result, "zond_getCode", account, "pending") 438 return result, err 439 } 440 441 // PendingNonceAt returns the account nonce of the given account in the pending state. 442 // This is the nonce that should be used for the next transaction. 443 func (ec *Client) PendingNonceAt(ctx context.Context, account common.Address) (uint64, error) { 444 var result hexutil.Uint64 445 err := ec.c.CallContext(ctx, &result, "zond_getTransactionCount", account, "pending") 446 return uint64(result), err 447 } 448 449 // PendingTransactionCount returns the total number of transactions in the pending state. 450 func (ec *Client) PendingTransactionCount(ctx context.Context) (uint, error) { 451 var num hexutil.Uint 452 err := ec.c.CallContext(ctx, &num, "zond_getBlockTransactionCountByNumber", "pending") 453 return uint(num), err 454 } 455 456 // Contract Calling 457 458 // CallContract executes a message call transaction, which is directly executed in the VM 459 // of the node, but never mined into the blockchain. 460 // 461 // blockNumber selects the block height at which the call runs. It can be nil, in which 462 // case the code is taken from the latest known block. Note that state from very old 463 // blocks might not be available. 464 func (ec *Client) CallContract(ctx context.Context, msg zond.CallMsg, blockNumber *big.Int) ([]byte, error) { 465 var hex hexutil.Bytes 466 err := ec.c.CallContext(ctx, &hex, "zond_call", toCallArg(msg), toBlockNumArg(blockNumber)) 467 if err != nil { 468 return nil, err 469 } 470 return hex, nil 471 } 472 473 // CallContractAtHash is almost the same as CallContract except that it selects 474 // the block by block hash instead of block height. 475 func (ec *Client) CallContractAtHash(ctx context.Context, msg zond.CallMsg, blockHash common.Hash) ([]byte, error) { 476 var hex hexutil.Bytes 477 err := ec.c.CallContext(ctx, &hex, "zond_call", toCallArg(msg), rpc.BlockNumberOrHashWithHash(blockHash, false)) 478 if err != nil { 479 return nil, err 480 } 481 return hex, nil 482 } 483 484 // PendingCallContract executes a message call transaction using the ZVM. 485 // The state seen by the contract call is the pending state. 486 func (ec *Client) PendingCallContract(ctx context.Context, msg zond.CallMsg) ([]byte, error) { 487 var hex hexutil.Bytes 488 err := ec.c.CallContext(ctx, &hex, "zond_call", toCallArg(msg), "pending") 489 if err != nil { 490 return nil, err 491 } 492 return hex, nil 493 } 494 495 // SuggestGasPrice retrieves the currently suggested gas price to allow a timely 496 // execution of a transaction. 497 func (zc *Client) SuggestGasPrice(ctx context.Context) (*big.Int, error) { 498 var hex hexutil.Big 499 if err := zc.c.CallContext(ctx, &hex, "zond_gasPrice"); err != nil { 500 return nil, err 501 } 502 return (*big.Int)(&hex), nil 503 } 504 505 // SuggestGasTipCap retrieves the currently suggested gas tip cap to 506 // allow a timely execution of a transaction. 507 func (ec *Client) SuggestGasTipCap(ctx context.Context) (*big.Int, error) { 508 var hex hexutil.Big 509 if err := ec.c.CallContext(ctx, &hex, "zond_maxPriorityFeePerGas"); err != nil { 510 return nil, err 511 } 512 return (*big.Int)(&hex), nil 513 } 514 515 type feeHistoryResultMarshaling struct { 516 OldestBlock *hexutil.Big `json:"oldestBlock"` 517 Reward [][]*hexutil.Big `json:"reward,omitempty"` 518 BaseFee []*hexutil.Big `json:"baseFeePerGas,omitempty"` 519 GasUsedRatio []float64 `json:"gasUsedRatio"` 520 } 521 522 // FeeHistory retrieves the fee market history. 523 func (ec *Client) FeeHistory(ctx context.Context, blockCount uint64, lastBlock *big.Int, rewardPercentiles []float64) (*zond.FeeHistory, error) { 524 var res feeHistoryResultMarshaling 525 if err := ec.c.CallContext(ctx, &res, "zond_feeHistory", hexutil.Uint(blockCount), toBlockNumArg(lastBlock), rewardPercentiles); err != nil { 526 return nil, err 527 } 528 reward := make([][]*big.Int, len(res.Reward)) 529 for i, r := range res.Reward { 530 reward[i] = make([]*big.Int, len(r)) 531 for j, r := range r { 532 reward[i][j] = (*big.Int)(r) 533 } 534 } 535 baseFee := make([]*big.Int, len(res.BaseFee)) 536 for i, b := range res.BaseFee { 537 baseFee[i] = (*big.Int)(b) 538 } 539 return &zond.FeeHistory{ 540 OldestBlock: (*big.Int)(res.OldestBlock), 541 Reward: reward, 542 BaseFee: baseFee, 543 GasUsedRatio: res.GasUsedRatio, 544 }, nil 545 } 546 547 // EstimateGas tries to estimate the gas needed to execute a specific transaction based on 548 // the current pending state of the backend blockchain. There is no guarantee that this is 549 // the true gas limit requirement as other transactions may be added or removed by miners, 550 // but it should provide a basis for setting a reasonable default. 551 func (ec *Client) EstimateGas(ctx context.Context, msg zond.CallMsg) (uint64, error) { 552 var hex hexutil.Uint64 553 err := ec.c.CallContext(ctx, &hex, "zond_estimateGas", toCallArg(msg)) 554 if err != nil { 555 return 0, err 556 } 557 return uint64(hex), nil 558 } 559 560 // SendTransaction injects a signed transaction into the pending pool for execution. 561 // 562 // If the transaction was a contract creation use the TransactionReceipt method to get the 563 // contract address after the transaction has been mined. 564 func (ec *Client) SendTransaction(ctx context.Context, tx *types.Transaction) error { 565 data, err := tx.MarshalBinary() 566 if err != nil { 567 return err 568 } 569 return ec.c.CallContext(ctx, nil, "zond_sendRawTransaction", hexutil.Encode(data)) 570 } 571 572 func toBlockNumArg(number *big.Int) string { 573 if number == nil { 574 return "latest" 575 } 576 if number.Sign() >= 0 { 577 return hexutil.EncodeBig(number) 578 } 579 // It's negative. 580 if number.IsInt64() { 581 return rpc.BlockNumber(number.Int64()).String() 582 } 583 // It's negative and large, which is invalid. 584 return fmt.Sprintf("<invalid %d>", number) 585 } 586 587 func toCallArg(msg zond.CallMsg) interface{} { 588 arg := map[string]interface{}{ 589 "from": msg.From, 590 "to": msg.To, 591 } 592 if len(msg.Data) > 0 { 593 arg["input"] = hexutil.Bytes(msg.Data) 594 } 595 if msg.Value != nil { 596 arg["value"] = (*hexutil.Big)(msg.Value) 597 } 598 if msg.Gas != 0 { 599 arg["gas"] = hexutil.Uint64(msg.Gas) 600 } 601 if msg.GasFeeCap != nil { 602 arg["maxFeePerGas"] = (*hexutil.Big)(msg.GasFeeCap) 603 } 604 if msg.GasTipCap != nil { 605 arg["maxPriorityFeePerGas"] = (*hexutil.Big)(msg.GasTipCap) 606 } 607 if msg.AccessList != nil { 608 arg["accessList"] = msg.AccessList 609 } 610 return arg 611 } 612 613 // rpcProgress is a copy of SyncProgress with hex-encoded fields. 614 type rpcProgress struct { 615 StartingBlock hexutil.Uint64 616 CurrentBlock hexutil.Uint64 617 HighestBlock hexutil.Uint64 618 619 PulledStates hexutil.Uint64 620 KnownStates hexutil.Uint64 621 622 SyncedAccounts hexutil.Uint64 623 SyncedAccountBytes hexutil.Uint64 624 SyncedBytecodes hexutil.Uint64 625 SyncedBytecodeBytes hexutil.Uint64 626 SyncedStorage hexutil.Uint64 627 SyncedStorageBytes hexutil.Uint64 628 HealedTrienodes hexutil.Uint64 629 HealedTrienodeBytes hexutil.Uint64 630 HealedBytecodes hexutil.Uint64 631 HealedBytecodeBytes hexutil.Uint64 632 HealingTrienodes hexutil.Uint64 633 HealingBytecode hexutil.Uint64 634 } 635 636 func (p *rpcProgress) toSyncProgress() *zond.SyncProgress { 637 if p == nil { 638 return nil 639 } 640 return &zond.SyncProgress{ 641 StartingBlock: uint64(p.StartingBlock), 642 CurrentBlock: uint64(p.CurrentBlock), 643 HighestBlock: uint64(p.HighestBlock), 644 PulledStates: uint64(p.PulledStates), 645 KnownStates: uint64(p.KnownStates), 646 SyncedAccounts: uint64(p.SyncedAccounts), 647 SyncedAccountBytes: uint64(p.SyncedAccountBytes), 648 SyncedBytecodes: uint64(p.SyncedBytecodes), 649 SyncedBytecodeBytes: uint64(p.SyncedBytecodeBytes), 650 SyncedStorage: uint64(p.SyncedStorage), 651 SyncedStorageBytes: uint64(p.SyncedStorageBytes), 652 HealedTrienodes: uint64(p.HealedTrienodes), 653 HealedTrienodeBytes: uint64(p.HealedTrienodeBytes), 654 HealedBytecodes: uint64(p.HealedBytecodes), 655 HealedBytecodeBytes: uint64(p.HealedBytecodeBytes), 656 HealingTrienodes: uint64(p.HealingTrienodes), 657 HealingBytecode: uint64(p.HealingBytecode), 658 } 659 }