package commands import ( "context" "fmt" "math/big" "github.com/holiman/uint256" "github.com/ledgerwatch/erigon/common/hexutil" "github.com/ledgerwatch/erigon/consensus/ethash" "github.com/ledgerwatch/erigon/core/rawdb" "github.com/ledgerwatch/erigon/rpc" ) // BlockReward returns the block reward for this block // func (api *ErigonImpl) BlockReward(ctx context.Context, blockNr rpc.BlockNumber) (Issuance, error) { // tx, err := api.db.Begin(ctx, ethdb.RO) // if err != nil { // return Issuance{}, err // } // defer tx.Rollback() // // return api.rewardCalc(tx, blockNr, "block") // nolint goconst //} // UncleReward returns the uncle reward for this block // func (api *ErigonImpl) UncleReward(ctx context.Context, blockNr rpc.BlockNumber) (Issuance, error) { // tx, err := api.db.Begin(ctx, ethdb.RO) // if err != nil { // return Issuance{}, err // } // defer tx.Rollback() // // return api.rewardCalc(tx, blockNr, "uncle") // nolint goconst //} // Issuance implements erigon_issuance. Returns the total issuance (block reward plus uncle reward) for the given block. func (api *ErigonImpl) WatchTheBurn(ctx context.Context, blockNr rpc.BlockNumber) (Issuance, error) { tx, err := api.db.BeginRo(ctx) if err != nil { return Issuance{}, err } defer tx.Rollback() chainConfig, err := api.chainConfig(tx) if err != nil { return Issuance{}, err } if chainConfig.Ethash == nil { // Clique for example has no issuance return Issuance{}, nil } header, err := api._blockReader.HeaderByNumber(ctx, tx, uint64(blockNr)) if err != nil { return Issuance{}, err } body, _, err := api._blockReader.Body(ctx, tx, header.Hash(), uint64(blockNr)) if err != nil { return Issuance{}, err } if body == nil { return Issuance{}, fmt.Errorf("could not find block body") } minerReward, uncleRewards := ethash.AccumulateRewards(chainConfig, header, body.Uncles) issuance := minerReward for _, r := range uncleRewards { p := r // avoids warning? issuance.Add(&issuance, &p) } var ret Issuance ret.BlockReward = (*hexutil.Big)(minerReward.ToBig()) ret.Issuance = (*hexutil.Big)(issuance.ToBig()) issuance.Sub(&issuance, &minerReward) ret.UncleReward = (*hexutil.Big)(issuance.ToBig()) // Compute how much was burnt if header.BaseFee != nil { burnt := header.BaseFee burnt.Mul(burnt, big.NewInt(int64(header.GasUsed))) ret.Burnt = (*hexutil.Big)(burnt) } else { ret.Burnt = (*hexutil.Big)(big.NewInt(0)) } // Compute totalIssued, totalBurnt and the supply of eth totalIssued, err := rawdb.ReadTotalIssued(tx, uint64(blockNr)) if err != nil { return Issuance{}, err } totalBurnt, err := rawdb.ReadTotalBurnt(tx, uint64(blockNr)) if err != nil { return Issuance{}, err } ret.TotalIssued = (*hexutil.Big)(totalIssued) ret.TotalBurnt = (*hexutil.Big)(totalBurnt) // Compute tips tips := big.NewInt(0) if header.BaseFee != nil { receipts, err := rawdb.ReadReceiptsByHash(tx, header.Hash()) if err != nil { return Issuance{}, err } baseFee, overflow := uint256.FromBig(header.BaseFee) if overflow { return Issuance{}, fmt.Errorf("baseFee overflow") } for i, transaction := range body.Transactions { tip := transaction.GetEffectiveGasTip(baseFee).ToBig() tips.Add(tips, tip.Mul(tip, big.NewInt(int64(receipts[i].GasUsed)))) } } ret.Tips = (*hexutil.Big)(tips) return ret, nil } // Issuance structure to return information about issuance type Issuance struct { BlockReward *hexutil.Big `json:"blockReward"` // Block reward for given block UncleReward *hexutil.Big `json:"uncleReward"` // Uncle reward for gived block Issuance *hexutil.Big `json:"issuance"` // Total amount of wei created in the block Burnt *hexutil.Big `json:"burnt"` // Total amount of wei burned in the block TotalIssued *hexutil.Big `json:"totalIssued"` // Total amount of wei created in total so far TotalBurnt *hexutil.Big `json:"totalBurnt"` // Total amount of wei burnt so far Tips *hexutil.Big `json:"tips"` // Total Tips generated by the block }