diff --git a/action/protocol/staking/builder.go b/action/protocol/staking/builder.go index 668df22f1c..520fcd26d0 100644 --- a/action/protocol/staking/builder.go +++ b/action/protocol/staking/builder.go @@ -8,5 +8,7 @@ type ( BuilderConfig struct { Staking genesis.Staking PersistCandsMapBlock uint64 + CandsMapPatchFile string + CreateStakingPatch bool } ) diff --git a/action/protocol/staking/protocol.go b/action/protocol/staking/protocol.go index 91ae7deafa..db4921022e 100644 --- a/action/protocol/staking/protocol.go +++ b/action/protocol/staking/protocol.go @@ -80,6 +80,7 @@ type ( config Configuration candBucketsIndexer *CandidatesBucketsIndexer voteReviser *VoteReviser + patch *PatchStore } // Configuration is the staking protocol configuration. @@ -90,6 +91,8 @@ type ( MinStakeAmount *big.Int BootstrapCandidates []genesis.BootstrapCandidate PersistCandsMapBlock uint64 + CandsMapPatchFile string + CreateStakingPatch bool } // DepositGas deposits gas to some pool @@ -150,6 +153,8 @@ func NewProtocol(depositGas DepositGas, cfg *BuilderConfig, candBucketsIndexer * MinStakeAmount: minStakeAmount, BootstrapCandidates: cfg.Staking.BootstrapCandidates, PersistCandsMapBlock: cfg.PersistCandsMapBlock, + CandsMapPatchFile: cfg.CandsMapPatchFile, + CreateStakingPatch: cfg.CreateStakingPatch, }, depositGas: depositGas, candBucketsIndexer: candBucketsIndexer, @@ -179,7 +184,10 @@ func (p *Protocol) Start(ctx context.Context, sr protocol.StateReader) (interfac if p.needToReadCandsMap(height) { name, operator, owners, err := readCandCenterStateFromStateDB(sr, height) if err != nil { - return nil, errors.Wrap(err, "failed to read name/operator map") + // stateDB does not have name/operator map yet + if name, operator, owners, err = p.readCandCenterStateFromPatch(height); err != nil { + return nil, errors.Wrap(err, "failed to read name/operator map") + } } if err = c.candCenter.base.loadNameOperatorMapOwnerList(name, operator, owners); err != nil { return nil, errors.Wrap(err, "failed to load name/operator map to cand center") @@ -339,7 +347,16 @@ func (p *Protocol) PreCommit(ctx context.Context, sm protocol.StateManager) erro if len(name) == 0 || len(op) == 0 || len(owners) == 0 { return ErrNilParameters } - return errors.Wrap(p.writeCandCenterStateToStateDB(csm, name, op, owners), "failed to write name/operator map to stateDB") + if err := p.writeCandCenterStateToStateDB(csm, name, op, owners); err != nil { + return errors.Wrap(err, "failed to write name/operator map to stateDB") + } + // write nameMap/operatorMap and ownerList to patch file + if p.config.CreateStakingPatch { + if err := p.writeNameOperatorMapToPatch(height, name, op, owners); err != nil { + return errors.Wrap(err, "failed to write staking patch file") + } + } + return nil } // Commit commits the last change @@ -626,3 +643,17 @@ func (p *Protocol) writeCandCenterStateToStateDB(csm CandidateStateManager, name } return csm.putCandidateList(owners, _ownerKey) } + +func (p *Protocol) writeNameOperatorMapToPatch(height uint64, name, op, owners CandidateList) error { + if p.patch == nil { + p.patch = NewPatchStore(p.config.CandsMapPatchFile) + } + return p.patch.Write(height, name, op, owners) +} + +func (p *Protocol) readCandCenterStateFromPatch(height uint64) (CandidateList, CandidateList, CandidateList, error) { + if p.patch == nil { + p.patch = NewPatchStore(p.config.CandsMapPatchFile) + } + return p.patch.Read(height) +} diff --git a/blockchain/config.go b/blockchain/config.go index 8fe59e45e5..b972a98e8d 100644 --- a/blockchain/config.go +++ b/blockchain/config.go @@ -28,6 +28,7 @@ type ( ChainDBPath string `yaml:"chainDBPath"` TrieDBPatchFile string `yaml:"trieDBPatchFile"` TrieDBPath string `yaml:"trieDBPath"` + CandsMapPatchFile string `yaml:"candsMapPatchFile"` IndexDBPath string `yaml:"indexDBPath"` BloomfilterIndexDBPath string `yaml:"bloomfilterIndexDBPath"` CandidateIndexDBPath string `yaml:"candidateIndexDBPath"` @@ -69,6 +70,8 @@ type ( StreamingBlockBufferSize uint64 `yaml:"streamingBlockBufferSize"` // PersistCandsMapBlock is the block to persist candidates map PersistCandsMapBlock uint64 `yaml:"persistCandsMapBlock"` + // CreateStakingPatch indicates to create patch file or not + CreateStakingPatch bool `yaml:"createStakingPatch"` } ) @@ -78,6 +81,7 @@ var ( ChainDBPath: "/var/data/chain.db", TrieDBPatchFile: "/var/data/trie.db.patch", TrieDBPath: "/var/data/trie.db", + CandsMapPatchFile: "/var/data/candsmap.patch", IndexDBPath: "/var/data/index.db", BloomfilterIndexDBPath: "/var/data/bloomfilter.index.db", CandidateIndexDBPath: "/var/data/candidate.index.db", diff --git a/chainservice/builder.go b/chainservice/builder.go index 95b0b96121..2ef7125362 100644 --- a/chainservice/builder.go +++ b/chainservice/builder.go @@ -451,6 +451,8 @@ func (builder *Builder) registerStakingProtocol() error { &staking.BuilderConfig{ Staking: builder.cfg.Genesis.Staking, PersistCandsMapBlock: builder.cfg.Chain.PersistCandsMapBlock, + CandsMapPatchFile: builder.cfg.Chain.CandsMapPatchFile, + CreateStakingPatch: builder.cfg.Chain.CreateStakingPatch, }, builder.cs.candBucketsIndexer, builder.cfg.Genesis.GreenlandBlockHeight,