Skip to content

Commit

Permalink
vochain fork: refactor ZkCircuits handling
Browse files Browse the repository at this point in the history
* circuit/config: rename `dev` -> `v0.0.1` and add voceremony as `v1.0.0`
* vochain/app.go: SetZkCircuit during beginBlock
* add config/forks.go
* circuit: add DownloadZkCircuits funcs
  * DownloadZkCircuitsForChainID
  * DownloadDefaultZkCircuit

NewBaseApplication now calls circuit.DownloadDefaultZkCircuit
instead of transactionHandler.LoadZkCircuit

and newTendermint now calls circuit.DownloadZkCircuitsForChainID
  • Loading branch information
altergui committed Nov 28, 2023
1 parent fe5d2b5 commit 3240d24
Show file tree
Hide file tree
Showing 5 changed files with 82 additions and 13 deletions.
33 changes: 33 additions & 0 deletions config/forks.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package config

// ForksCfg allows applying softforks at specified heights
type ForksCfg struct {
VoceremonyForkBlock uint32
}

// Forks is a map of chainIDs
var Forks = map[string]*ForksCfg{
"vocdoni/DEV/29": {
VoceremonyForkBlock: 180000, // estimated 2023-11-30T23:45:29.095375169Z
},
"vocdoni/STAGE/9": {
VoceremonyForkBlock: 190000, // estimated 2023-12-04T11:25:38.643517797Z
},
"vocdoni/LTS/1.2": {
VoceremonyForkBlock: 350000, // estimated 2023-12-06T05:59:27.529386884Z
},
}

// DefaultZkCircuitVersion is the circuit version used by default
const DefaultZkCircuitVersion = "v0.0.1"

// VoceremonyForkZkCircuitVersion is the circuit version used after VoceremonyForkBlock
const VoceremonyForkZkCircuitVersion = "v1.0.0"

// ForksForChainID returns the ForksCfg of chainID, if found, or an empty ForksCfg otherwise
func ForksForChainID(chainID string) *ForksCfg {
if cfg, found := Forks[chainID]; found {
return cfg
}
return &ForksCfg{}
}
21 changes: 21 additions & 0 deletions crypto/zk/circuit/circuit.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import (
"path/filepath"
"time"

"go.vocdoni.io/dvote/config"
"go.vocdoni.io/dvote/log"
)

Expand Down Expand Up @@ -40,6 +41,26 @@ type ZkCircuit struct {
Config *ZkCircuitConfig
}

// DownloadDefaultZkCircuit ensures the default circuit is cached locally
func DownloadDefaultZkCircuit() error {
_, err := LoadZkCircuitByTag(config.DefaultZkCircuitVersion)
if err != nil {
return fmt.Errorf("could not load zk verification keys: %w", err)
}
return nil
}

// DownloadZkCircuitsForChainID ensures all circuits needed for chainID are cached locally
func DownloadZkCircuitsForChainID(chainID string) error {
if config.ForksForChainID(chainID).VoceremonyForkBlock > 0 {
_, err := LoadZkCircuitByTag(config.VoceremonyForkZkCircuitVersion)
if err != nil {
return fmt.Errorf("could not load zk verification keys: %w", err)
}
}
return DownloadDefaultZkCircuit()
}

