Correctly use Gwei to compare builder bid value (#12290)

* Correctly use Gwei to compare builder bid value

* Minimal 1gwei for TestProduceBlindedBlock

---------

Co-authored-by: terence tsao <terence@prysmaticlabs.com>
This commit is contained in:
Potuz 2023-04-16 05:47:51 -03:00 committed by GitHub
parent c09977d8a8
commit 191b0c4652
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 122 additions and 4 deletions

View File

@ -2751,6 +2751,7 @@ func TestProduceBlindedBlock(t *testing.T) {
require.NoError(t, err)
wr, err := ssz.WithdrawalSliceRoot(wds, fieldparams.MaxWithdrawalsPerPayload)
require.NoError(t, err)
v := big.NewInt(1e9) // minimal 1 gwei
bid := &ethpbalpha.BuilderBidCapella{
Header: &enginev1.ExecutionPayloadHeaderCapella{
ParentHash: make([]byte, fieldparams.RootLength),
@ -2767,7 +2768,7 @@ func TestProduceBlindedBlock(t *testing.T) {
WithdrawalsRoot: wr[:],
},
Pubkey: sk.PublicKey().Marshal(),
Value: bytesutil.PadTo([]byte{1, 2, 3}, 32),
Value: bytesutil.PadTo(bytesutil.ReverseByteOrder(v.Bytes()), 32),
}
d := params.BeaconConfig().DomainApplicationBuilder
domain, err := signing.ComputeDomain(d, nil, nil)

View File

@ -33,6 +33,8 @@ var builderGetPayloadMissCount = promauto.NewCounter(prometheus.CounterOpts{
Help: "The number of get payload misses for validator requests to builder",
})
var gweiPerEth = big.NewInt(int64(params.BeaconConfig().GweiPerEth))
// blockBuilderTimeout is the maximum amount of time allowed for a block builder to respond to a
// block request. This value is known as `BUILDER_PROPOSAL_DELAY_TOLERANCE` in builder spec.
const blockBuilderTimeout = 1 * time.Second
@ -65,12 +67,14 @@ func (vs *Server) setExecutionData(ctx context.Context, blk interfaces.SignedBea
if err != nil {
return errors.Wrap(err, "failed to get local payload value")
}
v.Div(v, gweiPerEth)
localValue := v.Uint64()
v, err = builderPayload.Value()
if err != nil {
log.WithError(err).Warn("Proposer: failed to get builder payload value") // Default to local if can't get builder value.
v = big.NewInt(0) // Default to local if can't get builder value.
}
v.Div(v, gweiPerEth)
builderValue := v.Uint64()
withdrawalsMatched, err := matchingWithdrawalsRoot(localPayload, builderPayload)
@ -96,7 +100,7 @@ func (vs *Server) setExecutionData(ctx context.Context, blk interfaces.SignedBea
if !higherValueBuilder {
log.WithFields(logrus.Fields{
"localGweiValue": localValue,
"localBoostPercentage": 100 + boost,
"localBoostPercentage": boost,
"builderGweiValue": builderValue,
}).Warn("Proposer: using local execution payload because higher value")
}

View File

@ -196,7 +196,7 @@ func TestServer_setExecutionData(t *testing.T) {
require.NoError(t, err)
require.Equal(t, uint64(3), e.BlockNumber()) // Local block
require.LogsContain(t, hook, "builderGweiValue=1000000000 localBoostPercentage=100 localGweiValue=2000000000")
require.LogsContain(t, hook, "builderGweiValue=1 localBoostPercentage=0 localGweiValue=2")
})
t.Run("Builder configured. Local block and boost has higher value", func(t *testing.T) {
cfg := params.BeaconConfig().Copy()
@ -211,7 +211,7 @@ func TestServer_setExecutionData(t *testing.T) {
require.NoError(t, err)
require.Equal(t, uint64(3), e.BlockNumber()) // Local block
require.LogsContain(t, hook, "builderGweiValue=1000000000 localBoostPercentage=101 localGweiValue=1000000000")
require.LogsContain(t, hook, "builderGweiValue=1 localBoostPercentage=1 localGweiValue=1")
})
t.Run("Builder configured. Builder returns fault. Use local block", func(t *testing.T) {
blk, err := blocks.NewSignedBeaconBlock(util.NewBeaconBlockCapella())
@ -228,6 +228,119 @@ func TestServer_setExecutionData(t *testing.T) {
})
}
// Regression #12289
func TestNoWeiOverflow(t *testing.T) {
hook := logTest.NewGlobal()
ctx := context.Background()
cfg := params.BeaconConfig().Copy()
cfg.BellatrixForkEpoch = 0
cfg.CapellaForkEpoch = 0
params.OverrideBeaconConfig(cfg)
params.SetupTestConfigCleanup(t)
beaconDB := dbTest.SetupDB(t)
capellaTransitionState, _ := util.DeterministicGenesisStateCapella(t, 1)
wrappedHeaderCapella, err := blocks.WrappedExecutionPayloadHeaderCapella(&v1.ExecutionPayloadHeaderCapella{BlockNumber: 1}, big.NewInt(0))
require.NoError(t, err)
require.NoError(t, capellaTransitionState.SetLatestExecutionPayloadHeader(wrappedHeaderCapella))
b2pbCapella := util.NewBeaconBlockCapella()
b2rCapella, err := b2pbCapella.Block.HashTreeRoot()
require.NoError(t, err)
util.SaveBlock(t, context.Background(), beaconDB, b2pbCapella)
require.NoError(t, capellaTransitionState.SetFinalizedCheckpoint(&ethpb.Checkpoint{
Root: b2rCapella[:],
}))
require.NoError(t, beaconDB.SaveFeeRecipientsByValidatorIDs(context.Background(), []primitives.ValidatorIndex{0}, []common.Address{{}}))
withdrawals := []*v1.Withdrawal{{
Index: 1,
ValidatorIndex: 2,
Address: make([]byte, fieldparams.FeeRecipientLength),
Amount: 3,
}}
id := &v1.PayloadIDBytes{0x1}
vs := &Server{
ExecutionEngineCaller: &powtesting.EngineClient{PayloadIDBytes: id, ExecutionPayloadCapella: &v1.ExecutionPayloadCapella{BlockNumber: 1, Withdrawals: withdrawals}, BlockValue: big.NewInt(18395081606530051)},
HeadFetcher: &blockchainTest.ChainService{State: capellaTransitionState},
FinalizationFetcher: &blockchainTest.ChainService{},
BeaconDB: beaconDB,
ProposerSlotIndexCache: cache.NewProposerPayloadIDsCache(),
BlockBuilder: &builderTest.MockBuilderService{HasConfigured: true},
}
blk, err := blocks.NewSignedBeaconBlock(util.NewBlindedBeaconBlockCapella())
require.NoError(t, err)
require.NoError(t, vs.BeaconDB.SaveRegistrationsByValidatorIDs(ctx, []primitives.ValidatorIndex{blk.Block().ProposerIndex()},
[]*ethpb.ValidatorRegistrationV1{{FeeRecipient: make([]byte, fieldparams.FeeRecipientLength), Pubkey: make([]byte, fieldparams.BLSPubkeyLength)}}))
ti, err := slots.ToTime(uint64(time.Now().Unix()), 0)
require.NoError(t, err)
sk, err := bls.RandKey()
require.NoError(t, err)
wr, err := ssz.WithdrawalSliceRoot(withdrawals, fieldparams.MaxWithdrawalsPerPayload)
require.NoError(t, err)
builderValue := bytesutil.ReverseByteOrder(big.NewInt(195513127666416350).Bytes())
bid := &ethpb.BuilderBidCapella{
Header: &v1.ExecutionPayloadHeaderCapella{
FeeRecipient: make([]byte, fieldparams.FeeRecipientLength),
StateRoot: make([]byte, fieldparams.RootLength),
ReceiptsRoot: make([]byte, fieldparams.RootLength),
LogsBloom: make([]byte, fieldparams.LogsBloomLength),
PrevRandao: make([]byte, fieldparams.RootLength),
BaseFeePerGas: make([]byte, fieldparams.RootLength),
BlockHash: make([]byte, fieldparams.RootLength),
TransactionsRoot: bytesutil.PadTo([]byte{1}, fieldparams.RootLength),
ParentHash: params.BeaconConfig().ZeroHash[:],
Timestamp: uint64(ti.Unix()),
BlockNumber: 2,
WithdrawalsRoot: wr[:],
},
Pubkey: sk.PublicKey().Marshal(),
Value: bytesutil.PadTo(builderValue, 32),
}
d := params.BeaconConfig().DomainApplicationBuilder
domain, err := signing.ComputeDomain(d, nil, nil)
require.NoError(t, err)
sr, err := signing.ComputeSigningRoot(bid, domain)
require.NoError(t, err)
sBid := &ethpb.SignedBuilderBidCapella{
Message: bid,
Signature: sk.Sign(sr[:]).Marshal(),
}
vs.BlockBuilder = &builderTest.MockBuilderService{
BidCapella: sBid,
HasConfigured: true,
}
wb, err := blocks.NewSignedBeaconBlock(util.NewBeaconBlockCapella())
require.NoError(t, err)
chain := &blockchainTest.ChainService{ForkChoiceStore: doublylinkedtree.New(), Genesis: time.Now(), Block: wb}
vs.ForkFetcher = chain
vs.ForkchoiceFetcher = chain
vs.ForkchoiceFetcher.SetForkChoiceGenesisTime(uint64(time.Now().Unix()))
vs.TimeFetcher = chain
vs.HeadFetcher = chain
require.NoError(t, vs.setExecutionData(context.Background(), blk, capellaTransitionState))
e, err := blk.Block().Body().Execution()
require.NoError(t, err)
require.Equal(t, uint64(2), e.BlockNumber()) // Builder block
t.Run("Boosted local block, no overflow", func(t *testing.T) {
cfg := params.BeaconConfig().Copy()
cfg.LocalBlockValueBoost = 20 // Boost 1%.
params.OverrideBeaconConfig(cfg)
blk, err := blocks.NewSignedBeaconBlock(util.NewBeaconBlockCapella())
require.NoError(t, err)
vs.ExecutionEngineCaller = &powtesting.EngineClient{PayloadIDBytes: id, ExecutionPayloadCapella: &v1.ExecutionPayloadCapella{BlockNumber: 3, Withdrawals: withdrawals}, BlockValue: big.NewInt(162927606e9)} // 0.16 ETH
require.NoError(t, vs.setExecutionData(context.Background(), blk, capellaTransitionState))
e, err := blk.Block().Body().Execution()
require.NoError(t, err)
require.Equal(t, uint64(3), e.BlockNumber()) // Local block
require.LogsContain(t, hook, "builderGweiValue=195513127 localBoostPercentage=20 localGweiValue=162927606")
})
}
func TestServer_getPayloadHeader(t *testing.T) {
params.SetupTestConfigCleanup(t)
bc := params.BeaconConfig()