Skip to content

Commit 4b7811a

Browse files
Merge branch 'master' into illia-malachyn/6635-tests-for-websocket-controller
2 parents f2fbcec + 541d744 commit 4b7811a

File tree

30 files changed

+2470
-80
lines changed

30 files changed

+2470
-80
lines changed

.github/workflows/builds.yml

Lines changed: 22 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,10 @@ on:
4343
type: boolean
4444
description: 'Build amd64 `without_adx` and `without_netgo_without_adx` images, and arm64 images'
4545
required: false
46+
private_build:
47+
type: boolean
48+
description: 'Build private images'
49+
required: false
4650

4751
jobs:
4852
# matrix_builder generates a matrix that includes the roles selected in the input
@@ -109,16 +113,30 @@ jobs:
109113
credentials_json: ${{ secrets.GCR_SERVICE_KEY_SECRET }}
110114
- name: Set up Google Cloud SDK
111115
uses: google-github-actions/setup-gcloud@v1
112-
- name: Authenticate docker with gcloud
116+
117+
- name: Authenticate Docker with gcloud
113118
run: |
114-
gcloud auth configure-docker
119+
if [[ "${{ github.event.inputs.private_build }}" == "true" ]]; then
120+
gcloud auth configure-docker us-central1-docker.pkg.dev
121+
else
122+
gcloud auth configure-docker
123+
fi
124+
125+
- name: Set CONTAINER_REGISTRY
126+
id: set-registry
127+
run: |
128+
if [[ "${{ github.event.inputs.private_build }}" == "true" ]]; then
129+
echo "CONTAINER_REGISTRY=${{ vars.PRIVATE_REGISTRY }}" >> $GITHUB_ENV
130+
else
131+
echo "CONTAINER_REGISTRY=${{ vars.PUBLIC_REGISTRY }}" >> $GITHUB_ENV
132+
fi
115133
116134
- name: Build/Push ${{ matrix.role }} amd64 images with adx (default)
117135
env:
118136
IMAGE_TAG: ${{ inputs.docker_tag }}
119137
CADENCE_DEPLOY_KEY: ${{ secrets.CADENCE_DEPLOY_KEY }}
120138
run: |
121-
make docker-build-${{ matrix.role }}-with-adx docker-push-${{ matrix.role }}-with-adx
139+
make docker-build-${{ matrix.role }}-with-adx docker-push-${{ matrix.role }}-with-adx CONTAINER_REGISTRY=$CONTAINER_REGISTRY
122140
123141
- name: Build/Push ${{ matrix.role }} amd64 images without netgo and without adx, arm64 images
124142
if: ${{ inputs.include_alternative_builds }}
@@ -128,7 +146,7 @@ jobs:
128146
run: |
129147
make docker-build-${{ matrix.role }}-without-adx docker-push-${{ matrix.role }}-without-adx \
130148
docker-build-${{ matrix.role }}-without-netgo-without-adx docker-push-${{ matrix.role }}-without-netgo-without-adx \
131-
docker-cross-build-${{ matrix.role }}-arm docker-push-${{ matrix.role }}-arm
149+
docker-cross-build-${{ matrix.role }}-arm docker-push-${{ matrix.role }}-arm CONTAINER_REGISTRY=$CONTAINER_REGISTRY
132150
133151
134152

Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -860,6 +860,7 @@ docker-all-tools: tool-util tool-remove-execution-fork
860860
PHONY: docker-build-util
861861
docker-build-util:
862862
docker build -f cmd/Dockerfile --build-arg TARGET=./cmd/util --build-arg GOARCH=$(GOARCH) --build-arg VERSION=$(IMAGE_TAG) --build-arg CGO_FLAG=$(DISABLE_ADX) --target production \
863+
--secret id=cadence_deploy_key,env=CADENCE_DEPLOY_KEY --build-arg GOPRIVATE=$(GOPRIVATE) \
863864
-t "$(CONTAINER_REGISTRY)/util:latest" \
864865
-t "$(CONTAINER_REGISTRY)/util:$(IMAGE_TAG)" .
865866

cmd/bootstrap/utils/md5.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,8 @@ package utils
22

33
// The google storage API only provides md5 and crc32 hence overriding the linter flag for md5
44
import (
5-
"crypto/md5" //nolint:gosec
5+
// #nosec
6+
"crypto/md5"
67
"io"
78
"os"
89
)

cmd/util/cmd/export-evm-state/cmd.go

Lines changed: 63 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,17 @@ package evm_exporter
33
import (
44
"fmt"
55
"os"
6+
"path/filepath"
67

78
"github.com/rs/zerolog/log"
89
"github.com/spf13/cobra"
910

11+
"github.com/onflow/atree"
12+
1013
"github.com/onflow/flow-go/cmd/util/ledger/util"
1114
"github.com/onflow/flow-go/fvm/evm"
1215
"github.com/onflow/flow-go/fvm/evm/emulator/state"
16+
"github.com/onflow/flow-go/fvm/evm/testutils"
1317
"github.com/onflow/flow-go/ledger"
1418
"github.com/onflow/flow-go/ledger/common/convert"
1519
"github.com/onflow/flow-go/model/flow"
@@ -20,6 +24,8 @@ var (
2024
flagExecutionStateDir string
2125
flagOutputDir string
2226
flagStateCommitment string
27+
flagEVMStateGobDir string
28+
flagEVMStateGobHeight uint64
2329
)
2430

2531
var Cmd = &cobra.Command{
@@ -34,21 +40,33 @@ func init() {
3440

3541
Cmd.Flags().StringVar(&flagExecutionStateDir, "execution-state-dir", "",
3642
"Execution Node state dir (where WAL logs are written")
37-
_ = Cmd.MarkFlagRequired("execution-state-dir")
3843

3944
Cmd.Flags().StringVar(&flagOutputDir, "output-dir", "",
4045
"Directory to write new Execution State to")
4146
_ = Cmd.MarkFlagRequired("output-dir")
4247

4348
Cmd.Flags().StringVar(&flagStateCommitment, "state-commitment", "",
4449
"State commitment (hex-encoded, 64 characters)")
50+
51+
Cmd.Flags().StringVar(&flagEVMStateGobDir, "evm_state_gob_dir", "/var/flow/data/evm_state_gob",
52+
"directory that stores the evm state gob files as checkpoint")
53+
54+
Cmd.Flags().Uint64Var(&flagEVMStateGobHeight, "evm_state_gob_height", 0,
55+
"the flow height of the evm state gob files")
4556
}
4657

4758
func run(*cobra.Command, []string) {
4859
log.Info().Msg("start exporting evm state")
49-
err := ExportEVMState(flagChain, flagExecutionStateDir, flagStateCommitment, flagOutputDir)
50-
if err != nil {
51-
log.Fatal().Err(err).Msg("cannot get export evm state")
60+
if flagExecutionStateDir != "" {
61+
err := ExportEVMState(flagChain, flagExecutionStateDir, flagStateCommitment, flagOutputDir)
62+
if err != nil {
63+
log.Fatal().Err(err).Msg("cannot get export evm state")
64+
}
65+
} else if flagEVMStateGobDir != "" {
66+
err := ExportEVMStateFromGob(flagChain, flagEVMStateGobDir, flagEVMStateGobHeight, flagOutputDir)
67+
if err != nil {
68+
log.Fatal().Err(err).Msg("cannot get export evm state from gob files")
69+
}
5270
}
5371
}
5472

@@ -83,7 +101,40 @@ func ExportEVMState(
83101

84102
payloadsLedger := util.NewPayloadsLedger(filteredPayloads)
85103

86-
exporter, err := state.NewExporter(payloadsLedger, storageRoot)
104+
return ExportEVMStateFromPayloads(payloadsLedger, storageRoot, outputPath)
105+
}
106+
107+
func ExportEVMStateFromGob(
108+
chainName string,
109+
evmStateGobDir string,
110+
flowHeight uint64,
111+
outputPath string) error {
112+
113+
valueFileName, allocatorFileName := evmStateGobFileNamesByEndHeight(evmStateGobDir, flowHeight)
114+
chainID := flow.ChainID(chainName)
115+
116+
storageRoot := evm.StorageAccountAddress(chainID)
117+
valuesGob, err := testutils.DeserializeState(valueFileName)
118+
if err != nil {
119+
return err
120+
}
121+
122+
allocatorGobs, err := testutils.DeserializeAllocator(allocatorFileName)
123+
if err != nil {
124+
return err
125+
}
126+
127+
store := testutils.GetSimpleValueStorePopulated(valuesGob, allocatorGobs)
128+
129+
return ExportEVMStateFromPayloads(store, storageRoot, outputPath)
130+
}
131+
132+
func ExportEVMStateFromPayloads(
133+
ledger atree.Ledger,
134+
storageRoot flow.Address,
135+
outputPath string,
136+
) error {
137+
exporter, err := state.NewExporter(ledger, storageRoot)
87138
if err != nil {
88139
return fmt.Errorf("failed to create exporter: %w", err)
89140
}
@@ -95,15 +146,15 @@ func ExportEVMState(
95146
}
96147
}
97148

98-
fi, err := os.Create(outputPath)
99-
if err != nil {
100-
return err
101-
}
102-
defer fi.Close()
103-
104-
err = exporter.Export(outputPath)
149+
err = exporter.ExportGob(outputPath)
105150
if err != nil {
106151
return fmt.Errorf("failed to export: %w", err)
107152
}
108153
return nil
109154
}
155+
156+
func evmStateGobFileNamesByEndHeight(evmStateGobDir string, endHeight uint64) (string, string) {
157+
valueFileName := filepath.Join(evmStateGobDir, fmt.Sprintf("values-%d.gob", endHeight))
158+
allocatorFileName := filepath.Join(evmStateGobDir, fmt.Sprintf("allocators-%d.gob", endHeight))
159+
return valueFileName, allocatorFileName
160+
}

engine/consensus/dkg/doc.go

Lines changed: 44 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -1,54 +1,45 @@
1-
/*
2-
3-
Package dkg implements engines for the DKG protocol.
4-
5-
ReactorEngine
6-
7-
ReactorEngine implements triggers to control the lifecycle of DKG runs. A new
8-
DKG protocol is started when an EpochSetup event is sealed and finalized. The
9-
subsequent phase transitions are triggered when specified views are encountered
10-
(specifically when the first block of a given view is finalized). In between
11-
phase transitions the engine regularly queries the DKG smart-contract to read
12-
broadcast messages.
13-
14-
MessagingEngine
15-
16-
MessagingEngine is a network engine that enables consensus nodes to securely
17-
exchange private DKG messages. Note that broadcast messages are not exchanged
18-
through this engine, but rather via the DKG smart-contract.
19-
20-
Architecture
21-
22-
For every new epoch, the ReactorEngine instantiates a new DKGController with a
23-
new Broker using the provided ControllerFactory. The ControllerFactory ties new
24-
DKGControllers to the MessagingEngine via a BrokerTunnel which exposes channels
25-
to relay incoming and outgoing messages (cf. module/dkg).
26-
27-
EpochSetup/OnView
28-
|
29-
v
30-
+---------------+
31-
| ReactorEngine |
32-
+---------------+
33-
|
34-
v
35-
*~~~~~~~~~~~~~~~~~~~~~* (one/epoch)
36-
| +---------------+ |
37-
| | Controller | |
38-
| +---------------+ |
39-
| | |
40-
| v |
41-
| +---------------+ |
42-
| | Broker | |
43-
| +---------------+ |
44-
*~~~~~~~~|~~~~~~~~~\~~*
45-
tunnel smart-contract client
46-
| \
47-
+--------------+ +------------------+
48-
| Messaging | | DKGSmartContract |
49-
| Engine | | |
50-
+--------------+ +------------------+
51-
52-
*/
53-
1+
// Package dkg implements engines for the DKG protocol.
2+
//
3+
// # Reactor Engine
4+
//
5+
// The [ReactorEngine] implements triggers to control the lifecycle of DKG instances.
6+
// A new DKG instance is started when an EpochSetup service event is sealed.
7+
// The subsequent phase transitions are triggered when specified views are encountered.
8+
// Specifically, phase transitions for a view V are triggered when the first block with view ≥V is finalized.
9+
// Between phase transitions, we periodically query the DKG smart-contract ("whiteboard") to read broadcast messages.
10+
// Before transitioning the state machine to the next phase, we query the whiteboard w.r.t. the final view
11+
// of the phase - this ensures all participants eventually observe the same set of messages for each phase.
12+
//
13+
// # Messaging Engine
14+
//
15+
// The [MessagingEngine] is a network engine that enables consensus nodes to securely exchange
16+
// private (not broadcast) DKG messages. Broadcast messages are sent via the DKG smart contract.
17+
//
18+
// # Architecture
19+
//
20+
// In the happy path, one DKG instance runs every epoch. For each DKG instance, the [ReactorEngine]
21+
// instantiates a new, epoch-scoped module.DKGController and module.DKGBroker using the provided dkg.ControllerFactory.
22+
// The dkg.ControllerFactory ties new module.DKGController's to the [MessagingEngine] via a dkg.BrokerTunnel,
23+
// which exposes channels to relay incoming and outgoing messages (see package module/dkg for details).
24+
//
25+
// EpochSetup/EpochCommit/OnView events
26+
// ↓
27+
// ┏━━━━━━━━━━━━━━━━━┓
28+
// ┃ ReactorEngine ┃
29+
// ┗━━━━━━━━━━━━━━━━━┛
30+
// ↓
31+
// ┏━━━━━━━━━━━━━━━━━┓ ╮
32+
// ┃ Controller ┃ │
33+
// ┗━━━━━━━━━━━━━━━━━┛ │
34+
// ↓ ┝ Epoch-scoped components
35+
// ┏━━━━━━━━━━━━━━━━━┓ │
36+
// ┃ Broker ┃ │
37+
// ┗━━━━━━━━━━━━━━━━━┛ ╯
38+
// │ │
39+
// BrokerTunnel DKGContractClient
40+
// ↓ ↓
41+
// ┏━━━━━━━━━━━━━━┓ ┏━━━━━━━━━━━━━━━━━━┓
42+
// ┃ Messaging ┃ ┃ FlowDKG smart ┃
43+
// ┃ Engine ┃ ┃ contract ┃
44+
// ┗━━━━━━━━━━━━━━┛ ┗━━━━━━━━━━━━━━━━━━┛
5445
package dkg

fvm/evm/emulator/state/base.go

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -74,13 +74,13 @@ func NewBaseView(ledger atree.Ledger, rootAddress flow.Address) (*BaseView, erro
7474
// fetch the account collection, if not exist, create one
7575
view.accounts, view.accountSetupOnCommit, err = view.fetchOrCreateCollection(AccountsStorageIDKey)
7676
if err != nil {
77-
return nil, err
77+
return nil, fmt.Errorf("failed to fetch or create account collection with key %v: %w", AccountsStorageIDKey, err)
7878
}
7979

8080
// fetch the code collection, if not exist, create one
8181
view.codes, view.codeSetupOnCommit, err = view.fetchOrCreateCollection(CodesStorageIDKey)
8282
if err != nil {
83-
return nil, err
83+
return nil, fmt.Errorf("failed to fetch or create code collection with key %v: %w", CodesStorageIDKey, err)
8484
}
8585

8686
return view, nil
@@ -485,7 +485,10 @@ func (v *BaseView) fetchOrCreateCollection(path string) (collection *Collection,
485485
}
486486
if len(collectionID) == 0 {
487487
collection, err = v.collectionProvider.NewCollection()
488-
return collection, true, err
488+
if err != nil {
489+
return collection, true, fmt.Errorf("fail to create collection with key %v: %w", path, err)
490+
}
491+
return collection, true, nil
489492
}
490493
collection, err = v.collectionProvider.CollectionByID(collectionID)
491494
return collection, false, err

0 commit comments

Comments
 (0)