Skip to content

Commit 11ba79a

Browse files
authored
Merge branch 'master' into clang-cross-compile
2 parents e99be0f + b1231f3 commit 11ba79a

File tree

6 files changed

+122
-16
lines changed

6 files changed

+122
-16
lines changed

beacon-chain/core/state/transition.go

+4-4
Original file line numberDiff line numberDiff line change
@@ -176,7 +176,7 @@ func CalculateStateRoot(
176176
}
177177

178178
// Execute per block transition.
179-
state, err = computeStateRoot(ctx, state, signed)
179+
state, err = ProcessBlockForStateRoot(ctx, state, signed)
180180
if err != nil {
181181
return [32]byte{}, errors.Wrap(err, "could not process block")
182182
}
@@ -640,9 +640,9 @@ func ProcessEpochPrecompute(ctx context.Context, state *stateTrie.BeaconState) (
640640
return state, nil
641641
}
642642

643-
// computeStateRoot computes the state root of the block without verifying proposer signature
644-
// and randao.
645-
func computeStateRoot(
643+
// ProcessBlockForStateRoot processes the state for state root computation. It skips proposer signature
644+
// and randao signature verifications.
645+
func ProcessBlockForStateRoot(
646646
ctx context.Context,
647647
state *stateTrie.BeaconState,
648648
signed *ethpb.SignedBeaconBlock,

beacon-chain/core/state/transition_fuzz_test.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -187,7 +187,7 @@ func TestFuzzProcessEpochPrecompute_1000(t *testing.T) {
187187
}
188188
}
189189

190-
func TestFuzzcomputeStateRoot_1000(t *testing.T) {
190+
func TestFuzzProcessBlockForStateRoot_1000(t *testing.T) {
191191
ctx := context.Background()
192192
state := &stateTrie.BeaconState{}
193193
sb := &ethpb.SignedBeaconBlock{}
@@ -196,7 +196,7 @@ func TestFuzzcomputeStateRoot_1000(t *testing.T) {
196196
for i := 0; i < 1000; i++ {
197197
fuzzer.Fuzz(state)
198198
fuzzer.Fuzz(sb)
199-
s, err := computeStateRoot(ctx, state, sb)
199+
s, err := ProcessBlockForStateRoot(ctx, state, sb)
200200
if err != nil && s != nil {
201201
t.Fatalf("state should be nil on err. found: %v on error: %v for signed block: %v", s, err, sb)
202202
}

beacon-chain/stategen/BUILD.bazel

+3
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,10 @@ go_library(
1414
"//beacon-chain/db/filters:go_default_library",
1515
"//beacon-chain/state:go_default_library",
1616
"//shared/bytesutil:go_default_library",
17+
"//shared/featureconfig:go_default_library",
18+
"@com_github_pkg_errors//:go_default_library",
1719
"@com_github_prysmaticlabs_ethereumapis//eth/v1alpha1:go_default_library",
20+
"@io_opencensus_go//trace:go_default_library",
1821
],
1922
)
2023

beacon-chain/stategen/replay.go

+99-7
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,17 @@ package stategen
22

33
import (
44
"context"
5-
"errors"
5+
"fmt"
66

7+
"github.com/pkg/errors"
78
ethpb "github.com/prysmaticlabs/ethereumapis/eth/v1alpha1"
89
transition "github.com/prysmaticlabs/prysm/beacon-chain/core/state"
910
"github.com/prysmaticlabs/prysm/beacon-chain/db/filters"
1011
"github.com/prysmaticlabs/prysm/beacon-chain/state"
12+
stateTrie "github.com/prysmaticlabs/prysm/beacon-chain/state"
1113
"github.com/prysmaticlabs/prysm/shared/bytesutil"
14+
"github.com/prysmaticlabs/prysm/shared/featureconfig"
15+
"go.opencensus.io/trace"
1216
)
1317

1418
// ReplayBlocks replays the input blocks on the input state until the target slot is reached.
@@ -17,17 +21,31 @@ func (s *State) ReplayBlocks(ctx context.Context, state *state.BeaconState, sign
1721
// The input block list is sorted in decreasing slots order.
1822
if len(signed) > 0 {
1923
for i := len(signed) - 1; i >= 0; i-- {
20-
state, err = transition.ExecuteStateTransitionNoVerifyAttSigs(ctx, state, signed[i])
21-
if err != nil {
22-
return nil, err
24+
if featureconfig.Get().EnableStateGenSigVerify {
25+
state, err = transition.ExecuteStateTransition(ctx, state, signed[i])
26+
if err != nil {
27+
return nil, err
28+
}
29+
} else {
30+
state, err = executeStateTransitionStateGen(ctx, state, signed[i])
31+
if err != nil {
32+
return nil, err
33+
}
2334
}
2435
}
2536
}
2637

2738
// If there is skip slots at the end.
28-
state, err = transition.ProcessSlots(ctx, state, targetSlot)
29-
if err != nil {
30-
return nil, err
39+
if featureconfig.Get().EnableStateGenSigVerify {
40+
state, err = transition.ProcessSlots(ctx, state, targetSlot)
41+
if err != nil {
42+
return nil, err
43+
}
44+
} else {
45+
state, err = processSlotsStateGen(ctx, state, targetSlot)
46+
if err != nil {
47+
return nil, err
48+
}
3149
}
3250

3351
return state, nil
@@ -78,3 +96,77 @@ func (s *State) LoadBlocks(ctx context.Context, startSlot uint64, endSlot uint64
7896

7997
return filteredBlocks, nil
8098
}
99+
100+
// executeStateTransitionStateGen applies state transition on input historical state and block for state gen usages.
101+
// There's no signature verification involved given state gen only works with stored block and state in DB.
102+
// If the objects are already in stored in DB, one can omit redundant signature checks and ssz hashing calculations.
103+
// WARNING: This method should not be used on an unverified new block.
104+
func executeStateTransitionStateGen(
105+
ctx context.Context,
106+
state *stateTrie.BeaconState,
107+
signed *ethpb.SignedBeaconBlock,
108+
) (*stateTrie.BeaconState, error) {
109+
if ctx.Err() != nil {
110+
return nil, ctx.Err()
111+
}
112+
if signed == nil || signed.Block == nil {
113+
return nil, errors.New("nil block")
114+
}
115+
116+
ctx, span := trace.StartSpan(ctx, "beacon-chain.ChainService.ExecuteStateTransitionStateGen")
117+
defer span.End()
118+
var err error
119+
120+
// Execute per slots transition.
121+
// Given this is for state gen, a node uses the version process slots without skip slots cache.
122+
state, err = processSlotsStateGen(ctx, state, signed.Block.Slot)
123+
if err != nil {
124+
return nil, errors.Wrap(err, "could not process slot")
125+
}
126+
127+
// Execute per block transition.
128+
// Given this is for state gen, a node only cares about the post state without proposer
129+
// and randao signature verifications.
130+
state, err = transition.ProcessBlockForStateRoot(ctx, state, signed)
131+
if err != nil {
132+
return nil, errors.Wrap(err, "could not process block")
133+
}
134+
135+
return state, nil
136+
}
137+
138+
// processSlotsStateGen to process old slots for state gen usages.
139+
// There's no skip slot cache involved given state gen only works with already stored block and state in DB.
140+
// WARNING: This method should not be used for future slot.
141+
func processSlotsStateGen(ctx context.Context, state *stateTrie.BeaconState, slot uint64) (*stateTrie.BeaconState, error) {
142+
ctx, span := trace.StartSpan(ctx, "beacon-chain.ChainService.ProcessSlotsStateGen")
143+
defer span.End()
144+
if state == nil {
145+
return nil, errors.New("nil state")
146+
}
147+
148+
if state.Slot() > slot {
149+
err := fmt.Errorf("expected state.slot %d < slot %d", state.Slot(), slot)
150+
return nil, err
151+
}
152+
153+
if state.Slot() == slot {
154+
return state, nil
155+
}
156+
157+
for state.Slot() < slot {
158+
state, err := transition.ProcessSlot(ctx, state)
159+
if err != nil {
160+
return nil, errors.Wrap(err, "could not process slot")
161+
}
162+
if transition.CanProcessEpoch(state) {
163+
state, err = transition.ProcessEpochPrecompute(ctx, state)
164+
if err != nil {
165+
return nil, errors.Wrap(err, "could not process epoch with optimizations")
166+
}
167+
}
168+
state.SetSlot(state.Slot() + 1)
169+
}
170+
171+
return state, nil
172+
}

shared/featureconfig/config.go

+5-1
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ type Flags struct {
4343
DisableUpdateHeadPerAttestation bool // DisableUpdateHeadPerAttestation will disabling update head on per attestation basis.
4444
EnableByteMempool bool // EnaableByteMempool memory management.
4545
EnableDomainDataCache bool // EnableDomainDataCache caches validator calls to DomainData per epoch.
46+
EnableStateGenSigVerify bool // EnableStateGenSigVerify verifies proposer and randao signatures during state gen.
4647

4748
// DisableForkChoice disables using LMD-GHOST fork choice to update
4849
// the head of the chain based on attestations and instead accepts any valid received block
@@ -144,7 +145,10 @@ func ConfigureBeaconChain(ctx *cli.Context) {
144145
log.Warn("Enabling experimental memory management for beacon state")
145146
cfg.EnableByteMempool = true
146147
}
147-
148+
if ctx.GlobalBool(enableStateGenSigVerify.Name) {
149+
log.Warn("Enabling sig verify for state gen")
150+
cfg.EnableStateGenSigVerify = true
151+
}
148152
Init(cfg)
149153
}
150154

shared/featureconfig/flags.go

+9-2
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,11 @@ var (
9797
Usage: "Enable caching of domain data requests per epoch. This feature reduces the total " +
9898
"calls to the beacon node for each assignment.",
9999
}
100+
enableStateGenSigVerify = cli.BoolFlag{
101+
Name: "enable-state-gen-sig-verify",
102+
Usage: "Enable signature verification for state gen. This feature increases the cost to generate a historical state," +
103+
"the resulting state is signature verified.",
104+
}
100105
)
101106

102107
// Deprecated flags list.
@@ -205,8 +210,8 @@ var (
205210
Hidden: true,
206211
}
207212
deprecatedInitSyncCacheStateFlag = cli.BoolFlag{
208-
Name: "initial-sync-cache-state",
209-
Usage: deprecatedUsage,
213+
Name: "initial-sync-cache-state",
214+
Usage: deprecatedUsage,
210215
Hidden: true,
211216
}
212217
)
@@ -268,6 +273,7 @@ var BeaconChainFlags = append(deprecatedFlags, []cli.Flag{
268273
disableStrictAttestationPubsubVerificationFlag,
269274
disableUpdateHeadPerAttestation,
270275
enableByteMempool,
276+
enableStateGenSigVerify,
271277
}...)
272278

273279
// E2EBeaconChainFlags contains a list of the beacon chain feature flags to be tested in E2E.
@@ -279,4 +285,5 @@ var E2EBeaconChainFlags = []string{
279285
"--enable-eth1-data-vote-cache",
280286
"--proto-array-forkchoice",
281287
"--enable-byte-mempool",
288+
"--enable-state-gen-sig-verify",
282289
}

0 commit comments

Comments
 (0)