From d2cf49327f3d083e6e4eec0c747a8683f7c7b97f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?P=C3=A9ter=20Szil=C3=A1gyi?= Date: Tue, 4 Apr 2023 11:25:28 +0300 Subject: [PATCH] consensus/misc, params: add EIP-4844 blobfee conversions (#27041) * consensus/misc, params: add EIP-4844 blobfee conversions * consensus/misc: pull in fakeExponential test cases * consensus/misc: reuse bigints * consensus/misc: nit renames, additional larger testcase --------- Co-authored-by: Roberto Bayardo Co-authored-by: Martin Holst Swende --- consensus/misc/eip4844.go | 54 +++++++++++++++++++++ consensus/misc/eip4844_test.go | 85 ++++++++++++++++++++++++++++++++++ params/protocol_params.go | 3 ++ 3 files changed, 142 insertions(+) create mode 100644 consensus/misc/eip4844.go create mode 100644 consensus/misc/eip4844_test.go diff --git a/consensus/misc/eip4844.go b/consensus/misc/eip4844.go new file mode 100644 index 000000000..66ca9bd26 --- /dev/null +++ b/consensus/misc/eip4844.go @@ -0,0 +1,54 @@ +// Copyright 2023 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package misc + +import ( + "math/big" + + "github.com/ethereum/go-ethereum/params" +) + +var ( + minDataGasPrice = big.NewInt(params.BlobTxMinDataGasprice) + dataGaspriceUpdateFraction = big.NewInt(params.BlobTxDataGaspriceUpdateFraction) +) + +// CalcBlobFee calculates the blobfee from the header's excess data gas field. +func CalcBlobFee(excessDataGas *big.Int) *big.Int { + // If this block does not yet have EIP-4844 enabled, return the starting fee + if excessDataGas == nil { + return big.NewInt(params.BlobTxMinDataGasprice) + } + return fakeExponential(minDataGasPrice, excessDataGas, dataGaspriceUpdateFraction) +} + +// fakeExponential approximates factor * e ** (numerator / denominator) using +// Taylor expansion. +func fakeExponential(factor, numerator, denominator *big.Int) *big.Int { + var ( + output = new(big.Int) + accum = new(big.Int).Mul(factor, denominator) + ) + for i := 1; accum.Sign() > 0; i++ { + output.Add(output, accum) + + accum.Mul(accum, numerator) + accum.Div(accum, denominator) + accum.Div(accum, big.NewInt(int64(i))) + } + return output.Div(output, denominator) +} diff --git a/consensus/misc/eip4844_test.go b/consensus/misc/eip4844_test.go new file mode 100644 index 000000000..5838cab8e --- /dev/null +++ b/consensus/misc/eip4844_test.go @@ -0,0 +1,85 @@ +// Copyright 2023 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package misc + +import ( + "fmt" + "math/big" + "testing" + + "github.com/ethereum/go-ethereum/params" +) + +func TestCalcBlobFee(t *testing.T) { + tests := []struct { + excessDataGas int64 + blobfee int64 + }{ + {0, 1}, + {1542706, 1}, + {1542707, 2}, + {10 * 1024 * 1024, 111}, + } + have := CalcBlobFee(nil) + if have.Int64() != params.BlobTxMinDataGasprice { + t.Errorf("nil test: blobfee mismatch: have %v, want %v", have, params.BlobTxMinDataGasprice) + } + for i, tt := range tests { + have := CalcBlobFee(big.NewInt(tt.excessDataGas)) + if have.Int64() != tt.blobfee { + t.Errorf("test %d: blobfee mismatch: have %v want %v", i, have, tt.blobfee) + } + } +} + +func TestFakeExponential(t *testing.T) { + tests := []struct { + factor int64 + numerator int64 + denominator int64 + want int64 + }{ + // When numerator == 0 the return value should always equal the value of factor + {1, 0, 1, 1}, + {38493, 0, 1000, 38493}, + {0, 1234, 2345, 0}, // should be 0 + {1, 2, 1, 6}, // approximate 7.389 + {1, 4, 2, 6}, + {1, 3, 1, 16}, // approximate 20.09 + {1, 6, 2, 18}, + {1, 4, 1, 49}, // approximate 54.60 + {1, 8, 2, 50}, + {10, 8, 2, 542}, // approximate 540.598 + {11, 8, 2, 596}, // approximate 600.58 + {1, 5, 1, 136}, // approximate 148.4 + {1, 5, 2, 11}, // approximate 12.18 + {2, 5, 2, 23}, // approximate 24.36 + {1, 50000000, 2225652, 5709098764}, + } + for i, tt := range tests { + f, n, d := big.NewInt(tt.factor), big.NewInt(tt.numerator), big.NewInt(tt.denominator) + original := fmt.Sprintf("%d %d %d", f, n, d) + have := fakeExponential(f, n, d) + if have.Int64() != tt.want { + t.Errorf("test %d: fake exponential mismatch: have %v want %v", i, have, tt.want) + } + later := fmt.Sprintf("%d %d %d", f, n, d) + if original != later { + t.Errorf("test %d: fake exponential modified arguments: have\n%v\nwant\n%v", i, later, original) + } + } +} diff --git a/params/protocol_params.go b/params/protocol_params.go index bb703d0b7..ab5ed13c0 100644 --- a/params/protocol_params.go +++ b/params/protocol_params.go @@ -159,6 +159,9 @@ const ( // up to half the consumed gas could be refunded. Redefined as 1/5th in EIP-3529 RefundQuotient uint64 = 2 RefundQuotientEIP3529 uint64 = 5 + + BlobTxMinDataGasprice = 1 // Minimum gas price for data blobs + BlobTxDataGaspriceUpdateFraction = 2225652 // Controls the maximum rate of change for data gas price ) // Gas discount table for BLS12-381 G1 and G2 multi exponentiation operations