aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--core/gen_genesis.go2
-rw-r--r--core/gen_genesis_account.go14
-rw-r--r--core/genesis.go26
-rw-r--r--core/vm/governance.go99
4 files changed, 95 insertions, 46 deletions
diff --git a/core/gen_genesis.go b/core/gen_genesis.go
index 022f8257a..63f478cc7 100644
--- a/core/gen_genesis.go
+++ b/core/gen_genesis.go
@@ -15,6 +15,7 @@ import (
var _ = (*genesisSpecMarshaling)(nil)
+// MarshalJSON marshals as JSON.
func (g Genesis) MarshalJSON() ([]byte, error) {
type Genesis struct {
Config *params.ChainConfig `json:"config"`
@@ -51,6 +52,7 @@ func (g Genesis) MarshalJSON() ([]byte, error) {
return json.Marshal(&enc)
}
+// UnmarshalJSON unmarshals from JSON.
func (g *Genesis) UnmarshalJSON(input []byte) error {
type Genesis struct {
Config *params.ChainConfig `json:"config"`
diff --git a/core/gen_genesis_account.go b/core/gen_genesis_account.go
index 45a03c329..1a5653e4b 100644
--- a/core/gen_genesis_account.go
+++ b/core/gen_genesis_account.go
@@ -14,12 +14,15 @@ import (
var _ = (*genesisAccountMarshaling)(nil)
+// MarshalJSON marshals as JSON.
func (g GenesisAccount) MarshalJSON() ([]byte, error) {
type GenesisAccount struct {
Code hexutil.Bytes `json:"code,omitempty"`
Storage map[storageJSON]storageJSON `json:"storage,omitempty"`
Balance *math.HexOrDecimal256 `json:"balance" gencodec:"required"`
Nonce math.HexOrDecimal64 `json:"nonce,omitempty"`
+ Staked *math.HexOrDecimal256 `json:"staked"`
+ PublicKey hexutil.Bytes `json:"publicKey"`
PrivateKey hexutil.Bytes `json:"secretKey,omitempty"`
}
var enc GenesisAccount
@@ -32,16 +35,21 @@ func (g GenesisAccount) MarshalJSON() ([]byte, error) {
}
enc.Balance = (*math.HexOrDecimal256)(g.Balance)
enc.Nonce = math.HexOrDecimal64(g.Nonce)
+ enc.Staked = (*math.HexOrDecimal256)(g.Staked)
+ enc.PublicKey = g.PublicKey
enc.PrivateKey = g.PrivateKey
return json.Marshal(&enc)
}
+// UnmarshalJSON unmarshals from JSON.
func (g *GenesisAccount) UnmarshalJSON(input []byte) error {
type GenesisAccount struct {
Code *hexutil.Bytes `json:"code,omitempty"`
Storage map[storageJSON]storageJSON `json:"storage,omitempty"`
Balance *math.HexOrDecimal256 `json:"balance" gencodec:"required"`
Nonce *math.HexOrDecimal64 `json:"nonce,omitempty"`
+ Staked *math.HexOrDecimal256 `json:"staked"`
+ PublicKey *hexutil.Bytes `json:"publicKey"`
PrivateKey *hexutil.Bytes `json:"secretKey,omitempty"`
}
var dec GenesisAccount
@@ -64,6 +72,12 @@ func (g *GenesisAccount) UnmarshalJSON(input []byte) error {
if dec.Nonce != nil {
g.Nonce = uint64(*dec.Nonce)
}
+ if dec.Staked != nil {
+ g.Staked = (*big.Int)(dec.Staked)
+ }
+ if dec.PublicKey != nil {
+ g.PublicKey = *dec.PublicKey
+ }
if dec.PrivateKey != nil {
g.PrivateKey = *dec.PrivateKey
}
diff --git a/core/genesis.go b/core/genesis.go
index 96e2e3b97..5ee34c16e 100644
--- a/core/genesis.go
+++ b/core/genesis.go
@@ -31,6 +31,8 @@ import (
"github.com/dexon-foundation/dexon/core/rawdb"
"github.com/dexon-foundation/dexon/core/state"
"github.com/dexon-foundation/dexon/core/types"
+ "github.com/dexon-foundation/dexon/core/vm"
+ "github.com/dexon-foundation/dexon/crypto"
"github.com/dexon-foundation/dexon/ethdb"
"github.com/dexon-foundation/dexon/log"
"github.com/dexon-foundation/dexon/params"
@@ -83,6 +85,8 @@ type GenesisAccount struct {
Storage map[common.Hash]common.Hash `json:"storage,omitempty"`
Balance *big.Int `json:"balance" gencodec:"required"`
Nonce uint64 `json:"nonce,omitempty"`
+ Staked *big.Int `json:"staked"`
+ PublicKey []byte `json:"publicKey"`
PrivateKey []byte `json:"secretKey,omitempty"` // for tests
}
@@ -101,8 +105,10 @@ type genesisSpecMarshaling struct {
type genesisAccountMarshaling struct {
Code hexutil.Bytes
Balance *math.HexOrDecimal256
+ Staked *math.HexOrDecimal256
Nonce math.HexOrDecimal64
Storage map[storageJSON]storageJSON
+ PublicKey hexutil.Bytes
PrivateKey hexutil.Bytes
}
@@ -231,13 +237,29 @@ func (g *Genesis) ToBlock(db ethdb.Database) *types.Block {
db = ethdb.NewMemDatabase()
}
statedb, _ := state.New(common.Hash{}, state.NewDatabase(db))
+ govStateHelper := vm.GovernanceStateHelper{
+ Address: vm.GovernanceContractAddress,
+ StateDB: statedb,
+ }
for addr, account := range g.Alloc {
- statedb.AddBalance(addr, account.Balance)
+ statedb.AddBalance(addr, new(big.Int).Sub(account.Balance, account.Staked))
statedb.SetCode(addr, account.Code)
statedb.SetNonce(addr, account.Nonce)
for key, value := range account.Storage {
statedb.SetState(addr, key, value)
}
+
+ // Stake in governance state.
+ if account.Staked.Cmp(big.NewInt(0)) > 0 {
+ pk, err := crypto.DecompressPubkey(account.PublicKey)
+ if err != nil {
+ panic(err)
+ }
+ if crypto.PubkeyToAddress(*pk) != addr {
+ panic(fmt.Errorf("public key does not belones to %s", addr))
+ }
+ govStateHelper.Stake(addr, account.PublicKey, account.Staked)
+ }
}
root := statedb.IntermediateRoot(false)
head := &types.Header{
@@ -373,7 +395,7 @@ func DeveloperGenesisBlock(period uint64, faucet common.Address) *Genesis {
common.BytesToAddress([]byte{6}): {Balance: big.NewInt(1)}, // ECAdd
common.BytesToAddress([]byte{7}): {Balance: big.NewInt(1)}, // ECScalarMul
common.BytesToAddress([]byte{8}): {Balance: big.NewInt(1)}, // ECPairing
- faucet: {Balance: new(big.Int).Sub(new(big.Int).Lsh(big.NewInt(1), 256), big.NewInt(9))},
+ faucet: {Balance: new(big.Int).Sub(new(big.Int).Lsh(big.NewInt(1), 256), big.NewInt(9))},
},
}
}
diff --git a/core/vm/governance.go b/core/vm/governance.go
index b78d1bf94..497070222 100644
--- a/core/vm/governance.go
+++ b/core/vm/governance.go
@@ -787,38 +787,38 @@ const (
)
// State manipulation helper fro the governance contract.
-type StateHelper struct {
+type GovernanceStateHelper struct {
Address common.Address
StateDB StateDB
}
-func (s *StateHelper) getState(loc common.Hash) common.Hash {
+func (s *GovernanceStateHelper) getState(loc common.Hash) common.Hash {
return s.StateDB.GetState(s.Address, loc)
}
-func (s *StateHelper) setState(loc common.Hash, val common.Hash) {
+func (s *GovernanceStateHelper) setState(loc common.Hash, val common.Hash) {
s.StateDB.SetState(s.Address, loc, val)
}
-func (s *StateHelper) getStateBigInt(loc *big.Int) *big.Int {
+func (s *GovernanceStateHelper) getStateBigInt(loc *big.Int) *big.Int {
res := s.StateDB.GetState(s.Address, common.BigToHash(loc))
return new(big.Int).SetBytes(res.Bytes())
}
-func (s *StateHelper) setStateBigInt(loc *big.Int, val *big.Int) {
+func (s *GovernanceStateHelper) setStateBigInt(loc *big.Int, val *big.Int) {
s.setState(common.BigToHash(loc), common.BigToHash(val))
}
-func (s *StateHelper) getSlotLoc(loc *big.Int) *big.Int {
+func (s *GovernanceStateHelper) getSlotLoc(loc *big.Int) *big.Int {
return new(big.Int).SetBytes(crypto.Keccak256(common.BigToHash(loc).Bytes()))
}
-func (s *StateHelper) getMapLoc(pos *big.Int, key []byte) *big.Int {
+func (s *GovernanceStateHelper) getMapLoc(pos *big.Int, key []byte) *big.Int {
return new(big.Int).SetBytes(crypto.Keccak256(
key, common.BigToHash(pos).Bytes()))
}
-func (s *StateHelper) readBytes(loc *big.Int) []byte {
+func (s *GovernanceStateHelper) readBytes(loc *big.Int) []byte {
// length of the dynamic array (bytes).
rawLength := s.getStateBigInt(loc)
lengthByte := new(big.Int).Mod(rawLength, big.NewInt(256))
@@ -851,7 +851,7 @@ func (s *StateHelper) readBytes(loc *big.Int) []byte {
return data
}
-func (s *StateHelper) writeBytes(loc *big.Int, data []byte) {
+func (s *GovernanceStateHelper) writeBytes(loc *big.Int, data []byte) {
length := int64(len(data))
// short bytes (length <= 31)
@@ -892,7 +892,7 @@ func (s *StateHelper) writeBytes(loc *big.Int, data []byte) {
}
}
-func (s *StateHelper) read2DByteArray(pos, index *big.Int) [][]byte {
+func (s *GovernanceStateHelper) read2DByteArray(pos, index *big.Int) [][]byte {
baseLoc := s.getSlotLoc(pos)
loc := new(big.Int).Add(baseLoc, index)
@@ -907,7 +907,7 @@ func (s *StateHelper) read2DByteArray(pos, index *big.Int) [][]byte {
return data
}
-func (s *StateHelper) appendTo2DByteArray(pos, index *big.Int, data []byte) {
+func (s *GovernanceStateHelper) appendTo2DByteArray(pos, index *big.Int, data []byte) {
// Find the loc of the last element.
baseLoc := s.getSlotLoc(pos)
loc := new(big.Int).Add(baseLoc, index)
@@ -936,10 +936,21 @@ type nodeInfo struct {
staked *big.Int
}
-func (s *StateHelper) nodesLength() *big.Int {
+// Stake is a helper function for creating genesis state.
+func (s *GovernanceStateHelper) Stake(addr common.Address, publicKey []byte, staked *big.Int) {
+ offset := s.nodesLength()
+ s.pushNode(&nodeInfo{
+ owner: addr,
+ publicKey: publicKey,
+ staked: staked,
+ })
+ s.putOffset(addr, offset)
+}
+
+func (s *GovernanceStateHelper) nodesLength() *big.Int {
return s.getStateBigInt(big.NewInt(nodesLoc))
}
-func (s *StateHelper) node(index *big.Int) *nodeInfo {
+func (s *GovernanceStateHelper) node(index *big.Int) *nodeInfo {
node := new(nodeInfo)
arrayBaseLoc := s.getSlotLoc(big.NewInt(nodesLoc))
@@ -959,14 +970,14 @@ func (s *StateHelper) node(index *big.Int) *nodeInfo {
return nil
}
-func (s *StateHelper) pushNode(n *nodeInfo) {
+func (s *GovernanceStateHelper) pushNode(n *nodeInfo) {
// increase length by 1
arrayLength := s.nodesLength()
s.setStateBigInt(big.NewInt(nodesLoc), new(big.Int).Add(arrayLength, big.NewInt(1)))
s.updateNode(arrayLength, n)
}
-func (s *StateHelper) updateNode(index *big.Int, n *nodeInfo) {
+func (s *GovernanceStateHelper) updateNode(index *big.Int, n *nodeInfo) {
arrayBaseLoc := s.getSlotLoc(big.NewInt(nodesLoc))
elementBaseLoc := new(big.Int).Add(arrayBaseLoc, new(big.Int).Mul(index, big.NewInt(3)))
@@ -984,29 +995,29 @@ func (s *StateHelper) updateNode(index *big.Int, n *nodeInfo) {
}
// mapping(address => uint256) public offset;
-func (s *StateHelper) offset(addr common.Address) *big.Int {
+func (s *GovernanceStateHelper) offset(addr common.Address) *big.Int {
loc := s.getMapLoc(big.NewInt(offsetLoc), addr.Bytes())
return new(big.Int).Sub(s.getStateBigInt(loc), big.NewInt(1))
}
-func (s *StateHelper) putOffset(addr common.Address, offset *big.Int) {
+func (s *GovernanceStateHelper) putOffset(addr common.Address, offset *big.Int) {
loc := s.getMapLoc(big.NewInt(offsetLoc), addr.Bytes())
s.setStateBigInt(loc, new(big.Int).Add(offset, big.NewInt(1)))
}
-func (s *StateHelper) deleteOffset(addr common.Address) {
+func (s *GovernanceStateHelper) deleteOffset(addr common.Address) {
loc := s.getMapLoc(big.NewInt(offsetLoc), addr.Bytes())
s.setStateBigInt(loc, big.NewInt(0))
}
// bytes32[] public crs;
-func (s *StateHelper) lenCRS() *big.Int {
+func (s *GovernanceStateHelper) lenCRS() *big.Int {
return s.getStateBigInt(big.NewInt(crsLoc))
}
-func (s *StateHelper) crs(index *big.Int) common.Hash {
+func (s *GovernanceStateHelper) crs(index *big.Int) common.Hash {
baseLoc := s.getSlotLoc(big.NewInt(crsLoc))
loc := new(big.Int).Add(baseLoc, index)
return s.getState(common.BigToHash(loc))
}
-func (s *StateHelper) pushCRS(crs common.Hash) {
+func (s *GovernanceStateHelper) pushCRS(crs common.Hash) {
// increase length by 1.
length := s.getStateBigInt(big.NewInt(crsLoc))
s.setStateBigInt(big.NewInt(crsLoc), new(big.Int).Add(length, big.NewInt(1)))
@@ -1018,28 +1029,28 @@ func (s *StateHelper) pushCRS(crs common.Hash) {
}
// bytes[][] public dkgMasterPublicKeys;
-func (s *StateHelper) dkgMasterPublicKeys(round *big.Int) [][]byte {
+func (s *GovernanceStateHelper) dkgMasterPublicKeys(round *big.Int) [][]byte {
return s.read2DByteArray(big.NewInt(dkgMasterPublicKeysLoc), round)
}
-func (s *StateHelper) pushDKGMasterPublicKey(round *big.Int, pk []byte) {
+func (s *GovernanceStateHelper) pushDKGMasterPublicKey(round *big.Int, pk []byte) {
s.appendTo2DByteArray(big.NewInt(dkgMasterPublicKeysLoc), round, pk)
}
// bytes[][] public dkgComplaints;
-func (s *StateHelper) dkgComplaints(round *big.Int) [][]byte {
+func (s *GovernanceStateHelper) dkgComplaints(round *big.Int) [][]byte {
return s.read2DByteArray(big.NewInt(dkgComplaintsLoc), round)
}
-func (s *StateHelper) pushDKGComplaint(round *big.Int, complaint []byte) {
+func (s *GovernanceStateHelper) pushDKGComplaint(round *big.Int, complaint []byte) {
s.appendTo2DByteArray(big.NewInt(dkgComplaintsLoc), round, complaint)
}
// mapping(address => bool)[] public dkgFinalized;
-func (s *StateHelper) dkgFinalized(round *big.Int, addr common.Address) bool {
+func (s *GovernanceStateHelper) dkgFinalized(round *big.Int, addr common.Address) bool {
baseLoc := new(big.Int).Add(s.getSlotLoc(big.NewInt(dkgFinailizedLoc)), round)
mapLoc := s.getMapLoc(baseLoc, addr.Bytes())
return s.getStateBigInt(mapLoc).Cmp(big.NewInt(0)) != 0
}
-func (s *StateHelper) putDKGFinalized(round *big.Int, addr common.Address, finalized bool) {
+func (s *GovernanceStateHelper) putDKGFinalized(round *big.Int, addr common.Address, finalized bool) {
baseLoc := new(big.Int).Add(s.getSlotLoc(big.NewInt(dkgFinailizedLoc)), round)
mapLoc := s.getMapLoc(baseLoc, addr.Bytes())
res := big.NewInt(0)
@@ -1050,73 +1061,73 @@ func (s *StateHelper) putDKGFinalized(round *big.Int, addr common.Address, final
}
// uint256[] public dkgFinalizedsCount;
-func (s *StateHelper) dkgFinalizedsCount(round *big.Int) *big.Int {
+func (s *GovernanceStateHelper) dkgFinalizedsCount(round *big.Int) *big.Int {
loc := new(big.Int).Add(s.getSlotLoc(big.NewInt(dkgFinalizedsCountLoc)), round)
return s.getStateBigInt(loc)
}
-func (s *StateHelper) incDKGFinalizedsCount(round *big.Int) {
+func (s *GovernanceStateHelper) incDKGFinalizedsCount(round *big.Int) {
loc := new(big.Int).Add(s.getSlotLoc(big.NewInt(dkgFinalizedsCountLoc)), round)
count := s.getStateBigInt(loc)
s.setStateBigInt(loc, new(big.Int).Add(count, big.NewInt(1)))
}
// address public owner;
-func (s *StateHelper) owner() common.Address {
+func (s *GovernanceStateHelper) owner() common.Address {
val := s.getState(common.BigToHash(big.NewInt(ownerLoc)))
return common.BytesToAddress(val.Bytes())
}
// uint256 public numChains;
-func (s *StateHelper) numChains() *big.Int {
+func (s *GovernanceStateHelper) numChains() *big.Int {
return s.getStateBigInt(big.NewInt(numChainsLoc))
}
// uint256 public lambdaBA;
-func (s *StateHelper) lambdaBA() *big.Int {
+func (s *GovernanceStateHelper) lambdaBA() *big.Int {
return s.getStateBigInt(big.NewInt(lambdaBALoc))
}
// uint256 public lambdaDKG;
-func (s *StateHelper) lambdaDKG() *big.Int {
+func (s *GovernanceStateHelper) lambdaDKG() *big.Int {
return s.getStateBigInt(big.NewInt(lambdaDKGLoc))
}
// uint256 public k;
-func (s *StateHelper) k() *big.Int {
+func (s *GovernanceStateHelper) k() *big.Int {
return s.getStateBigInt(big.NewInt(kLoc))
}
// uint256 public phiRatio; // stored as PhiRatio * 10^6
-func (s *StateHelper) phiRatio() *big.Int {
+func (s *GovernanceStateHelper) phiRatio() *big.Int {
return s.getStateBigInt(big.NewInt(phiRatioLoc))
}
// uint256 public notarySetSize;
-func (s *StateHelper) notarySetSize() *big.Int {
+func (s *GovernanceStateHelper) notarySetSize() *big.Int {
return s.getStateBigInt(big.NewInt(notarySetSizeLoc))
}
// uint256 public dkgSetSize;
-func (s *StateHelper) dkgSetSize() *big.Int {
+func (s *GovernanceStateHelper) dkgSetSize() *big.Int {
return s.getStateBigInt(big.NewInt(dkgSetSizeLoc))
}
// uint256 public roundInterval
-func (s *StateHelper) roundInterval() *big.Int {
+func (s *GovernanceStateHelper) roundInterval() *big.Int {
return s.getStateBigInt(big.NewInt(roundIntervalLoc))
}
// uint256 public minBlockInterval
-func (s *StateHelper) minBlockInterval() *big.Int {
+func (s *GovernanceStateHelper) minBlockInterval() *big.Int {
return s.getStateBigInt(big.NewInt(minBlockIntervalLoc))
}
// uint256 public maxBlockInterval
-func (s *StateHelper) maxBlockInterval() *big.Int {
+func (s *GovernanceStateHelper) maxBlockInterval() *big.Int {
return s.getStateBigInt(big.NewInt(maxBlockIntervalLoc))
}
-func (s *StateHelper) emitConfigurationChangedEvent() {
+func (s *GovernanceStateHelper) emitConfigurationChangedEvent() {
s.StateDB.AddLog(&types.Log{
Address: s.Address,
Topics: []common.Hash{events["ConfigurationChanged"].Id()},
@@ -1124,7 +1135,7 @@ func (s *StateHelper) emitConfigurationChangedEvent() {
})
}
-func (s *StateHelper) emitCRSProposed(round *big.Int, crs common.Hash) {
+func (s *GovernanceStateHelper) emitCRSProposed(round *big.Int, crs common.Hash) {
s.StateDB.AddLog(&types.Log{
Address: s.Address,
Topics: []common.Hash{events["CRSProposed"].Id(), common.BigToHash(round)},
@@ -1135,14 +1146,14 @@ func (s *StateHelper) emitCRSProposed(round *big.Int, crs common.Hash) {
// GovernanceContract represents the governance contract of DEXCON.
type GovernanceContract struct {
evm *EVM
- state StateHelper
+ state GovernanceStateHelper
contract *Contract
}
func newGovernanceContract(evm *EVM, contract *Contract) *GovernanceContract {
return &GovernanceContract{
evm: evm,
- state: StateHelper{contract.Address(), evm.StateDB},
+ state: GovernanceStateHelper{contract.Address(), evm.StateDB},
contract: contract,
}
}