mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-08-19 10:22:23 +00:00
merge
This commit is contained in:
parent
507ef74a91
commit
78d17e64cd
4 changed files with 102 additions and 9 deletions
|
|
@ -1,6 +1,8 @@
|
||||||
package lcp
|
package lcp
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
"math/big"
|
"math/big"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
|
@ -14,6 +16,44 @@ import (
|
||||||
//types2 "github.com/pavelkrolevets/go-ethereum/core/types"
|
//types2 "github.com/pavelkrolevets/go-ethereum/core/types"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
func (ec *EpochContext) cVotes() (votes map[common.Address]*big.Int, err error) {
|
||||||
|
votes = map[common.Address]*big.Int{}
|
||||||
|
delegateTrie := ec.Context.DelegateTrie()
|
||||||
|
candidateTrie := ec.Context.CandidateTrie()
|
||||||
|
statedb := ec.statedb
|
||||||
|
|
||||||
|
iterCandidate := trie.NewIterator(candidateTrie.NodeIterator(nil))
|
||||||
|
existCandidate := iterCandidate.Next()
|
||||||
|
if !existCandidate {
|
||||||
|
return votes, errors.New("no candidates")
|
||||||
|
}
|
||||||
|
for existCandidate {
|
||||||
|
candidate := iterCandidate.Value
|
||||||
|
candidateAddr := common.BytesToAddress(candidate)
|
||||||
|
delegateIterator := trie.NewIterator(delegateTrie.PrefixIterator(candidate))
|
||||||
|
existDelegator := delegateIterator.Next()
|
||||||
|
if !existDelegator {
|
||||||
|
votes[candidateAddr] = new(big.Int)
|
||||||
|
existCandidate = iterCandidate.Next()
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
for existDelegator {
|
||||||
|
delegator := delegateIterator.Value
|
||||||
|
score, ok := votes[candidateAddr]
|
||||||
|
if !ok {
|
||||||
|
score = new(big.Int)
|
||||||
|
}
|
||||||
|
delegatorAddr := common.BytesToAddress(delegator)
|
||||||
|
weight := statedb.GetBalance(delegatorAddr)
|
||||||
|
score.Add(score, weight)
|
||||||
|
votes[candidateAddr] = score
|
||||||
|
existDelegator = delegateIterator.Next()
|
||||||
|
}
|
||||||
|
existCandidate = iterCandidate.Next()
|
||||||
|
}
|
||||||
|
return votes, nil
|
||||||
|
}
|
||||||
|
|
||||||
func TestEpochContextCountVotes(t *testing.T) {
|
func TestEpochContextCountVotes(t *testing.T) {
|
||||||
voteMap := map[common.Address][]common.Address{
|
voteMap := map[common.Address][]common.Address{
|
||||||
common.HexToAddress("0x44d1ce0b7cb3588bca96151fe1bc05af38f91b6e"): {
|
common.HexToAddress("0x44d1ce0b7cb3588bca96151fe1bc05af38f91b6e"): {
|
||||||
|
|
@ -38,10 +78,12 @@ func TestEpochContextCountVotes(t *testing.T) {
|
||||||
assert.Nil(t, err)
|
assert.Nil(t, err)
|
||||||
|
|
||||||
epochContext := &EpochContext{
|
epochContext := &EpochContext{
|
||||||
Context: LCPContext,
|
Context: LCPContext,
|
||||||
statedb: stateDB,
|
statedb: stateDB,
|
||||||
}
|
}
|
||||||
_, err = epochContext.countVotes()
|
|
||||||
|
// _, err = epochContext.countVotes()
|
||||||
|
_, err = epochContext.cVotes()
|
||||||
assert.NotNil(t, err)
|
assert.NotNil(t, err)
|
||||||
|
|
||||||
for candidate, electors := range voteMap {
|
for candidate, electors := range voteMap {
|
||||||
|
|
@ -49,17 +91,30 @@ func TestEpochContextCountVotes(t *testing.T) {
|
||||||
for _, elector := range electors {
|
for _, elector := range electors {
|
||||||
stateDB.SetBalance(elector, big.NewInt(balance))
|
stateDB.SetBalance(elector, big.NewInt(balance))
|
||||||
assert.Nil(t, LCPContext.Delegate(elector, candidate))
|
assert.Nil(t, LCPContext.Delegate(elector, candidate))
|
||||||
|
|
||||||
|
// print candidates list
|
||||||
|
_, e := epochContext.Context.VoteTrie().TryGet([]byte(elector.Bytes()))
|
||||||
|
if _, ok := e.(*trie.MissingNodeError); !ok {
|
||||||
|
fmt.Println(err)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
result, err := epochContext.countVotes()
|
result, err := epochContext.countVotes()
|
||||||
assert.Nil(t, err)
|
assert.Nil(t, err)
|
||||||
assert.Equal(t, len(voteMap), len(result))
|
assert.Equal(t, len(voteMap), len(result))
|
||||||
|
|
||||||
for candidate, electors := range voteMap {
|
for candidate, electors := range voteMap {
|
||||||
voteCount, ok := result[candidate]
|
voteCount, ok := result[candidate]
|
||||||
assert.True(t, ok)
|
assert.True(t, ok)
|
||||||
|
|
||||||
|
fmt.Println("voteCount =", voteCount)
|
||||||
|
fmt.Println("ele =", balance*int64(len(electors)))
|
||||||
|
|
||||||
assert.Equal(t, balance*int64(len(electors)), voteCount.Int64())
|
assert.Equal(t, balance*int64(len(electors)), voteCount.Int64())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
//func TestLookupValidator(t *testing.T) {
|
//func TestLookupValidator(t *testing.T) {
|
||||||
// db, _ := ethdb.NewMemDatabase()
|
// db, _ := ethdb.NewMemDatabase()
|
||||||
|
|
|
||||||
|
|
@ -356,7 +356,7 @@ func AccumulateRewards(config *params.ChainConfig, state *state.StateDB, header
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *LCP) Finalize(chain consensus.ChainReader, header *types.Header, state *state.StateDB, txs []*types.Transaction,
|
func (d *LCP) Finalize(chain consensus.ChainReader, header *types.Header, state *state.StateDB, txs []*types.Transaction,
|
||||||
uncles []*types.Header, receipts []*types.Receipt, LCPContext *types.LCPContext) (*types.Block, error) {
|
uncles []*types.Header, receipts []*types.Receipt) (*types.Block, error) {
|
||||||
// Accumulate block rewards and commit the final state root
|
// Accumulate block rewards and commit the final state root
|
||||||
AccumulateRewards(chain.Config(), state, header, uncles)
|
AccumulateRewards(chain.Config(), state, header, uncles)
|
||||||
header.Root = state.IntermediateRoot(chain.Config().IsEIP158(header.Number))
|
header.Root = state.IntermediateRoot(chain.Config().IsEIP158(header.Number))
|
||||||
|
|
|
||||||
|
|
@ -17,6 +17,8 @@
|
||||||
package core
|
package core
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"math/big"
|
||||||
|
|
||||||
"github.com/pavelkrolevets/go-ethereum/common"
|
"github.com/pavelkrolevets/go-ethereum/common"
|
||||||
"github.com/pavelkrolevets/go-ethereum/consensus"
|
"github.com/pavelkrolevets/go-ethereum/consensus"
|
||||||
"github.com/pavelkrolevets/go-ethereum/consensus/misc"
|
"github.com/pavelkrolevets/go-ethereum/consensus/misc"
|
||||||
|
|
@ -65,10 +67,11 @@ 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 {
|
if p.config.DAOForkSupport && p.config.DAOForkBlock != nil && p.config.DAOForkBlock.Cmp(block.Number()) == 0 {
|
||||||
misc.ApplyDAOHardFork(statedb)
|
misc.ApplyDAOHardFork(statedb)
|
||||||
}
|
}
|
||||||
|
// Set out block dpos context
|
||||||
// Iterate over and process the individual transactions
|
// Iterate over and process the individual transactions
|
||||||
for i, tx := range block.Transactions() {
|
for i, tx := range block.Transactions() {
|
||||||
statedb.Prepare(tx.Hash(), block.Hash(), i)
|
statedb.Prepare(tx.Hash(), block.Hash(), i)
|
||||||
receipt, _, err := ApplyTransaction(p.config, p.bc, nil, gp, statedb, header, tx, usedGas, cfg)
|
receipt, _, err := ApplyTransaction(p.config, block.LCPCtx(), p.bc, nil, gp, statedb, header, tx, usedGas, cfg)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, 0, err
|
return nil, nil, 0, err
|
||||||
}
|
}
|
||||||
|
|
@ -85,11 +88,15 @@ func (p *StateProcessor) Process(block *types.Block, statedb *state.StateDB, cfg
|
||||||
// and uses the input parameters for its environment. It returns the receipt
|
// and uses the input parameters for its environment. It returns the receipt
|
||||||
// for the transaction, gas used and an error if the transaction failed,
|
// for the transaction, gas used and an error if the transaction failed,
|
||||||
// indicating the block was invalid.
|
// indicating the block was invalid.
|
||||||
func ApplyTransaction(config *params.ChainConfig, bc ChainContext, author *common.Address, gp *GasPool, statedb *state.StateDB, header *types.Header, tx *types.Transaction, usedGas *uint64, cfg vm.Config) (*types.Receipt, uint64, error) {
|
func ApplyTransaction(config *params.ChainConfig, lcpContext *types.LCPContext, bc ChainContext, author *common.Address, gp *GasPool, statedb *state.StateDB, header *types.Header, tx *types.Transaction, usedGas *uint64, cfg vm.Config) (*types.Receipt, uint64, error) {
|
||||||
msg, err := tx.AsMessage(types.MakeSigner(config, header.Number))
|
msg, err := tx.AsMessage(types.MakeSigner(config, header.Number))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, 0, err
|
return nil, 0, err
|
||||||
}
|
}
|
||||||
|
if msg.To() == nil && msg.Type() != types.Binary {
|
||||||
|
return nil, 0, types.ErrInvalidType
|
||||||
|
}
|
||||||
|
|
||||||
// Create a new context to be used in the EVM environment
|
// Create a new context to be used in the EVM environment
|
||||||
context := NewEVMContext(msg, header, bc, author)
|
context := NewEVMContext(msg, header, bc, author)
|
||||||
// Create a new environment which holds all relevant information
|
// Create a new environment which holds all relevant information
|
||||||
|
|
@ -100,6 +107,12 @@ func ApplyTransaction(config *params.ChainConfig, bc ChainContext, author *commo
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, 0, err
|
return nil, 0, err
|
||||||
}
|
}
|
||||||
|
if msg.Type() != types.Binary {
|
||||||
|
if err = applyLcpMessage(lcpContext, msg); err != nil {
|
||||||
|
return nil, 0, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Update the state with pending changes
|
// Update the state with pending changes
|
||||||
var root []byte
|
var root []byte
|
||||||
if config.IsByzantium(header.Number) {
|
if config.IsByzantium(header.Number) {
|
||||||
|
|
@ -107,20 +120,40 @@ func ApplyTransaction(config *params.ChainConfig, bc ChainContext, author *commo
|
||||||
} else {
|
} else {
|
||||||
root = statedb.IntermediateRoot(config.IsEIP158(header.Number)).Bytes()
|
root = statedb.IntermediateRoot(config.IsEIP158(header.Number)).Bytes()
|
||||||
}
|
}
|
||||||
*usedGas += gas
|
// *usedGas += gas
|
||||||
|
usedGas.Add(usedGas, gas)
|
||||||
|
|
||||||
// Create a new receipt for the transaction, storing the intermediate root and gas used by the tx
|
// Create a new receipt for the transaction, storing the intermediate root and gas used by the tx
|
||||||
// based on the eip phase, we're passing wether the root touch-delete accounts.
|
// based on the eip phase, we're passing wether the root touch-delete accounts.
|
||||||
receipt := types.NewReceipt(root, failed, *usedGas)
|
// receipt := types.NewReceipt(root, failed, *usedGas)
|
||||||
|
receipt := types.NewReceipt(root, failed, usedGas)
|
||||||
receipt.TxHash = tx.Hash()
|
receipt.TxHash = tx.Hash()
|
||||||
receipt.GasUsed = gas
|
// receipt.GasUsed = gas
|
||||||
|
receipt.GasUsed = new(big.Int).Set(gas)
|
||||||
// if the transaction created a contract, store the creation address in the receipt.
|
// if the transaction created a contract, store the creation address in the receipt.
|
||||||
if msg.To() == nil {
|
if msg.To() == nil {
|
||||||
receipt.ContractAddress = crypto.CreateAddress(vmenv.Context.Origin, tx.Nonce())
|
receipt.ContractAddress = crypto.CreateAddress(vmenv.Context.Origin, tx.Nonce())
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set the receipt logs and create a bloom for filtering
|
// Set the receipt logs and create a bloom for filtering
|
||||||
receipt.Logs = statedb.GetLogs(tx.Hash())
|
receipt.Logs = statedb.GetLogs(tx.Hash())
|
||||||
receipt.Bloom = types.CreateBloom(types.Receipts{receipt})
|
receipt.Bloom = types.CreateBloom(types.Receipts{receipt})
|
||||||
|
|
||||||
return receipt, gas, err
|
return receipt, gas, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func applyLcpMessage(lcpContext *types.LCPContext, msg types.Message) error {
|
||||||
|
switch msg.Type() {
|
||||||
|
case types.LoginCandidate:
|
||||||
|
lcpContext.BecomeCandidate(msg.From())
|
||||||
|
case types.LogoutCandidate:
|
||||||
|
lcpContext.KickoutCandidate(msg.From())
|
||||||
|
case types.Delegate:
|
||||||
|
lcpContext.Delegate(msg.From(), *(msg.To()))
|
||||||
|
case types.UnDelegate:
|
||||||
|
lcpContext.UnDelegate(msg.From(), *(msg.To()))
|
||||||
|
default:
|
||||||
|
return types.ErrInvalidType
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -31,6 +31,9 @@ import (
|
||||||
|
|
||||||
//go:generate gencodec -type txdata -field-override txdataMarshaling -out gen_tx_json.go
|
//go:generate gencodec -type txdata -field-override txdataMarshaling -out gen_tx_json.go
|
||||||
|
|
||||||
|
// transaction type
|
||||||
|
type TxType uint8
|
||||||
|
|
||||||
var (
|
var (
|
||||||
ErrInvalidSig = errors.New("invalid transaction v, r, s values")
|
ErrInvalidSig = errors.New("invalid transaction v, r, s values")
|
||||||
)
|
)
|
||||||
|
|
@ -387,6 +390,7 @@ type Message struct {
|
||||||
gasPrice *big.Int
|
gasPrice *big.Int
|
||||||
data []byte
|
data []byte
|
||||||
checkNonce bool
|
checkNonce bool
|
||||||
|
txType TxType
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewMessage(from common.Address, to *common.Address, nonce uint64, amount *big.Int, gasLimit uint64, gasPrice *big.Int, data []byte, checkNonce bool) Message {
|
func NewMessage(from common.Address, to *common.Address, nonce uint64, amount *big.Int, gasLimit uint64, gasPrice *big.Int, data []byte, checkNonce bool) Message {
|
||||||
|
|
@ -410,3 +414,4 @@ func (m Message) Gas() uint64 { return m.gasLimit }
|
||||||
func (m Message) Nonce() uint64 { return m.nonce }
|
func (m Message) Nonce() uint64 { return m.nonce }
|
||||||
func (m Message) Data() []byte { return m.data }
|
func (m Message) Data() []byte { return m.data }
|
||||||
func (m Message) CheckNonce() bool { return m.checkNonce }
|
func (m Message) CheckNonce() bool { return m.checkNonce }
|
||||||
|
func (m Message) Type() TxType { return m.txType }
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue