diff options
author | Mission Liao <mission.liao@dexon.org> | 2018-11-07 16:11:17 +0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2018-11-07 16:11:17 +0800 |
commit | 766e6aac32b8f97934833c06814c37dbdd9b7ae2 (patch) | |
tree | aac3c79c6db2c5c32de3519888b2e1253eb0fceb /core/test/state-change-request.go | |
parent | bcdc444319ca9fe219f27e818ab9ec863d6757ea (diff) | |
download | tangerine-consensus-766e6aac32b8f97934833c06814c37dbdd9b7ae2.tar tangerine-consensus-766e6aac32b8f97934833c06814c37dbdd9b7ae2.tar.gz tangerine-consensus-766e6aac32b8f97934833c06814c37dbdd9b7ae2.tar.bz2 tangerine-consensus-766e6aac32b8f97934833c06814c37dbdd9b7ae2.tar.lz tangerine-consensus-766e6aac32b8f97934833c06814c37dbdd9b7ae2.tar.xz tangerine-consensus-766e6aac32b8f97934833c06814c37dbdd9b7ae2.tar.zst tangerine-consensus-766e6aac32b8f97934833c06814c37dbdd9b7ae2.zip |
test: make StateChangeRequest broadcast-able (#305)
Make `test.StateChangeRequest` behaves like tx
on ethereum:
- Can be broadcasted and cached in a pool.
- Uniquely indexed, and be removed after
applied.
Changes:
- Make cloneDKGx functions in test.State as
utilities.
- Add hash and timestamp fields to
test.StateChangeRequest.
- Add two methods to test.State:
- PackOwnRequests would pack all pending
change requests owned by this instance as
byte slice, and move them to global pending
requests pool.
- AddRequestsFromOthers would add pending
change requests from others to global
pending requests pool.
- The method State.PackRequests now would pack
requests in global pending requests pool.
- The method State.Apply would remove
corresponding StateChangeRequest by hash.
Diffstat (limited to 'core/test/state-change-request.go')
-rw-r--r-- | core/test/state-change-request.go | 135 |
1 files changed, 135 insertions, 0 deletions
diff --git a/core/test/state-change-request.go b/core/test/state-change-request.go new file mode 100644 index 0000000..0f49db0 --- /dev/null +++ b/core/test/state-change-request.go @@ -0,0 +1,135 @@ +// Copyright 2018 The dexon-consensus Authors +// This file is part of the dexon-consensus library. +// +// The dexon-consensus library is free software: you can redistribute it +// and/or modify it under the terms of the GNU Lesser General Public License as +// published by the Free Software Foundation, either version 3 of the License, +// or (at your option) any later version. +// +// The dexon-consensus library is distributed in the hope that it will be +// useful, but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser +// General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the dexon-consensus library. If not, see +// <http://www.gnu.org/licenses/>. + +package test + +import ( + "time" + + "github.com/dexon-foundation/dexon-consensus/common" + "github.com/dexon-foundation/dexon-consensus/core/crypto" + typesDKG "github.com/dexon-foundation/dexon-consensus/core/types/dkg" + "github.com/dexon-foundation/dexon/rlp" +) + +// StateChangeType is the type of state change request. +type StateChangeType uint8 + +// Types of state change. +const ( + StateChangeNothing StateChangeType = iota + // DKG & CRS + StateAddCRS + StateAddDKGComplaint + StateAddDKGMasterPublicKey + StateAddDKGFinal + // Configuration related. + StateChangeNumChains + StateChangeLambdaBA + StateChangeLambdaDKG + StateChangeRoundInterval + StateChangeMinBlockInterval + StateChangeMaxBlockInterval + StateChangeK + StateChangePhiRatio + StateChangeNotarySetSize + StateChangeDKGSetSize + // Node set related. + StateAddNode +) + +// StateChangeRequest carries information of state change request. +type StateChangeRequest struct { + Type StateChangeType `json:"type"` + Payload interface{} `json:"payload"` + // The purpose of these fields are aiming to provide an unique ID for each + // change request. + Hash common.Hash + Timestamp uint64 +} + +// this structure is mainly for marshalling for StateChangeRequest. +type rawStateChangeRequest struct { + Type StateChangeType + Payload rlp.RawValue + Hash common.Hash + Timestamp uint64 +} + +// NewStateChangeRequest constructs an StateChangeRequest instance. +func NewStateChangeRequest( + t StateChangeType, payload interface{}) *StateChangeRequest { + now := uint64(time.Now().UTC().UnixNano()) + b, err := rlp.EncodeToBytes(struct { + Type StateChangeType + Payload interface{} + Timestamp uint64 + }{t, payload, now}) + if err != nil { + panic(err) + } + return &StateChangeRequest{ + Hash: crypto.Keccak256Hash(b), + Type: t, + Payload: payload, + Timestamp: now, + } +} + +// Clone a StateChangeRequest instance. +func (req *StateChangeRequest) Clone() (copied *StateChangeRequest) { + copied = &StateChangeRequest{ + Type: req.Type, + Hash: req.Hash, + Timestamp: req.Timestamp, + } + // NOTE: The cloned DKGx structs would be different from sources in binary + // level, thus would produce different hash from the source. + // I don't want different hash for source/copied requests thus would + // copy the hash from source directly. + switch req.Type { + case StateAddNode: + srcBytes := req.Payload.([]byte) + copiedBytes := make([]byte, len(srcBytes)) + copy(copiedBytes, srcBytes) + req.Payload = copiedBytes + case StateAddCRS: + crsReq := req.Payload.(*crsAdditionRequest) + copied.Payload = &crsAdditionRequest{ + Round: crsReq.Round, + CRS: crsReq.CRS, + } + case StateAddDKGFinal: + copied.Payload = cloneDKGFinalize(req.Payload.(*typesDKG.Finalize)) + case StateAddDKGMasterPublicKey: + copied.Payload = cloneDKGMasterPublicKey( + req.Payload.(*typesDKG.MasterPublicKey)) + case StateAddDKGComplaint: + copied.Payload = cloneDKGComplaint(req.Payload.(*typesDKG.Complaint)) + default: + copied.Payload = req.Payload + } + return +} + +// Equal checks equality between two StateChangeRequest. +func (req *StateChangeRequest) Equal(other *StateChangeRequest) error { + if req.Hash == other.Hash { + return nil + } + return ErrStatePendingChangesNotEqual +} |