Skip to content

Commit

Permalink
create new func penalties for hard fork
Browse files Browse the repository at this point in the history
  • Loading branch information
nguyenbatam committed Mar 5, 2019
1 parent e90141a commit ba55451
Show file tree
Hide file tree
Showing 12 changed files with 170 additions and 210 deletions.
43 changes: 20 additions & 23 deletions cmd/tomoclean/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,12 @@ import (
var (
dir = flag.String("dir", "", "dir to mainet chain data")
cacheSize = flag.Int("size", 1000000, "dir to mainet chain data")
file = flag.String("file", "", "dir to mainet chain data")
)

type TrieRoot struct {
trie *trie.SecureTrie
number uint64
}
type StateNode struct {
node trie.Node
path []byte
Expand All @@ -45,7 +48,7 @@ var cleanAddress = []common.Address{common.HexToAddress(common.BlockSigners)}
var cache *lru.Cache
var finish = int32(0)
var running = true
var stateRoots = make(chan *trie.SecureTrie)
var stateRoots = make(chan TrieRoot)

func main() {
flag.Parse()
Expand All @@ -63,10 +66,9 @@ func main() {
if err != nil {
continue
}
fmt.Println(time.Now().Format(time.RFC3339), "Found a trie state root at block ", i, "state root ", root.Hex())
if running {
stateRoots <- trieRoot
}else {
stateRoots <- TrieRoot{trieRoot, i}
} else {
break
}
}
Expand All @@ -78,29 +80,31 @@ func main() {
atomic.StoreInt32(&finish, 1)
if running {
for _, address := range cleanAddress {
enc := trieRoot.Get(address.Bytes())
enc := trieRoot.trie.Get(address.Bytes())
var data state.Account
rlp.DecodeBytes(enc, &data)
fmt.Println(time.Now().Format(time.RFC3339), "Start clean state address ", address.Hex(), " at state root ", common.Bytes2Hex(trieRoot.Root()), "state address root", data.Root.Hex())
fmt.Println(time.Now().Format(time.RFC3339), "Start clean state address ", address.Hex(), " at block ", trieRoot.number)
signerRoot, err := resolveHash(data.Root[:], lddb.LDB())
if err != nil {
fmt.Println(time.Now().Format(time.RFC3339), "Not found clean state address ", address.Hex(), " at state root ", common.Bytes2Hex(trieRoot.Root()), "state address root", data.Root.Hex())
fmt.Println(time.Now().Format(time.RFC3339), "Not found clean state address ", address.Hex(), " at block ", trieRoot.number)
continue
}
batch := new(leveldb.Batch)
list := []*StateNode{&StateNode{node: signerRoot}}
count := 1
list := []*StateNode{{node: signerRoot}}
for len(list) > 0 {
newList, total := findNewNodes(list, lddb.LDB(), batch)
count = count + 17*len(newList)
list = removeNodesNil(newList, total)
}
fmt.Println(time.Now().Format(time.RFC3339), "Finish clean state address ", address.Hex(), " at state root ", common.Bytes2Hex(trieRoot.Root()), "state address root", data.Root.Hex())
fmt.Println(time.Now().Format(time.RFC3339), "Finish clean state address ", address.Hex(), " at block ", trieRoot.number, " keys ", count)
err = lddb.LDB().Write(batch, nil)
if err != nil {
fmt.Println(time.Now().Format(time.RFC3339), "Write batch leveldb error", err)
os.Exit(1)
}
}
}else {
} else {
break
}
atomic.StoreInt32(&finish, 0)
Expand Down Expand Up @@ -133,10 +137,7 @@ func catchEventInterupt(db *leveldb.DB) {
running = false
if atomic.LoadInt32(&finish) == 0 {
close(stateRoots)
fmt.Println(time.Now(), "interrupt compact")
db.CompactRange(util.Range{})
db.Close()
fmt.Println(time.Now(), "interrupt end")
os.Exit(1)
}
}
Expand Down Expand Up @@ -169,7 +170,7 @@ func getAllChilds(n StateNode, db *leveldb.DB) ([17]*StateNode, error) {
if err == nil {
childs[i] = &StateNode{node: childNode, path: append(n.path, byte(i))}
} else if err != nil {
_, ok := err.(*trie.MissingNodeError);
_, ok := err.(*trie.MissingNodeError)
if !ok {
return childs, err
}
Expand All @@ -186,7 +187,7 @@ func getAllChilds(n StateNode, db *leveldb.DB) ([17]*StateNode, error) {
if err == nil {
childs[0] = &StateNode{node: childNode, path: append(n.path, node.Key...)}
} else if err != nil {
_, ok := err.(*trie.MissingNodeError);
_, ok := err.(*trie.MissingNodeError)
if !ok {
return childs, err
}
Expand Down Expand Up @@ -234,8 +235,7 @@ func findNewNodes(nodes []*StateNode, db *leveldb.DB, batchlvdb *leveldb.Batch)
childNodes := make([][17]*StateNode, length)
results := make(chan ResultProcessNode)
wg := sync.WaitGroup{}
wgResults := sync.WaitGroup{}
wg.Add(nWorker)
wg.Add(length)
for i := 0; i < nWorker; i++ {
from := i * chunkSize
to := from + chunkSize
Expand All @@ -245,15 +245,12 @@ func findNewNodes(nodes []*StateNode, db *leveldb.DB, batchlvdb *leveldb.Batch)
go func(from int, to int) {
for j := from; j < to; j++ {
childs, keys, number := processNodes(*nodes[j], db)
wgResults.Add(1)
go func(result ResultProcessNode) {
results <- result
}(ResultProcessNode{j, number, childs, keys})
}
wg.Done()
}(from, to)
}
wg.Wait()
total := 0
go func() {
for result := range results {
Expand All @@ -264,10 +261,10 @@ func findNewNodes(nodes []*StateNode, db *leveldb.DB, batchlvdb *leveldb.Batch)
batchlvdb.Delete(*key)
}
}
wgResults.Done()
wg.Done()
}
}()
wgResults.Wait()
wg.Wait()
close(results)
return childNodes, total
}
5 changes: 3 additions & 2 deletions common/constants.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,12 @@ const (
LimitThresholdNonceInQueue = 10
DefaultMinGasPrice = 2500
MergeSignRange = 15
RangeReturnSigner = 90
RangeReturnSigner = 150
MinimunMinerBlockPerEpoch = 1
)

var TIP2019Block = big.NewInt(1050000)
var TIPEVMSignerBlock = big.NewInt(2500000)
var TIPSigning = big.NewInt(3000000)
var IsTestnet bool = false
var StoreRewardFolder string
var RollbackHash Hash
Expand Down
31 changes: 15 additions & 16 deletions consensus/posv/posv.go
Original file line number Diff line number Diff line change
Expand Up @@ -227,10 +227,10 @@ type Posv struct {

BlockSigners *lru.Cache
HookReward func(chain consensus.ChainReader, state *state.StateDB, header *types.Header) (error, map[string]interface{})
HookPenalty func(chain consensus.ChainReader, blockNumberEpoc uint64) ([]common.Address, error)
HookPenaltyTIPEVM func(chain consensus.ChainReader, blockNumberEpoc uint64) ([]common.Address, error)
HookValidator func(header *types.Header, signers []common.Address) ([]byte, error)
HookVerifyMNs func(header *types.Header, signers []common.Address) error
HookPenalty func(chain consensus.ChainReader, blockNumberEpoc uint64) ([]common.Address, error)
HookPenaltyTIPSigning func(chain consensus.ChainReader, header *types.Header, candidate []common.Address) ([]common.Address, error)
HookValidator func(header *types.Header, signers []common.Address) ([]byte, error)
HookVerifyMNs func(header *types.Header, signers []common.Address) error
}

// New creates a PoSV proof-of-stake-voting consensus engine with the initial
Expand Down Expand Up @@ -398,12 +398,12 @@ func (c *Posv) verifyCascadingFields(chain consensus.ChainReader, header *types.
}
// If the block is a checkpoint block, verify the signer list
if number%c.config.Epoch == 0 {
signers := snap.GetSigners()
penPenalties := []common.Address{}
if c.HookPenalty != nil || c.HookPenaltyTIPEVM != nil {
var penPenalties []common.Address = nil
if c.HookPenalty != nil || c.HookPenaltyTIPSigning != nil {
var err error = nil
if chain.Config().IsTIPEVMSigner(header.Number) {
penPenalties, err = c.HookPenaltyTIPEVM(chain, number)
if chain.Config().IsTIPSigning(header.Number) {
penPenalties, err = c.HookPenaltyTIPSigning(chain, header, signers)
} else {
penPenalties, err = c.HookPenalty(chain, number)
}
Expand All @@ -418,7 +418,6 @@ func (c *Posv) verifyCascadingFields(chain consensus.ChainReader, header *types.
return errInvalidCheckpointPenalties
}
}
signers := snap.GetSigners()
signers = common.RemoveItemFromArray(signers, penPenalties)
for i := 1; i <= common.LimitPenaltyEpoch; i++ {
if number > uint64(i)*c.config.Epoch {
Expand Down Expand Up @@ -795,11 +794,11 @@ func (c *Posv) Prepare(chain consensus.ChainReader, header *types.Header) error
header.Extra = header.Extra[:extraVanity]
masternodes := snap.GetSigners()
if number >= c.config.Epoch && number%c.config.Epoch == 0 {
if c.HookPenalty != nil || c.HookPenaltyTIPEVM != nil {
if c.HookPenalty != nil || c.HookPenaltyTIPSigning != nil {
var penMasternodes []common.Address = nil
var err error = nil
if chain.Config().IsTIPEVMSigner(header.Number) {
penMasternodes, err = c.HookPenaltyTIPEVM(chain, number)
if chain.Config().IsTIPSigning(header.Number) {
penMasternodes, err = c.HookPenaltyTIPSigning(chain, header, masternodes)
} else {
penMasternodes, err = c.HookPenalty(chain, number)
}
Expand All @@ -810,7 +809,7 @@ func (c *Posv) Prepare(chain consensus.ChainReader, header *types.Header) error
// penalize bad masternode(s)
masternodes = common.RemoveItemFromArray(masternodes, penMasternodes)
for _, address := range penMasternodes {
log.Debug("Penalty status", "address", address, "block number", number)
log.Debug("Penalty status", "address", address, "number", number)
}
header.Penalties = common.ExtractAddressToBytes(penMasternodes)
}
Expand Down Expand Up @@ -1079,15 +1078,15 @@ func (c *Posv) CacheData(header *types.Header, txs []*types.Transaction, receipt
return signTxs
}

func (c *Posv) CacheSigner(header *types.Header, txs []*types.Transaction) []*types.Transaction {
func (c *Posv) CacheSigner(hash common.Hash, txs []*types.Transaction) []*types.Transaction {
signTxs := []*types.Transaction{}
for _, tx := range txs {
if tx.IsSigningTransaction() {
signTxs = append(signTxs, tx)
}
}
log.Debug("Save tx signers to cache", "hash", header.Hash().String(), "number", header.Number, "len(txs)", len(signTxs))
c.BlockSigners.Add(header.Hash(), signTxs)
log.Debug("Save tx signers to cache", "hash", hash.String(), "len(txs)", len(signTxs))
c.BlockSigners.Add(hash, signTxs)
return signTxs
}

Expand Down
62 changes: 3 additions & 59 deletions contracts/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -306,62 +306,6 @@ func DecryptRandomizeFromSecretsAndOpening(secrets [][32]byte, opening [32]byte)
return random, nil
}

// Get txw signed for block using cache or block body inside.
func GetSignersSignedAtBlockHash(c *posv.Posv, chain consensus.ChainReader, data map[common.Hash][]common.Address, header *types.Header, curNumber uint64) map[common.Hash][]common.Address {
if signData, ok := c.BlockSigners.Get(header.Hash()); ok {
txs := signData.([]*types.Transaction)
for _, tx := range txs {
blkHash := common.BytesToHash(tx.Data()[len(tx.Data())-32:])
from := *tx.From()
data[blkHash] = append(data[blkHash], from)
}
} else {
log.Debug("Failed get from cached", "hash", header.Hash().String(), "number", curNumber)
block := chain.GetBlock(header.Hash(), curNumber)
txs := block.Transactions()
receipts := core.GetBlockReceipts(c.GetDb(), header.Hash(), curNumber)

var signTxs []*types.Transaction
for _, tx := range txs {
if tx.IsSigningTransaction() {
var b uint
for _, r := range receipts {
if r.TxHash == tx.Hash() {
if len(r.PostState) > 0 {
b = types.ReceiptStatusSuccessful
} else {
b = r.Status
}
break
}
}

if b == types.ReceiptStatusFailed {
continue
}

signTxs = append(signTxs, tx)
blkHash := common.BytesToHash(tx.Data()[len(tx.Data())-32:])
from := *tx.From()
data[blkHash] = append(data[blkHash], from)
}
}
c.BlockSigners.Add(header.Hash(), signTxs)
}

return data
}

// Get signers list from bytes.
func GetSignersFromBytes(byteHeader []byte) []common.Address {
signers := make([]common.Address, len(byteHeader)/common.AddressLength)
for i := 0; i < len(signers); i++ {
copy(signers[i][:], byteHeader[i*common.AddressLength:])
}

return signers
}

// Calculate reward for reward checkpoint.
func GetRewardForCheckpoint(c *posv.Posv, chain consensus.ChainReader, header *types.Header, rCheckpoint uint64, totalSigner *uint64) (map[common.Address]*rewardLog, error) {
// Not reward for singer of genesis block and only calculate reward at checkpoint block.
Expand All @@ -381,11 +325,11 @@ func GetRewardForCheckpoint(c *posv.Posv, chain consensus.ChainReader, header *t
log.Debug("Failed get from cached", "hash", header.Hash().String(), "number", i)
block := chain.GetBlock(header.Hash(), i)
txs := block.Transactions()
if !chain.Config().IsTIPEVMSigner(header.Number) {
if !chain.Config().IsTIPSigning(header.Number) {
receipts := core.GetBlockReceipts(c.GetDb(), header.Hash(), i)
signData = c.CacheData(header, txs, receipts);
signData = c.CacheData(header, txs, receipts)
} else {
signData = c.CacheSigner(header, txs);
signData = c.CacheSigner(header.Hash(), txs)
}
}
txs := signData.([]*types.Transaction)
Expand Down
6 changes: 3 additions & 3 deletions core/blockchain.go
Original file line number Diff line number Diff line change
Expand Up @@ -507,7 +507,7 @@ func (bc *BlockChain) insert(block *types.Block) {
bc.currentBlock.Store(block)

// save cache BlockSigners
if bc.chainConfig.Posv != nil && !bc.chainConfig.IsTIPEVMSigner(block.Number()) {
if bc.chainConfig.Posv != nil && !bc.chainConfig.IsTIPSigning(block.Number()) {
engine := bc.Engine().(*posv.Posv)
engine.CacheData(block.Header(), block.Transactions(), bc.GetReceiptsByHash(block.Hash()))
}
Expand Down Expand Up @@ -1020,9 +1020,9 @@ func (bc *BlockChain) WriteBlockWithState(block *types.Block, receipts []*types.
bc.insert(block)
}
// save cache BlockSigners
if bc.chainConfig.Posv != nil && bc.chainConfig.IsTIPEVMSigner(block.Number()) {
if bc.chainConfig.Posv != nil && bc.chainConfig.IsTIPSigning(block.Number()) {
engine := bc.Engine().(*posv.Posv)
engine.CacheSigner(block.Header(), block.Transactions())
engine.CacheSigner(block.Header().Hash(), block.Transactions())
}
bc.futureBlocks.Remove(block.Hash())
return status, nil
Expand Down
6 changes: 3 additions & 3 deletions core/state_processor.go
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ func (p *StateProcessor) Process(block *types.Block, statedb *state.StateDB, cfg
if p.config.DAOForkSupport && p.config.DAOForkBlock != nil && p.config.DAOForkBlock.Cmp(block.Number()) == 0 {
misc.ApplyDAOHardFork(statedb)
}
if p.config.IsTIPEVMSigner(header.Number) {
if common.TIPSigning.Cmp(header.Number) == 0 {
statedb.DeleteAddress(common.HexToAddress(common.BlockSigners))
}
InitSignerInTransactions(p.config, header, block.Transactions())
Expand Down Expand Up @@ -104,7 +104,7 @@ func (p *StateProcessor) ProcessBlockNoValidator(cBlock *CalculatedBlock, stated
if p.config.DAOForkSupport && p.config.DAOForkBlock != nil && p.config.DAOForkBlock.Cmp(block.Number()) == 0 {
misc.ApplyDAOHardFork(statedb)
}
if p.config.IsTIPEVMSigner(header.Number) {
if common.TIPSigning.Cmp(header.Number) == 0 {
statedb.DeleteAddress(common.HexToAddress(common.BlockSigners))
}
if cBlock.stop {
Expand Down Expand Up @@ -138,7 +138,7 @@ func (p *StateProcessor) ProcessBlockNoValidator(cBlock *CalculatedBlock, stated
// for the transaction, gas used and an error if the transaction failed,
// indicating the block was invalid.
func ApplyTransaction(config *params.ChainConfig, bc *BlockChain, author *common.Address, gp *GasPool, statedb *state.StateDB, header *types.Header, tx *types.Transaction, usedGas *uint64, cfg vm.Config) (*types.Receipt, uint64, error) {
if tx.To() != nil && tx.To().String() == common.BlockSigners && config.IsTIPEVMSigner(header.Number) {
if tx.To() != nil && tx.To().String() == common.BlockSigners && config.IsTIPSigning(header.Number) {
return ApplySignTransaction(config, statedb, header, tx, usedGas)
}
msg, err := tx.AsMessage(types.MakeSigner(config, header.Number))
Expand Down
8 changes: 4 additions & 4 deletions core/tx_pool.go
Original file line number Diff line number Diff line change
Expand Up @@ -218,8 +218,8 @@ type TxPool struct {

wg sync.WaitGroup // for shutdown sync

homestead bool
IsMasterNode func(address common.Address) bool
homestead bool
IsSigner func(address common.Address) bool
}

// NewTxPool creates a new transaction pool to gather, sort and filter inbound
Expand Down Expand Up @@ -592,7 +592,7 @@ func (pool *TxPool) validateTx(tx *types.Transaction, local bool) error {
// Drop non-local transactions under our own minimal accepted gas price
local = local || pool.locals.contains(from) // account may be local even if the transaction arrived from the network
if !local && pool.gasPrice.Cmp(tx.GasPrice()) > 0 {
if !tx.IsSpecialTransaction() || (pool.IsMasterNode != nil && !pool.IsMasterNode(from)) {
if !tx.IsSpecialTransaction() || (pool.IsSigner != nil && !pool.IsSigner(from)) {
return ErrUnderpriced
}
}
Expand Down Expand Up @@ -661,7 +661,7 @@ func (pool *TxPool) add(tx *types.Transaction, local bool) (bool, error) {
return false, err
}
from, _ := types.Sender(pool.signer, tx) // already validated
if tx.IsSpecialTransaction() && pool.IsMasterNode != nil && pool.IsMasterNode(from) && pool.pendingState.GetNonce(from) == tx.Nonce() {
if tx.IsSpecialTransaction() && pool.IsSigner != nil && pool.IsSigner(from) && pool.pendingState.GetNonce(from) == tx.Nonce() {
return pool.promoteSpecialTx(from, tx)
}
// If the transaction pool is full, discard underpriced transactions
Expand Down
Loading

0 comments on commit ba55451

Please sign in to comment.