// LoadZkCircuitByTag gets the circuit configuration associated to the provided
// tag or gets the default one and load its artifacts to prepare the circuit to
// be used.
Expand Down
21 changes: 10 additions & 11 deletions crypto/zk/circuit/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ func (conf *ZkCircuitConfig) SupportsCensusSize(maxCensusSize uint64) bool {
// the remote and local location of the circuits artifacts and their metadata
// such as artifacts hash or the number of parameters.
var CircuitsConfigurations = map[string]*ZkCircuitConfig{
"dev": {
"v0.0.1": {
URI: "https://raw.githubusercontent.com/vocdoni/" +
"zk-franchise-proof-circuit/master",
CircuitPath: "artifacts/zkCensus/dev/160",
Expand All @@ -92,17 +92,16 @@ var CircuitsConfigurations = map[string]*ZkCircuitConfig{
WasmHash: hexToBytes("0x80a73567f6a4655d4332301efcff4bc5711bb48176d1c71fdb1e48df222ac139"),
WasmFilename: "circuit.wasm",
},
"prod": {
URI: "https://raw.githubusercontent.com/vocdoni/" +
"zk-franchise-proof-circuit/master",
CircuitPath: "artifacts/zkCensus/dev/160",
"v1.0.0": {
URI: "https://raw.githubusercontent.com/altergui/zk-voceremony",
CircuitPath: "ceremony/vocdoni-zkcensus-ceremony/results",
Levels: 160, // ZkCircuit number of levels
ProvingKeyHash: hexToBytes("0xe359b256e5e3c78acaccf8dab5dc4bea99a2f07b2a05e935b5ca658c714dea4a"),
ProvingKeyFilename: "proving_key.zkey",
VerificationKeyHash: hexToBytes("0x235e55571812f8e324e73e37e53829db0c4ac8f68469b9b953876127c97b425f"),
VerificationKeyFilename: "verification_key.json",
WasmHash: hexToBytes("0x80a73567f6a4655d4332301efcff4bc5711bb48176d1c71fdb1e48df222ac139"),
WasmFilename: "circuit.wasm",
ProvingKeyHash: hexToBytes("0x94f4062db3e43175ac1136f285551d547a177e37b0616a41900a38ed5ec3d478"),
ProvingKeyFilename: "census_proving_key.zkey",
VerificationKeyHash: hexToBytes("0x2a47ff7e511926290fedfa406886944eeb0a3df9021ca26333c0c124c89aa7b0"),
VerificationKeyFilename: "census_verification_key.json",
WasmHash: hexToBytes("0xc98133cf4d84ced677549e0d848739f4e80ddf78af678cbc8b95377247a92773"),
WasmFilename: "census.wasm",
},
}

Expand Down
16 changes: 14 additions & 2 deletions vochain/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -136,10 +136,11 @@ func NewBaseApplication(vochainCfg *config.VochainCfg) (*BaseApplication, error)
istc,
filepath.Join(vochainCfg.DataDir, "txHandler"),
)
// Load or download the zk verification keys
if err := transactionHandler.LoadZkCircuit(circuit.DefaultCircuitConfigurationTag); err != nil {

if err := circuit.DownloadDefaultZkCircuit(); err != nil {
return nil, fmt.Errorf("cannot load zk circuit: %w", err)
}

blockCache, err := lru.New[int64, *tmtypes.Block](32)
if err != nil {
return nil, err
Expand Down Expand Up @@ -260,6 +261,7 @@ func (app *BaseApplication) beginBlock(t time.Time, height uint32) {
app.State.Rollback()
app.startBlockTimestamp.Store(t.Unix())
app.State.SetHeight(height)
app.SetZkCircuit()
go app.State.CachePurge(height)
app.State.OnBeginBlock(vstate.BeginBlock{
Height: int64(height),
Expand Down Expand Up @@ -352,6 +354,16 @@ func (app *BaseApplication) Genesis() *tmtypes.GenesisDoc {
return app.genesisInfo
}

// SetZkCircuit updates the ZkCircuit if planned at the current height
func (app *BaseApplication) SetZkCircuit() {
if config.ForksForChainID(app.chainID).VoceremonyForkBlock == app.Height() {
err := app.TransactionHandler.LoadZkCircuit(config.VoceremonyForkZkCircuitVersion)
if err != nil {
log.Fatalf("failed to update ZkCircuit on VoceremonyForkBlock: %w", err)
}
}
}

// SetCircuitConfigTag sets the current BaseApplication circuit config tag
// attribute to the provided one and loads the circuit configuration based on
// it. The available circuit config tags are defined in
Expand Down
4 changes: 4 additions & 0 deletions vochain/start.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import (

"go.vocdoni.io/dvote/config"
"go.vocdoni.io/dvote/crypto/ethereum"
"go.vocdoni.io/dvote/crypto/zk/circuit"
vocdoniGenesis "go.vocdoni.io/dvote/vochain/genesis"

tmcfg "github.com/cometbft/cometbft/config"
Expand Down Expand Up @@ -275,6 +276,9 @@ func newTendermint(app *BaseApplication,
log.Infow("genesis file", "genesis", tconfig.GenesisFile(), "chainID", genesisCID.ChainID)
app.SetChainID(genesisCID.ChainID)

// the chain might need additional ZkCircuits, now that we know the chainID ensure they are downloaded
circuit.DownloadZkCircuitsForChainID(genesisCID.ChainID)

// assign the default tendermint methods
app.SetDefaultMethods()
node, err := tmnode.NewNode(tconfig,
Expand Down

0 comments on commit 3240d24

Please sign in to comment.