mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-08-20 02:42:27 +00:00
commit
702a8ed560
13 changed files with 609 additions and 83 deletions
|
|
@ -1256,6 +1256,7 @@ func MakeChain(ctx *cli.Context, stack *node.Node) (chain *core.BlockChain, chai
|
||||||
DatasetsOnDisk: eth.DefaultConfig.Ethash.DatasetsOnDisk,
|
DatasetsOnDisk: eth.DefaultConfig.Ethash.DatasetsOnDisk,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
Fatalf("Only support posv consensus")
|
||||||
}
|
}
|
||||||
if gcmode := ctx.GlobalString(GCModeFlag.Name); gcmode != "full" && gcmode != "archive" {
|
if gcmode := ctx.GlobalString(GCModeFlag.Name); gcmode != "full" && gcmode != "archive" {
|
||||||
Fatalf("--%s must be either 'full' or 'archive'", GCModeFlag.Name)
|
Fatalf("--%s must be either 'full' or 'archive'", GCModeFlag.Name)
|
||||||
|
|
|
||||||
|
|
@ -778,7 +778,7 @@ func (c *Posv) Prepare(chain consensus.ChainReader, header *types.Header) error
|
||||||
}
|
}
|
||||||
header.Extra = header.Extra[:extraVanity]
|
header.Extra = header.Extra[:extraVanity]
|
||||||
masternodes := snap.GetSigners()
|
masternodes := snap.GetSigners()
|
||||||
if number > 0 && number%c.config.Epoch == 0 {
|
if number >= c.config.Epoch && number%c.config.Epoch == 0 {
|
||||||
if c.HookPenalty != nil {
|
if c.HookPenalty != nil {
|
||||||
penMasternodes, err := c.HookPenalty(chain, number)
|
penMasternodes, err := c.HookPenalty(chain, number)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
||||||
33
contracts/blockSignerReader.go
Normal file
33
contracts/blockSignerReader.go
Normal file
|
|
@ -0,0 +1,33 @@
|
||||||
|
package contracts
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/ethereum/go-ethereum/common"
|
||||||
|
"github.com/ethereum/go-ethereum/core/state"
|
||||||
|
"github.com/ethereum/go-ethereum/core/types"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
slotBlockSignerMapping = map[string]uint64{
|
||||||
|
"blockSigners": 0,
|
||||||
|
"blocks": 1,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
func GetSigners(statedb *state.StateDB, block *types.Block) []common.Address {
|
||||||
|
slot := slotBlockSignerMapping["blockSigners"]
|
||||||
|
keys := []common.Hash{}
|
||||||
|
keyArrSlot := getLocMappingAtKey(block.Hash(), slot)
|
||||||
|
arrSlot := statedb.GetState(common.HexToAddress(common.BlockSigners), common.BigToHash(keyArrSlot))
|
||||||
|
arrLength := arrSlot.Big().Uint64()
|
||||||
|
for i := uint64(0); i < arrLength; i++ {
|
||||||
|
key := getLocDynamicArrAtElement(common.BigToHash(keyArrSlot), i, 1)
|
||||||
|
keys = append(keys, key)
|
||||||
|
}
|
||||||
|
rets := []common.Address{}
|
||||||
|
for _, key := range keys {
|
||||||
|
ret := statedb.GetState(common.HexToAddress(common.BlockSigners), key)
|
||||||
|
rets = append(rets, common.HexToAddress(ret.Hex()))
|
||||||
|
}
|
||||||
|
|
||||||
|
return rets
|
||||||
|
}
|
||||||
37
contracts/randomizeReader.go
Normal file
37
contracts/randomizeReader.go
Normal file
|
|
@ -0,0 +1,37 @@
|
||||||
|
package contracts
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/ethereum/go-ethereum/common"
|
||||||
|
"github.com/ethereum/go-ethereum/core/state"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
slotRandomizeMapping = map[string]uint64{
|
||||||
|
"randomSecret": 0,
|
||||||
|
"randomOpening": 1,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
func GetSecret(statedb *state.StateDB, address common.Address) [][32]byte {
|
||||||
|
slot := slotRandomizeMapping["randomSecret"]
|
||||||
|
locSecret := getLocMappingAtKey(address.Hash(), slot)
|
||||||
|
arrLength := statedb.GetState(common.HexToAddress(common.RandomizeSMC), common.BigToHash(locSecret))
|
||||||
|
keys := []common.Hash{}
|
||||||
|
for i := uint64(0); i < arrLength.Big().Uint64(); i++ {
|
||||||
|
key := getLocDynamicArrAtElement(common.BigToHash(locSecret), i, 1)
|
||||||
|
keys = append(keys, key)
|
||||||
|
}
|
||||||
|
rets := [][32]byte{}
|
||||||
|
for _, key := range keys {
|
||||||
|
ret := statedb.GetState(common.HexToAddress(common.RandomizeSMC), key)
|
||||||
|
rets = append(rets, ret)
|
||||||
|
}
|
||||||
|
return rets
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetOpening(statedb *state.StateDB, address common.Address) [32]byte {
|
||||||
|
slot := slotRandomizeMapping["randomOpening"]
|
||||||
|
locOpening := getLocMappingAtKey(address.Hash(), slot)
|
||||||
|
ret := statedb.GetState(common.HexToAddress(common.RandomizeSMC), common.BigToHash(locOpening))
|
||||||
|
return ret
|
||||||
|
}
|
||||||
34
contracts/smcUtils.go
Normal file
34
contracts/smcUtils.go
Normal file
|
|
@ -0,0 +1,34 @@
|
||||||
|
package contracts
|
||||||
|
|
||||||
|
import (
|
||||||
|
"math/big"
|
||||||
|
|
||||||
|
"github.com/ethereum/go-ethereum/common"
|
||||||
|
"github.com/ethereum/go-ethereum/crypto"
|
||||||
|
)
|
||||||
|
|
||||||
|
func getLocSimpleVariable(slot uint64) common.Hash {
|
||||||
|
slotHash := common.BigToHash(new(big.Int).SetUint64(slot))
|
||||||
|
return slotHash
|
||||||
|
}
|
||||||
|
|
||||||
|
func getLocMappingAtKey(key common.Hash, slot uint64) *big.Int {
|
||||||
|
slotHash := common.BigToHash(new(big.Int).SetUint64(slot))
|
||||||
|
retByte := crypto.Keccak256(key.Bytes(), slotHash.Bytes())
|
||||||
|
ret := new(big.Int)
|
||||||
|
ret.SetBytes(retByte)
|
||||||
|
return ret
|
||||||
|
}
|
||||||
|
|
||||||
|
func getLocDynamicArrAtElement(slotHash common.Hash, index uint64, elementSize uint64) common.Hash {
|
||||||
|
slotKecBig := crypto.Keccak256Hash(slotHash.Bytes()).Big()
|
||||||
|
//arrBig = slotKecBig + index * elementSize
|
||||||
|
arrBig := slotKecBig.Add(slotKecBig, new(big.Int).SetUint64(index*elementSize))
|
||||||
|
return common.BigToHash(arrBig)
|
||||||
|
}
|
||||||
|
|
||||||
|
func getLocFixedArrAtElement(slot uint64, index uint64, elementSize uint64) common.Hash {
|
||||||
|
slotBig := new(big.Int).SetUint64(slot)
|
||||||
|
arrBig := slotBig.Add(slotBig, new(big.Int).SetUint64(index*elementSize))
|
||||||
|
return common.BigToHash(arrBig)
|
||||||
|
}
|
||||||
281
contracts/test.go
Normal file
281
contracts/test.go
Normal file
|
|
@ -0,0 +1,281 @@
|
||||||
|
package contracts
|
||||||
|
//
|
||||||
|
//import (
|
||||||
|
// "fmt"
|
||||||
|
// "math/big"
|
||||||
|
// "time"
|
||||||
|
//
|
||||||
|
// "github.com/ethereum/go-ethereum/common"
|
||||||
|
// "github.com/ethereum/go-ethereum/core"
|
||||||
|
// "github.com/ethereum/go-ethereum/core/state"
|
||||||
|
// "github.com/ethereum/go-ethereum/crypto"
|
||||||
|
// "github.com/ethereum/go-ethereum/ethdb"
|
||||||
|
// "github.com/ethereum/go-ethereum/core/types"
|
||||||
|
//)
|
||||||
|
//
|
||||||
|
//var (
|
||||||
|
// slotValidatorMapping = map[string]uint64{
|
||||||
|
// "withdrawsState": 0,
|
||||||
|
// "validatorsState": 1,
|
||||||
|
// "voters": 2,
|
||||||
|
// "candidates": 3,
|
||||||
|
// "candidateCount": 4,
|
||||||
|
// "minCandidateCap": 5,
|
||||||
|
// "minVoterCap": 6,
|
||||||
|
// "maxValidatorNumber": 7,
|
||||||
|
// "candidateWithdrawDelay": 8,
|
||||||
|
// "voterWithdrawDelay": 9,
|
||||||
|
// }
|
||||||
|
// slotBlockSignerMapping = map[string]uint64{
|
||||||
|
// "blockSigners": 0,
|
||||||
|
// "blocks": 1,
|
||||||
|
// }
|
||||||
|
// slotRandomizeMapping = map[string]uint64{
|
||||||
|
// "randomSecret": 0,
|
||||||
|
// "randomOpening": 1,
|
||||||
|
// }
|
||||||
|
// datadir = "/mnt/sgp1_tuna_chaindata3/data/tomo/chaindata"
|
||||||
|
// candidate = "0xd6fa3e7a89bf8c84f0ccd204a15c0d259daf2091"
|
||||||
|
//)
|
||||||
|
//
|
||||||
|
//func main() {
|
||||||
|
// //Init
|
||||||
|
// chaindb, err := ethdb.NewLDBDatabase(datadir, 0, 0)
|
||||||
|
// if err != nil || chaindb == nil {
|
||||||
|
// fmt.Printf("Can't get chaindb: %v", err)
|
||||||
|
// return
|
||||||
|
// }
|
||||||
|
// headHash := core.GetHeadBlockHash(chaindb)
|
||||||
|
// blockNumber := core.GetBlockNumber(chaindb, headHash)
|
||||||
|
// block := core.GetBlock(chaindb, headHash, blockNumber)
|
||||||
|
// if block == nil {
|
||||||
|
// fmt.Println("Can't get head block")
|
||||||
|
// return
|
||||||
|
// }
|
||||||
|
// database := state.NewDatabase(chaindb)
|
||||||
|
// headerRootHash := block.Header().Root
|
||||||
|
// headHeaderHash := core.GetHeadHeaderHash(chaindb)
|
||||||
|
// statedb, _ := state.New(headHeaderHash, database)
|
||||||
|
// if statedb == nil {
|
||||||
|
// headHeaderHash = headerRootHash
|
||||||
|
// }
|
||||||
|
// candidateAddress := common.HexToAddress(candidate)
|
||||||
|
// fmt.Printf("Block head :%d, header root:%v\n", blockNumber, headerRootHash.Hex())
|
||||||
|
// statedb, _ = state.New(headHeaderHash, database)
|
||||||
|
// if statedb == nil {
|
||||||
|
// fmt.Println("Can't get state db")
|
||||||
|
// return
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// //GetCandidates
|
||||||
|
// _ = GetCandidates(statedb)
|
||||||
|
//
|
||||||
|
// //GetCandidateOwner
|
||||||
|
// _ = GetCandidateOwner(statedb, candidateAddress)
|
||||||
|
//
|
||||||
|
// //GetCandidateCap
|
||||||
|
// _ = GetCandidateCap(statedb, candidateAddress)
|
||||||
|
//
|
||||||
|
// //GetVoters
|
||||||
|
// voters := GetVoters(statedb, candidateAddress)
|
||||||
|
//
|
||||||
|
// start := time.Now()
|
||||||
|
// fmt.Printf("--------GetVoterCap---------\n")
|
||||||
|
// for _, voter := range voters {
|
||||||
|
// //GetVoterCap
|
||||||
|
// _ = GetVoterCap(statedb, candidateAddress, voter)
|
||||||
|
// }
|
||||||
|
// elapsed := time.Since(start)
|
||||||
|
// fmt.Printf("Execution time: %s\n", elapsed)
|
||||||
|
//
|
||||||
|
// //GetSigners
|
||||||
|
// blockInput := core.GetBlock(chaindb, common.HexToHash("0x632f2403ea19697082d794900275632eb3373f7a9943b1407461995bbbc2816a"), uint64(1800))
|
||||||
|
// _ = GetSigners(statedb, blockInput)
|
||||||
|
//
|
||||||
|
// //GetOpening
|
||||||
|
// _ = GetOpening(statedb, candidateAddress)
|
||||||
|
// //GetSecret
|
||||||
|
// _ = GetSecret(statedb, candidateAddress)
|
||||||
|
//}
|
||||||
|
//
|
||||||
|
//func GetCandidates(statedb *state.StateDB) []common.Address {
|
||||||
|
// start := time.Now()
|
||||||
|
// fmt.Printf("--------GetCandidates---------\n")
|
||||||
|
//
|
||||||
|
// slot := slotValidatorMapping["candidates"]
|
||||||
|
// slotHash := common.BigToHash(new(big.Int).SetUint64(slot))
|
||||||
|
// arrLength := statedb.GetState(common.HexToAddress(common.MasternodeVotingSMC), slotHash)
|
||||||
|
// fmt.Printf("Candidates length: %v\n", arrLength.Hex())
|
||||||
|
// keys := []common.Hash{}
|
||||||
|
// for i := uint64(0); i < arrLength.Big().Uint64(); i++ {
|
||||||
|
// key := getLocDynamicArrAtElement(slotHash, i, 1)
|
||||||
|
// keys = append(keys, key)
|
||||||
|
// }
|
||||||
|
// rets := []common.Address{}
|
||||||
|
// for _, key := range keys {
|
||||||
|
// ret := statedb.GetState(common.HexToAddress(common.MasternodeVotingSMC), key)
|
||||||
|
// rets = append(rets, common.HexToAddress(ret.Hex()))
|
||||||
|
// fmt.Printf("%v\n", common.HexToAddress(ret.Hex()).Hex())
|
||||||
|
// }
|
||||||
|
// elapsed := time.Since(start)
|
||||||
|
// fmt.Printf("Execution time: %s\n", elapsed)
|
||||||
|
// return rets
|
||||||
|
//}
|
||||||
|
//
|
||||||
|
//func GetCandidateOwner(statedb *state.StateDB, candidate common.Address) common.Address {
|
||||||
|
// start := time.Now()
|
||||||
|
// fmt.Printf("--------GetCandidateOwner---------\n")
|
||||||
|
//
|
||||||
|
// slot := slotValidatorMapping["validatorsState"]
|
||||||
|
// // validatorsState[_candidate].owner;
|
||||||
|
// locValidatorsState := getLocMappingAtKey(candidate.Hash(), slot)
|
||||||
|
// locCandidateOwner := locValidatorsState.Add(locValidatorsState, new(big.Int).SetUint64(uint64(0)))
|
||||||
|
// ret := statedb.GetState(common.HexToAddress(common.MasternodeVotingSMC), common.BigToHash(locCandidateOwner))
|
||||||
|
// fmt.Printf("ret: %v\n", common.HexToAddress(ret.Hex()).Hex())
|
||||||
|
//
|
||||||
|
// elapsed := time.Since(start)
|
||||||
|
// fmt.Printf("Execution time: %s\n", elapsed)
|
||||||
|
// return common.HexToAddress(ret.Hex())
|
||||||
|
//}
|
||||||
|
//
|
||||||
|
//func GetCandidateCap(statedb *state.StateDB, candidate common.Address) string {
|
||||||
|
// start := time.Now()
|
||||||
|
// fmt.Printf("--------GetCandidateCap---------\n")
|
||||||
|
//
|
||||||
|
// slot := slotValidatorMapping["validatorsState"]
|
||||||
|
// // validatorsState[_candidate].cap;
|
||||||
|
// locValidatorsState := getLocMappingAtKey(candidate.Hash(), slot)
|
||||||
|
// locCandidateCap := locValidatorsState.Add(locValidatorsState, new(big.Int).SetUint64(uint64(1)))
|
||||||
|
// ret := statedb.GetState(common.HexToAddress(common.MasternodeVotingSMC), common.BigToHash(locCandidateCap))
|
||||||
|
// fmt.Printf("cap: %v\n", ret.Big().String())
|
||||||
|
//
|
||||||
|
// elapsed := time.Since(start)
|
||||||
|
// fmt.Printf("Execution time: %s\n", elapsed)
|
||||||
|
// return ret.Hex()
|
||||||
|
//}
|
||||||
|
//
|
||||||
|
//func GetVoterCap(state *state.StateDB, candidate, voter common.Address) *big.Int {
|
||||||
|
// //validatorsState[_candidate].voters[_voter]
|
||||||
|
// slot := slotValidatorMapping["validatorsState"]
|
||||||
|
// locValidatorsState := getLocMappingAtKey(candidate.Hash(), slot)
|
||||||
|
// locCandidateVoters := locValidatorsState.Add(locValidatorsState, new(big.Int).SetUint64(uint64(2)))
|
||||||
|
// retByte := crypto.Keccak256(voter.Hash().Bytes(), common.BigToHash(locCandidateVoters).Bytes())
|
||||||
|
// ret := state.GetState(common.HexToAddress(common.MasternodeVotingSMC), common.BytesToHash(retByte))
|
||||||
|
// fmt.Printf("voter: %v - cap: %v\n", voter.Hex(), ret.Big().String())
|
||||||
|
// return ret.Big()
|
||||||
|
//}
|
||||||
|
//
|
||||||
|
//func GetVoters(statedb *state.StateDB, candidate common.Address) []common.Address {
|
||||||
|
// start := time.Now()
|
||||||
|
// fmt.Printf("--------GetVoters---------\n")
|
||||||
|
//
|
||||||
|
// //mapping(address => address[]) voters;
|
||||||
|
// slot := slotValidatorMapping["voters"]
|
||||||
|
// locVoters := getLocMappingAtKey(candidate.Hash(), slot)
|
||||||
|
// arrLength := statedb.GetState(common.HexToAddress(common.MasternodeVotingSMC), common.BigToHash(locVoters))
|
||||||
|
// fmt.Printf("Voters length: %v\n", arrLength.Hex())
|
||||||
|
// keys := []common.Hash{}
|
||||||
|
// for i := uint64(0); i < arrLength.Big().Uint64(); i++ {
|
||||||
|
// key := getLocDynamicArrAtElement(common.BigToHash(locVoters), i, 1)
|
||||||
|
// keys = append(keys, key)
|
||||||
|
// }
|
||||||
|
// rets := []common.Address{}
|
||||||
|
// for _, key := range keys {
|
||||||
|
// ret := statedb.GetState(common.HexToAddress(common.MasternodeVotingSMC), key)
|
||||||
|
// rets = append(rets, common.HexToAddress(ret.Hex()))
|
||||||
|
// fmt.Printf("%v\n", common.HexToAddress(ret.Hex()).Hex())
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// elapsed := time.Since(start)
|
||||||
|
// fmt.Printf("Execution time: %s\n", elapsed)
|
||||||
|
// return rets
|
||||||
|
//}
|
||||||
|
//
|
||||||
|
//func GetSigners(statedb *state.StateDB, block *types.Block) []common.Address {
|
||||||
|
// methodName := "getSigners"
|
||||||
|
// fmt.Printf("---%s---\n", methodName)
|
||||||
|
// start := time.Now()
|
||||||
|
// slot := slotBlockSignerMapping["blockSigners"]
|
||||||
|
// keys := []common.Hash{}
|
||||||
|
// keyArrSlot := getLocMappingAtKey(block.Hash(), slot)
|
||||||
|
// arrSlot := statedb.GetState(common.HexToAddress(common.BlockSigners), common.BigToHash(keyArrSlot))
|
||||||
|
// arrLength := arrSlot.Big().Uint64()
|
||||||
|
// for i := uint64(0); i < arrLength; i++ {
|
||||||
|
// key := getLocDynamicArrAtElement(common.BigToHash(keyArrSlot), i, 1)
|
||||||
|
// keys = append(keys, key)
|
||||||
|
// }
|
||||||
|
// rets := []common.Address{}
|
||||||
|
// for _, key := range keys {
|
||||||
|
// ret := statedb.GetState(common.HexToAddress(common.BlockSigners), key)
|
||||||
|
// rets = append(rets, common.HexToAddress(ret.Hex()))
|
||||||
|
// fmt.Printf("%v\n", common.HexToAddress(ret.Hex()).Hex())
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// elapsed := time.Since(start)
|
||||||
|
// fmt.Printf("Execution time: %s\n", elapsed)
|
||||||
|
// return rets
|
||||||
|
//}
|
||||||
|
//
|
||||||
|
//func GetSecret(statedb *state.StateDB, address common.Address) [][32]byte {
|
||||||
|
// start := time.Now()
|
||||||
|
// fmt.Printf("--------GetSecret---------\n")
|
||||||
|
//
|
||||||
|
// slot := slotRandomizeMapping["randomSecret"]
|
||||||
|
// locSecret := getLocMappingAtKey(address.Hash(), slot)
|
||||||
|
// arrLength := statedb.GetState(common.HexToAddress(common.RandomizeSMC), common.BigToHash(locSecret))
|
||||||
|
// fmt.Printf("Secret length: %v\n", arrLength.Hex())
|
||||||
|
// keys := []common.Hash{}
|
||||||
|
// for i := uint64(0); i < arrLength.Big().Uint64(); i++ {
|
||||||
|
// key := getLocDynamicArrAtElement(common.BigToHash(locSecret), i, 1)
|
||||||
|
// keys = append(keys, key)
|
||||||
|
// }
|
||||||
|
// rets := [][32]byte{}
|
||||||
|
// for _, key := range keys {
|
||||||
|
// ret := statedb.GetState(common.HexToAddress(common.RandomizeSMC), key)
|
||||||
|
// rets = append(rets, ret)
|
||||||
|
// fmt.Printf("ret hex: %v - ret byte: %v\n", ret.Hex(), ret.Bytes())
|
||||||
|
// }
|
||||||
|
// elapsed := time.Since(start)
|
||||||
|
//
|
||||||
|
// fmt.Printf("Execution time: %s\n", elapsed)
|
||||||
|
// return rets
|
||||||
|
//}
|
||||||
|
//
|
||||||
|
//func GetOpening(statedb *state.StateDB, address common.Address) [32]byte {
|
||||||
|
// start := time.Now()
|
||||||
|
// fmt.Printf("--------GetOpening---------\n")
|
||||||
|
//
|
||||||
|
// slot := slotRandomizeMapping["randomOpening"]
|
||||||
|
// locOpening := getLocMappingAtKey(address.Hash(), slot)
|
||||||
|
// ret := statedb.GetState(common.HexToAddress(common.RandomizeSMC), common.BigToHash(locOpening))
|
||||||
|
// fmt.Printf("ret hex: %v - ret byte: %v\n", ret.Hex(), ret.Bytes())
|
||||||
|
// elapsed := time.Since(start)
|
||||||
|
// fmt.Printf("Execution time: %s\n", elapsed)
|
||||||
|
// return ret
|
||||||
|
//}
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//////////////////////////////////////
|
||||||
|
///////////// Common lib /////////////
|
||||||
|
//////////////////////////////////////
|
||||||
|
//
|
||||||
|
//func getLocMappingAtKey(key common.Hash, slot uint64) *big.Int {
|
||||||
|
// slotHash := common.BigToHash(new(big.Int).SetUint64(slot))
|
||||||
|
// retByte := crypto.Keccak256(key.Bytes(), slotHash.Bytes())
|
||||||
|
// ret := new(big.Int)
|
||||||
|
// ret.SetBytes(retByte)
|
||||||
|
// return ret
|
||||||
|
//}
|
||||||
|
//
|
||||||
|
//func getLocDynamicArrAtElement(slotHash common.Hash, index uint64, elementSize uint64) common.Hash {
|
||||||
|
// slotKecBig := crypto.Keccak256Hash(slotHash.Bytes()).Big()
|
||||||
|
// //arrBig = slotKecBig + index * elementSize
|
||||||
|
// arrBig := slotKecBig.Add(slotKecBig, new(big.Int).SetUint64(index*elementSize))
|
||||||
|
// return common.BigToHash(arrBig)
|
||||||
|
//}
|
||||||
|
//
|
||||||
|
//func getLocFixedArrAtElement(slot uint64, index uint64, elementSize uint64) common.Hash {
|
||||||
|
// slotBig := new(big.Int).SetUint64(slot)
|
||||||
|
// arrBig := slotBig.Add(slotBig, new(big.Int).SetUint64(index*elementSize))
|
||||||
|
// return common.BigToHash(arrBig)
|
||||||
|
//}
|
||||||
|
|
@ -31,20 +31,19 @@ import (
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/ethereum/go-ethereum/accounts"
|
"github.com/ethereum/go-ethereum/accounts"
|
||||||
"github.com/ethereum/go-ethereum/accounts/abi/bind"
|
|
||||||
"github.com/ethereum/go-ethereum/common"
|
"github.com/ethereum/go-ethereum/common"
|
||||||
"github.com/ethereum/go-ethereum/common/hexutil"
|
"github.com/ethereum/go-ethereum/common/hexutil"
|
||||||
"github.com/ethereum/go-ethereum/consensus"
|
"github.com/ethereum/go-ethereum/consensus"
|
||||||
"github.com/ethereum/go-ethereum/consensus/posv"
|
"github.com/ethereum/go-ethereum/consensus/posv"
|
||||||
"github.com/ethereum/go-ethereum/contracts/blocksigner/contract"
|
|
||||||
randomizeContract "github.com/ethereum/go-ethereum/contracts/randomize/contract"
|
|
||||||
contractValidator "github.com/ethereum/go-ethereum/contracts/validator/contract"
|
|
||||||
"github.com/ethereum/go-ethereum/core"
|
"github.com/ethereum/go-ethereum/core"
|
||||||
"github.com/ethereum/go-ethereum/core/state"
|
"github.com/ethereum/go-ethereum/core/state"
|
||||||
"github.com/ethereum/go-ethereum/core/types"
|
"github.com/ethereum/go-ethereum/core/types"
|
||||||
"github.com/ethereum/go-ethereum/ethdb"
|
"github.com/ethereum/go-ethereum/ethdb"
|
||||||
"github.com/ethereum/go-ethereum/log"
|
"github.com/ethereum/go-ethereum/log"
|
||||||
"github.com/ethereum/go-ethereum/params"
|
"github.com/ethereum/go-ethereum/params"
|
||||||
|
"github.com/ethereum/go-ethereum/accounts/abi/bind"
|
||||||
|
"github.com/ethereum/go-ethereum/contracts/blocksigner/contract"
|
||||||
|
randomizeContract "github.com/ethereum/go-ethereum/contracts/randomize/contract"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
|
@ -199,7 +198,12 @@ func BuildTxOpeningRandomize(nonce uint64, randomizeAddr common.Address, randomi
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get signers signed for blockNumber from blockSigner contract.
|
// Get signers signed for blockNumber from blockSigner contract.
|
||||||
func GetSignersFromContract(addrBlockSigner common.Address, client bind.ContractBackend, blockHash common.Hash) ([]common.Address, error) {
|
func GetSignersFromContract(state *state.StateDB, block *types.Block) ([]common.Address, error) {
|
||||||
|
return GetSigners(state, block), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get signers signed for blockNumber from blockSigner contract.
|
||||||
|
func GetSignersFromContract1(addrBlockSigner common.Address, client bind.ContractBackend, blockHash common.Hash) ([]common.Address, error) {
|
||||||
blockSigner, err := contract.NewBlockSigner(addrBlockSigner, client)
|
blockSigner, err := contract.NewBlockSigner(addrBlockSigner, client)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error("Fail get instance of blockSigner", "error", err)
|
log.Error("Fail get instance of blockSigner", "error", err)
|
||||||
|
|
@ -219,18 +223,15 @@ func GetRandomizeFromContract(client bind.ContractBackend, addrMasternode common
|
||||||
randomize, err := randomizeContract.NewTomoRandomize(common.HexToAddress(common.RandomizeSMC), client)
|
randomize, err := randomizeContract.NewTomoRandomize(common.HexToAddress(common.RandomizeSMC), client)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error("Fail to get instance of randomize", "error", err)
|
log.Error("Fail to get instance of randomize", "error", err)
|
||||||
return -1, err
|
|
||||||
}
|
}
|
||||||
opts := new(bind.CallOpts)
|
opts := new(bind.CallOpts)
|
||||||
secrets, err := randomize.GetSecret(opts, addrMasternode)
|
secrets, err := randomize.GetSecret(opts, addrMasternode)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error("Fail get secrets from randomize", "error", err)
|
log.Error("Fail get secrets from randomize", "error", err)
|
||||||
return -1, err
|
|
||||||
}
|
}
|
||||||
opening, err := randomize.GetOpening(opts, addrMasternode)
|
opening, err := randomize.GetOpening(opts, addrMasternode)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error("Fail get opening from randomize", "error", err)
|
log.Error("Fail get opening from randomize", "error", err)
|
||||||
return -1, err
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return DecryptRandomizeFromSecretsAndOpening(secrets, opening)
|
return DecryptRandomizeFromSecretsAndOpening(secrets, opening)
|
||||||
|
|
@ -420,46 +421,28 @@ func CalculateRewardForSigner(chainReward *big.Int, signers map[common.Address]*
|
||||||
return resultSigners, nil
|
return resultSigners, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func GetCandidatesOwnerBySigner(validator *contractValidator.TomoValidator, signerAddr common.Address) common.Address {
|
// Get candidate owner by address.
|
||||||
owner := signerAddr
|
func GetCandidatesOwnerBySigner(state *state.StateDB, signerAddr common.Address) common.Address {
|
||||||
opts := new(bind.CallOpts)
|
owner := GetCandidateOwner(state, signerAddr)
|
||||||
owner, err := validator.GetCandidateOwner(opts, signerAddr)
|
|
||||||
if err != nil {
|
|
||||||
log.Error("Fail get candidate owner", "error", err)
|
|
||||||
return owner
|
return owner
|
||||||
}
|
}
|
||||||
|
|
||||||
return owner
|
func CalculateRewardForHolders(foundationWalletAddr common.Address, state *state.StateDB, signer common.Address, calcReward *big.Int) (error, map[common.Address]*big.Int) {
|
||||||
}
|
rewards, err := GetRewardBalancesRate(foundationWalletAddr, state, signer, calcReward)
|
||||||
|
|
||||||
// Calculate reward for holders.
|
|
||||||
func CalculateRewardForHolders(foudationWalletAddr common.Address, validator *contractValidator.TomoValidator, state *state.StateDB, signer common.Address, calcReward *big.Int) (error, map[common.Address]*big.Int) {
|
|
||||||
rewards, err := GetRewardBalancesRate(foudationWalletAddr, signer, calcReward, validator)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err, nil
|
return err, nil
|
||||||
}
|
}
|
||||||
if len(rewards) > 0 {
|
|
||||||
for holder, reward := range rewards {
|
|
||||||
state.AddBalance(holder, reward)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return nil, rewards
|
return nil, rewards
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get reward balance rates for master node, founder and holders.
|
func GetRewardBalancesRate(foundationWalletAddr common.Address, state *state.StateDB, masterAddr common.Address, totalReward *big.Int) (map[common.Address]*big.Int, error) {
|
||||||
func GetRewardBalancesRate(foudationWalletAddr common.Address, masterAddr common.Address, totalReward *big.Int, validator *contractValidator.TomoValidator) (map[common.Address]*big.Int, error) {
|
owner := GetCandidatesOwnerBySigner(state, masterAddr)
|
||||||
owner := GetCandidatesOwnerBySigner(validator, masterAddr)
|
|
||||||
balances := make(map[common.Address]*big.Int)
|
balances := make(map[common.Address]*big.Int)
|
||||||
rewardMaster := new(big.Int).Mul(totalReward, new(big.Int).SetInt64(common.RewardMasterPercent))
|
rewardMaster := new(big.Int).Mul(totalReward, new(big.Int).SetInt64(common.RewardMasterPercent))
|
||||||
rewardMaster = new(big.Int).Div(rewardMaster, new(big.Int).SetInt64(100))
|
rewardMaster = new(big.Int).Div(rewardMaster, new(big.Int).SetInt64(100))
|
||||||
balances[owner] = rewardMaster
|
balances[owner] = rewardMaster
|
||||||
// Get voters for masternode.
|
// Get voters for masternode.
|
||||||
opts := new(bind.CallOpts)
|
voters := GetVoters(state, masterAddr)
|
||||||
voters, err := validator.GetVoters(opts, masterAddr)
|
|
||||||
if err != nil {
|
|
||||||
log.Crit("Fail to get voters", "error", err)
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(voters) > 0 {
|
if len(voters) > 0 {
|
||||||
totalVoterReward := new(big.Int).Mul(totalReward, new(big.Int).SetUint64(common.RewardVoterPercent))
|
totalVoterReward := new(big.Int).Mul(totalReward, new(big.Int).SetUint64(common.RewardVoterPercent))
|
||||||
|
|
@ -468,13 +451,7 @@ func GetRewardBalancesRate(foudationWalletAddr common.Address, masterAddr common
|
||||||
// Get voters capacities.
|
// Get voters capacities.
|
||||||
voterCaps := make(map[common.Address]*big.Int)
|
voterCaps := make(map[common.Address]*big.Int)
|
||||||
for _, voteAddr := range voters {
|
for _, voteAddr := range voters {
|
||||||
var voterCap *big.Int
|
voterCap := GetVoterCap(state, masterAddr, voteAddr)
|
||||||
|
|
||||||
voterCap, err = validator.GetVoterCap(opts, masterAddr, voteAddr)
|
|
||||||
if err != nil {
|
|
||||||
log.Crit("Fail to get vote capacity", "error", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
totalCap.Add(totalCap, voterCap)
|
totalCap.Add(totalCap, voterCap)
|
||||||
voterCaps[voteAddr] = voterCap
|
voterCaps[voteAddr] = voterCap
|
||||||
}
|
}
|
||||||
|
|
@ -494,9 +471,9 @@ func GetRewardBalancesRate(foudationWalletAddr common.Address, masterAddr common
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
foudationReward := new(big.Int).Mul(totalReward, new(big.Int).SetInt64(common.RewardFoundationPercent))
|
foundationReward := new(big.Int).Mul(totalReward, new(big.Int).SetInt64(common.RewardFoundationPercent))
|
||||||
foudationReward = new(big.Int).Div(foudationReward, new(big.Int).SetInt64(100))
|
foundationReward = new(big.Int).Div(foundationReward, new(big.Int).SetInt64(100))
|
||||||
balances[foudationWalletAddr] = foudationReward
|
balances[foundationWalletAddr] = foundationReward
|
||||||
|
|
||||||
jsonHolders, err := json.Marshal(balances)
|
jsonHolders, err := json.Marshal(balances)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
||||||
|
|
@ -20,15 +20,16 @@ import (
|
||||||
"math/big"
|
"math/big"
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
"math/rand"
|
||||||
|
"encoding/json"
|
||||||
|
|
||||||
"github.com/ethereum/go-ethereum/accounts/abi/bind"
|
"github.com/ethereum/go-ethereum/accounts/abi/bind"
|
||||||
"github.com/ethereum/go-ethereum/accounts/abi/bind/backends"
|
"github.com/ethereum/go-ethereum/accounts/abi/bind/backends"
|
||||||
"github.com/ethereum/go-ethereum/common"
|
"github.com/ethereum/go-ethereum/common"
|
||||||
"github.com/ethereum/go-ethereum/contracts"
|
contractValidator "github.com/ethereum/go-ethereum/contracts/validator/contract"
|
||||||
"github.com/ethereum/go-ethereum/contracts/validator/contract"
|
|
||||||
"github.com/ethereum/go-ethereum/core"
|
"github.com/ethereum/go-ethereum/core"
|
||||||
"github.com/ethereum/go-ethereum/crypto"
|
"github.com/ethereum/go-ethereum/crypto"
|
||||||
"math/rand"
|
"github.com/ethereum/go-ethereum/log"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
|
@ -94,7 +95,7 @@ func TestRewardBalance(t *testing.T) {
|
||||||
// validatorAddr, _, baseValidator, err := contract.DeployTomoValidator(transactOpts, contractBackend, big.NewInt(50000), big.NewInt(99), big.NewInt(100), big.NewInt(100))
|
// validatorAddr, _, baseValidator, err := contract.DeployTomoValidator(transactOpts, contractBackend, big.NewInt(50000), big.NewInt(99), big.NewInt(100), big.NewInt(100))
|
||||||
validatorCap := new(big.Int)
|
validatorCap := new(big.Int)
|
||||||
validatorCap.SetString("50000000000000000000000", 10)
|
validatorCap.SetString("50000000000000000000000", 10)
|
||||||
validatorAddr, _, baseValidator, err := contract.DeployTomoValidator(
|
validatorAddr, _, baseValidator, err := contractValidator.DeployTomoValidator(
|
||||||
transactOpts,
|
transactOpts,
|
||||||
contractBackend,
|
contractBackend,
|
||||||
[]common.Address{addr},
|
[]common.Address{addr},
|
||||||
|
|
@ -144,7 +145,7 @@ func TestRewardBalance(t *testing.T) {
|
||||||
|
|
||||||
foundationAddr := common.HexToAddress(common.FoudationAddr)
|
foundationAddr := common.HexToAddress(common.FoudationAddr)
|
||||||
totalReward := new(big.Int).SetInt64(15 * 1000)
|
totalReward := new(big.Int).SetInt64(15 * 1000)
|
||||||
rewards, err := contracts.GetRewardBalancesRate(foundationAddr, acc3Addr, totalReward, baseValidator)
|
rewards, err := GetRewardBalancesRate(foundationAddr, acc3Addr, totalReward, baseValidator)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Error("Fail to get reward balances rate.", err)
|
t.Error("Fail to get reward balances rate.", err)
|
||||||
}
|
}
|
||||||
|
|
@ -175,3 +176,76 @@ func TestRewardBalance(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func GetRewardBalancesRate(foudationWalletAddr common.Address, masterAddr common.Address, totalReward *big.Int, validator *contractValidator.TomoValidator) (map[common.Address]*big.Int, error) {
|
||||||
|
owner := GetCandidatesOwnerBySigner(validator, masterAddr)
|
||||||
|
balances := make(map[common.Address]*big.Int)
|
||||||
|
rewardMaster := new(big.Int).Mul(totalReward, new(big.Int).SetInt64(common.RewardMasterPercent))
|
||||||
|
rewardMaster = new(big.Int).Div(rewardMaster, new(big.Int).SetInt64(100))
|
||||||
|
balances[owner] = rewardMaster
|
||||||
|
// Get voters for masternode.
|
||||||
|
opts := new(bind.CallOpts)
|
||||||
|
voters, err := validator.GetVoters(opts, masterAddr)
|
||||||
|
if err != nil {
|
||||||
|
log.Crit("Fail to get voters", "error", err)
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(voters) > 0 {
|
||||||
|
totalVoterReward := new(big.Int).Mul(totalReward, new(big.Int).SetUint64(common.RewardVoterPercent))
|
||||||
|
totalVoterReward = new(big.Int).Div(totalVoterReward, new(big.Int).SetUint64(100))
|
||||||
|
totalCap := new(big.Int)
|
||||||
|
// Get voters capacities.
|
||||||
|
voterCaps := make(map[common.Address]*big.Int)
|
||||||
|
for _, voteAddr := range voters {
|
||||||
|
var voterCap *big.Int
|
||||||
|
|
||||||
|
voterCap, err = validator.GetVoterCap(opts, masterAddr, voteAddr)
|
||||||
|
if err != nil {
|
||||||
|
log.Crit("Fail to get vote capacity", "error", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
totalCap.Add(totalCap, voterCap)
|
||||||
|
voterCaps[voteAddr] = voterCap
|
||||||
|
}
|
||||||
|
if totalCap.Cmp(new(big.Int).SetInt64(0)) > 0 {
|
||||||
|
for addr, voteCap := range voterCaps {
|
||||||
|
// Only valid voter has cap > 0.
|
||||||
|
if voteCap.Cmp(new(big.Int).SetInt64(0)) > 0 {
|
||||||
|
rcap := new(big.Int).Mul(totalVoterReward, voteCap)
|
||||||
|
rcap = new(big.Int).Div(rcap, totalCap)
|
||||||
|
if balances[addr] != nil {
|
||||||
|
balances[addr].Add(balances[addr], rcap)
|
||||||
|
} else {
|
||||||
|
balances[addr] = rcap
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
foudationReward := new(big.Int).Mul(totalReward, new(big.Int).SetInt64(common.RewardFoundationPercent))
|
||||||
|
foudationReward = new(big.Int).Div(foudationReward, new(big.Int).SetInt64(100))
|
||||||
|
balances[foudationWalletAddr] = foudationReward
|
||||||
|
|
||||||
|
jsonHolders, err := json.Marshal(balances)
|
||||||
|
if err != nil {
|
||||||
|
log.Error("Fail to parse json holders", "error", err)
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
log.Info("Holders reward", "holders", string(jsonHolders), "master node", masterAddr.String())
|
||||||
|
|
||||||
|
return balances, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetCandidatesOwnerBySigner(validator *contractValidator.TomoValidator, signerAddr common.Address) common.Address {
|
||||||
|
owner := signerAddr
|
||||||
|
opts := new(bind.CallOpts)
|
||||||
|
owner, err := validator.GetCandidateOwner(opts, signerAddr)
|
||||||
|
if err != nil {
|
||||||
|
log.Error("Fail get candidate owner", "error", err)
|
||||||
|
return owner
|
||||||
|
}
|
||||||
|
|
||||||
|
return owner
|
||||||
|
}
|
||||||
88
contracts/validatorReader.go
Normal file
88
contracts/validatorReader.go
Normal file
|
|
@ -0,0 +1,88 @@
|
||||||
|
package contracts
|
||||||
|
|
||||||
|
import (
|
||||||
|
"math/big"
|
||||||
|
|
||||||
|
"github.com/ethereum/go-ethereum/accounts/abi"
|
||||||
|
"github.com/ethereum/go-ethereum/common"
|
||||||
|
"github.com/ethereum/go-ethereum/core/state"
|
||||||
|
"github.com/ethereum/go-ethereum/crypto"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
slotValidatorMapping = map[string]uint64{
|
||||||
|
"withdrawsState": 0,
|
||||||
|
"validatorsState": 1,
|
||||||
|
"voters": 2,
|
||||||
|
"candidates": 3,
|
||||||
|
"candidateCount": 4,
|
||||||
|
"minCandidateCap": 5,
|
||||||
|
"minVoterCap": 6,
|
||||||
|
"maxValidatorNumber": 7,
|
||||||
|
"candidateWithdrawDelay": 8,
|
||||||
|
"voterWithdrawDelay": 9,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
func GetCandidates(statedb *state.StateDB) []common.Address {
|
||||||
|
slot := slotValidatorMapping["candidates"]
|
||||||
|
slotHash := common.BigToHash(new(big.Int).SetUint64(slot))
|
||||||
|
arrLength := statedb.GetState(common.HexToAddress(common.MasternodeVotingSMC), slotHash)
|
||||||
|
keys := []common.Hash{}
|
||||||
|
for i := uint64(0); i < arrLength.Big().Uint64(); i++ {
|
||||||
|
key := getLocDynamicArrAtElement(slotHash, i, 1)
|
||||||
|
keys = append(keys, key)
|
||||||
|
}
|
||||||
|
rets := []common.Address{}
|
||||||
|
for _, key := range keys {
|
||||||
|
ret := statedb.GetState(common.HexToAddress(common.MasternodeVotingSMC), key)
|
||||||
|
rets = append(rets, common.HexToAddress(ret.Hex()))
|
||||||
|
}
|
||||||
|
return rets
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetCandidateOwner(statedb *state.StateDB, candidate common.Address) common.Address {
|
||||||
|
slot := slotValidatorMapping["validatorsState"]
|
||||||
|
// validatorsState[_candidate].owner;
|
||||||
|
locValidatorsState := getLocMappingAtKey(candidate.Hash(), slot)
|
||||||
|
locCandidateOwner := locValidatorsState.Add(locValidatorsState, new(big.Int).SetUint64(uint64(0)))
|
||||||
|
ret := statedb.GetState(common.HexToAddress(common.MasternodeVotingSMC), common.BigToHash(locCandidateOwner))
|
||||||
|
return common.HexToAddress(ret.Hex())
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetCandidateCap(statedb *state.StateDB, parsed abi.ABI, candidate common.Address) string {
|
||||||
|
slot := slotValidatorMapping["validatorsState"]
|
||||||
|
// validatorsState[_candidate].cap;
|
||||||
|
locValidatorsState := getLocMappingAtKey(candidate.Hash(), slot)
|
||||||
|
locCandidateCap := locValidatorsState.Add(locValidatorsState, new(big.Int).SetUint64(uint64(1)))
|
||||||
|
ret := statedb.GetState(common.HexToAddress(common.MasternodeVotingSMC), common.BigToHash(locCandidateCap))
|
||||||
|
return ret.Hex()
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetVoters(statedb *state.StateDB, candidate common.Address) []common.Address {
|
||||||
|
//mapping(address => address[]) voters;
|
||||||
|
slot := slotValidatorMapping["voters"]
|
||||||
|
locVoters := getLocMappingAtKey(candidate.Hash(), slot)
|
||||||
|
arrLength := statedb.GetState(common.HexToAddress(common.MasternodeVotingSMC), common.BigToHash(locVoters))
|
||||||
|
keys := []common.Hash{}
|
||||||
|
for i := uint64(0); i < arrLength.Big().Uint64(); i++ {
|
||||||
|
key := getLocDynamicArrAtElement(common.BigToHash(locVoters), i, 1)
|
||||||
|
keys = append(keys, key)
|
||||||
|
}
|
||||||
|
rets := []common.Address{}
|
||||||
|
for _, key := range keys {
|
||||||
|
ret := statedb.GetState(common.HexToAddress(common.MasternodeVotingSMC), key)
|
||||||
|
rets = append(rets, common.HexToAddress(ret.Hex()))
|
||||||
|
}
|
||||||
|
|
||||||
|
return rets
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetVoterCap(state *state.StateDB, candidate, voter common.Address) *big.Int {
|
||||||
|
slot := slotValidatorMapping["validatorsState"]
|
||||||
|
locValidatorsState := getLocMappingAtKey(candidate.Hash(), slot)
|
||||||
|
locCandidateVoters := locValidatorsState.Add(locValidatorsState, new(big.Int).SetUint64(uint64(2)))
|
||||||
|
retByte := crypto.Keccak256(voter.Hash().Bytes(), common.BigToHash(locCandidateVoters).Bytes())
|
||||||
|
ret := state.GetState(common.HexToAddress(common.MasternodeVotingSMC), common.BytesToHash(retByte))
|
||||||
|
return ret.Big()
|
||||||
|
}
|
||||||
|
|
@ -48,7 +48,6 @@ func TestHeaderVerification(t *testing.T) {
|
||||||
for i := 0; i < len(blocks); i++ {
|
for i := 0; i < len(blocks); i++ {
|
||||||
for j, valid := range []bool{true, false} {
|
for j, valid := range []bool{true, false} {
|
||||||
var results <-chan error
|
var results <-chan error
|
||||||
|
|
||||||
if valid {
|
if valid {
|
||||||
engine := ethash.NewFaker()
|
engine := ethash.NewFaker()
|
||||||
_, results = engine.VerifyHeaders(chain, []*types.Header{headers[i]}, []bool{true})
|
_, results = engine.VerifyHeaders(chain, []*types.Header{headers[i]}, []bool{true})
|
||||||
|
|
@ -104,7 +103,6 @@ func testHeaderConcurrentVerification(t *testing.T, threads int) {
|
||||||
// also an invalid chain (enough if one arbitrary block is invalid).
|
// also an invalid chain (enough if one arbitrary block is invalid).
|
||||||
for i, valid := range []bool{true, false} {
|
for i, valid := range []bool{true, false} {
|
||||||
var results <-chan error
|
var results <-chan error
|
||||||
|
|
||||||
if valid {
|
if valid {
|
||||||
chain, _ := NewBlockChain(testdb, nil, params.TestChainConfig, ethash.NewFaker(), vm.Config{})
|
chain, _ := NewBlockChain(testdb, nil, params.TestChainConfig, ethash.NewFaker(), vm.Config{})
|
||||||
_, results = chain.engine.VerifyHeaders(chain, headers, seals)
|
_, results = chain.engine.VerifyHeaders(chain, headers, seals)
|
||||||
|
|
@ -175,7 +173,6 @@ func testHeaderConcurrentAbortion(t *testing.T, threads int) {
|
||||||
// Start the verifications and immediately abort
|
// Start the verifications and immediately abort
|
||||||
chain, _ := NewBlockChain(testdb, nil, params.TestChainConfig, ethash.NewFakeDelayer(time.Millisecond), vm.Config{})
|
chain, _ := NewBlockChain(testdb, nil, params.TestChainConfig, ethash.NewFakeDelayer(time.Millisecond), vm.Config{})
|
||||||
defer chain.Stop()
|
defer chain.Stop()
|
||||||
|
|
||||||
abort, results := chain.engine.VerifyHeaders(chain, headers, seals)
|
abort, results := chain.engine.VerifyHeaders(chain, headers, seals)
|
||||||
close(abort)
|
close(abort)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -34,10 +34,9 @@ import (
|
||||||
"github.com/ethereum/go-ethereum/consensus/ethash"
|
"github.com/ethereum/go-ethereum/consensus/ethash"
|
||||||
"github.com/ethereum/go-ethereum/consensus/posv"
|
"github.com/ethereum/go-ethereum/consensus/posv"
|
||||||
"github.com/ethereum/go-ethereum/contracts"
|
"github.com/ethereum/go-ethereum/contracts"
|
||||||
"github.com/ethereum/go-ethereum/contracts/validator/contract"
|
|
||||||
"github.com/ethereum/go-ethereum/core"
|
"github.com/ethereum/go-ethereum/core"
|
||||||
"github.com/ethereum/go-ethereum/core/bloombits"
|
"github.com/ethereum/go-ethereum/core/bloombits"
|
||||||
"github.com/ethereum/go-ethereum/core/state"
|
//"github.com/ethereum/go-ethereum/core/state"
|
||||||
"github.com/ethereum/go-ethereum/core/types"
|
"github.com/ethereum/go-ethereum/core/types"
|
||||||
"github.com/ethereum/go-ethereum/core/vm"
|
"github.com/ethereum/go-ethereum/core/vm"
|
||||||
"github.com/ethereum/go-ethereum/eth/downloader"
|
"github.com/ethereum/go-ethereum/eth/downloader"
|
||||||
|
|
@ -53,6 +52,7 @@ import (
|
||||||
"github.com/ethereum/go-ethereum/params"
|
"github.com/ethereum/go-ethereum/params"
|
||||||
"github.com/ethereum/go-ethereum/rlp"
|
"github.com/ethereum/go-ethereum/rlp"
|
||||||
"github.com/ethereum/go-ethereum/rpc"
|
"github.com/ethereum/go-ethereum/rpc"
|
||||||
|
"github.com/ethereum/go-ethereum/core/state"
|
||||||
)
|
)
|
||||||
|
|
||||||
type LesServer interface {
|
type LesServer interface {
|
||||||
|
|
@ -244,9 +244,9 @@ func New(ctx *node.ServiceContext, config *Config) (*Ethereum, error) {
|
||||||
|
|
||||||
// Hook scans for bad masternodes and decide to penalty them
|
// Hook scans for bad masternodes and decide to penalty them
|
||||||
c.HookPenalty = func(chain consensus.ChainReader, blockNumberEpoc uint64) ([]common.Address, error) {
|
c.HookPenalty = func(chain consensus.ChainReader, blockNumberEpoc uint64) ([]common.Address, error) {
|
||||||
client, err := eth.blockchain.GetClient()
|
canonicalState, err := eth.blockchain.State()
|
||||||
if err != nil {
|
if canonicalState == nil || err != nil {
|
||||||
return nil, err
|
log.Crit("Can't get state at head of canonical chain", "head number", eth.blockchain.CurrentHeader().Number.Uint64(), "err", err)
|
||||||
}
|
}
|
||||||
prevEpoc := blockNumberEpoc - chain.Config().Posv.Epoch
|
prevEpoc := blockNumberEpoc - chain.Config().Posv.Epoch
|
||||||
if prevEpoc >= 0 {
|
if prevEpoc >= 0 {
|
||||||
|
|
@ -254,12 +254,13 @@ func New(ctx *node.ServiceContext, config *Config) (*Ethereum, error) {
|
||||||
prevHeader := chain.GetHeaderByNumber(prevEpoc)
|
prevHeader := chain.GetHeaderByNumber(prevEpoc)
|
||||||
penSigners := c.GetMasternodes(chain, prevHeader)
|
penSigners := c.GetMasternodes(chain, prevHeader)
|
||||||
if len(penSigners) > 0 {
|
if len(penSigners) > 0 {
|
||||||
blockSignerAddr := common.HexToAddress(common.BlockSigners)
|
|
||||||
// Loop for each block to check missing sign.
|
// Loop for each block to check missing sign.
|
||||||
for i := prevEpoc; i < blockNumberEpoc; i++ {
|
for i := prevEpoc; i < blockNumberEpoc; i++ {
|
||||||
blockHeader := chain.GetHeaderByNumber(i)
|
bheader := chain.GetHeaderByNumber(i)
|
||||||
|
bhash := bheader.Hash()
|
||||||
|
block := chain.GetBlock(bhash, i)
|
||||||
if len(penSigners) > 0 {
|
if len(penSigners) > 0 {
|
||||||
signedMasternodes, err := contracts.GetSignersFromContract(blockSignerAddr, client, blockHeader.Hash())
|
signedMasternodes, err := contracts.GetSignersFromContract(canonicalState, block)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
@ -287,25 +288,28 @@ func New(ctx *node.ServiceContext, config *Config) (*Ethereum, error) {
|
||||||
|
|
||||||
// Hook calculates reward for masternodes
|
// Hook calculates reward for masternodes
|
||||||
c.HookReward = func(chain consensus.ChainReader, state *state.StateDB, header *types.Header) (error, map[string]interface{}) {
|
c.HookReward = func(chain consensus.ChainReader, state *state.StateDB, header *types.Header) (error, map[string]interface{}) {
|
||||||
client, err := eth.blockchain.GetClient()
|
canonicalState, err := eth.blockchain.State()
|
||||||
if err != nil {
|
if canonicalState == nil || err != nil {
|
||||||
log.Crit("Fail to connect IPC client for blockSigner", "error", err)
|
log.Crit("Can't get state at head of canonical chain", "head number", header.Number.Uint64(), "err", err)
|
||||||
}
|
}
|
||||||
number := header.Number.Uint64()
|
number := header.Number.Uint64()
|
||||||
rCheckpoint := chain.Config().Posv.RewardCheckpoint
|
rCheckpoint := chain.Config().Posv.RewardCheckpoint
|
||||||
foudationWalletAddr := chain.Config().Posv.FoudationWalletAddr
|
foundationWalletAddr := chain.Config().Posv.FoudationWalletAddr
|
||||||
if foudationWalletAddr == (common.Address{}) {
|
if foundationWalletAddr == (common.Address{}) {
|
||||||
log.Error("Foundation Wallet Address is empty", "error", foudationWalletAddr)
|
log.Error("Foundation Wallet Address is empty", "error", foundationWalletAddr)
|
||||||
|
return err, nil
|
||||||
}
|
}
|
||||||
rewards := make(map[string]interface{})
|
rewards := make(map[string]interface{})
|
||||||
if number > 0 && number-rCheckpoint > 0 && foudationWalletAddr != (common.Address{}) {
|
if number > 0 && number-rCheckpoint > 0 && foundationWalletAddr != (common.Address{}) {
|
||||||
start := time.Now()
|
start := time.Now()
|
||||||
|
// Get signers in blockSigner smartcontract.
|
||||||
// Get reward inflation.
|
// Get reward inflation.
|
||||||
chainReward := new(big.Int).Mul(new(big.Int).SetUint64(chain.Config().Posv.Reward), new(big.Int).SetUint64(params.Ether))
|
chainReward := new(big.Int).Mul(new(big.Int).SetUint64(chain.Config().Posv.Reward), new(big.Int).SetUint64(params.Ether))
|
||||||
chainReward = rewardInflation(chainReward, number, common.BlocksPerYear)
|
chainReward = rewardInflation(chainReward, number, common.BlocksPerYear)
|
||||||
|
|
||||||
totalSigner := new(uint64)
|
totalSigner := new(uint64)
|
||||||
signers, err := contracts.GetRewardForCheckpoint(c, chain, number, rCheckpoint, totalSigner)
|
signers, err := contracts.GetRewardForCheckpoint(c, chain, number, rCheckpoint, totalSigner)
|
||||||
|
|
||||||
log.Debug("Time Get Signers", "block", header.Number.Uint64(), "time", common.PrettyDuration(time.Since(start)))
|
log.Debug("Time Get Signers", "block", header.Number.Uint64(), "time", common.PrettyDuration(time.Since(start)))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Crit("Fail to get signers for reward checkpoint", "error", err)
|
log.Crit("Fail to get signers for reward checkpoint", "error", err)
|
||||||
|
|
@ -315,19 +319,19 @@ func New(ctx *node.ServiceContext, config *Config) (*Ethereum, error) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Crit("Fail to calculate reward for signers", "error", err)
|
log.Crit("Fail to calculate reward for signers", "error", err)
|
||||||
}
|
}
|
||||||
// Get validator.
|
|
||||||
validator, err := contract.NewTomoValidator(common.HexToAddress(common.MasternodeVotingSMC), client)
|
|
||||||
if err != nil {
|
|
||||||
log.Crit("Fail get instance of Tomo Validator", "error", err)
|
|
||||||
}
|
|
||||||
// Add reward for coin holders.
|
// Add reward for coin holders.
|
||||||
voterResults := make(map[common.Address]interface{})
|
voterResults := make(map[common.Address]interface{})
|
||||||
if len(signers) > 0 {
|
if len(signers) > 0 {
|
||||||
for signer, calcReward := range rewardSigners {
|
for signer, calcReward := range rewardSigners {
|
||||||
err, rewards := contracts.CalculateRewardForHolders(foudationWalletAddr, validator, state, signer, calcReward)
|
err, rewards := contracts.CalculateRewardForHolders(foundationWalletAddr, canonicalState, signer, calcReward)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Crit("Fail to calculate reward for holders.", "error", err)
|
log.Crit("Fail to calculate reward for holders.", "error", err)
|
||||||
}
|
}
|
||||||
|
if len(rewards) > 0 {
|
||||||
|
for holder, reward := range rewards {
|
||||||
|
state.AddBalance(holder, reward)
|
||||||
|
}
|
||||||
|
}
|
||||||
voterResults[signer] = rewards
|
voterResults[signer] = rewards
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -353,6 +357,7 @@ func New(ctx *node.ServiceContext, config *Config) (*Ethereum, error) {
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
eth.txPool.IsMasterNode = func(address common.Address) bool {
|
eth.txPool.IsMasterNode = func(address common.Address) bool {
|
||||||
currentHeader := eth.blockchain.CurrentHeader()
|
currentHeader := eth.blockchain.CurrentHeader()
|
||||||
snap, err := c.GetSnapshot(eth.blockchain, currentHeader)
|
snap, err := c.GetSnapshot(eth.blockchain, currentHeader)
|
||||||
|
|
@ -404,6 +409,7 @@ func CreateConsensusEngine(ctx *node.ServiceContext, config *ethash.Config, chai
|
||||||
if chainConfig.Posv != nil {
|
if chainConfig.Posv != nil {
|
||||||
return posv.New(chainConfig.Posv, db)
|
return posv.New(chainConfig.Posv, db)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Otherwise assume proof-of-work
|
// Otherwise assume proof-of-work
|
||||||
switch {
|
switch {
|
||||||
case config.PowMode == ethash.ModeFake:
|
case config.PowMode == ethash.ModeFake:
|
||||||
|
|
|
||||||
|
|
@ -855,22 +855,19 @@ func (s *PublicBlockChainAPI) rpcOutputBlock(b *types.Block, inclTx bool, fullTx
|
||||||
}
|
}
|
||||||
fields["uncles"] = uncleHashes
|
fields["uncles"] = uncleHashes
|
||||||
|
|
||||||
// Get signers for block.
|
|
||||||
client, err := s.b.GetIPCClient()
|
|
||||||
if err != nil {
|
|
||||||
log.Error("Fail to connect IPC client for block status", "error", err)
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
var signers []common.Address
|
var signers []common.Address
|
||||||
var filterSigners []common.Address
|
var filterSigners []common.Address
|
||||||
finality := int32(0)
|
finality := int32(0)
|
||||||
if b.Number().Int64() > 0 {
|
if b.Number().Int64() > 0 {
|
||||||
engine := s.b.GetEngine()
|
engine := s.b.GetEngine()
|
||||||
addrBlockSigner := common.HexToAddress(common.BlockSigners)
|
blockNr := rpc.BlockNumber(b.Number().Int64())
|
||||||
signers, err = contracts.GetSignersFromContract(addrBlockSigner, client, b.Hash())
|
state, _, err := s.b.StateAndHeaderByNumber(ctx, blockNr)
|
||||||
|
if state == nil || err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
signers, err = contracts.GetSignersFromContract(state, b)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error("Fail to get signers from block signer SC.", "error", err)
|
log.Error("Fail to get signers from block signer SC.", "error", err)
|
||||||
return nil, err
|
|
||||||
}
|
}
|
||||||
// Get block epoc latest.
|
// Get block epoc latest.
|
||||||
if s.b.ChainConfig().Posv != nil {
|
if s.b.ChainConfig().Posv != nil {
|
||||||
|
|
|
||||||
|
|
@ -552,6 +552,7 @@ func (self *worker) commitNewWork() {
|
||||||
if atomic.LoadInt32(&self.mining) == 1 {
|
if atomic.LoadInt32(&self.mining) == 1 {
|
||||||
header.Coinbase = self.coinbase
|
header.Coinbase = self.coinbase
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := self.engine.Prepare(self.chain, header); err != nil {
|
if err := self.engine.Prepare(self.chain, header); err != nil {
|
||||||
log.Error("Failed to prepare header for new block", "err", err)
|
log.Error("Failed to prepare header for new block", "err", err)
|
||||||
return
|
return
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue