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
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"math/big"
|
||||
"testing"
|
||||
|
||||
|
|
@ -14,6 +16,44 @@ import (
|
|||
//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) {
|
||||
voteMap := map[common.Address][]common.Address{
|
||||
common.HexToAddress("0x44d1ce0b7cb3588bca96151fe1bc05af38f91b6e"): {
|
||||
|
|
@ -38,10 +78,12 @@ func TestEpochContextCountVotes(t *testing.T) {
|
|||
assert.Nil(t, err)
|
||||
|
||||
epochContext := &EpochContext{
|
||||
Context: LCPContext,
|
||||
statedb: stateDB,
|
||||
Context: LCPContext,
|
||||
statedb: stateDB,
|
||||
}
|
||||
_, err = epochContext.countVotes()
|
||||
|
||||
// _, err = epochContext.countVotes()
|
||||
_, err = epochContext.cVotes()
|
||||
assert.NotNil(t, err)
|
||||
|
||||
for candidate, electors := range voteMap {
|
||||
|
|
@ -49,17 +91,30 @@ func TestEpochContextCountVotes(t *testing.T) {
|
|||
for _, elector := range electors {
|
||||
stateDB.SetBalance(elector, big.NewInt(balance))
|
||||
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()
|
||||
assert.Nil(t, err)
|
||||
assert.Equal(t, len(voteMap), len(result))
|
||||
|
||||
for candidate, electors := range voteMap {
|
||||
voteCount, ok := result[candidate]
|
||||
assert.True(t, ok)
|
||||
|
||||
fmt.Println("voteCount =", voteCount)
|
||||
fmt.Println("ele =", balance*int64(len(electors)))
|
||||
|
||||
assert.Equal(t, balance*int64(len(electors)), voteCount.Int64())
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
//func TestLookupValidator(t *testing.T) {
|
||||
// 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,
|
||||
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
|
||||
AccumulateRewards(chain.Config(), state, header, uncles)
|
||||
header.Root = state.IntermediateRoot(chain.Config().IsEIP158(header.Number))
|
||||
|
|
|
|||
|
|
@ -17,6 +17,8 @@
|
|||
package core
|
||||
|
||||
import (
|
||||
"math/big"
|
||||
|
||||
"github.com/pavelkrolevets/go-ethereum/common"
|
||||
"github.com/pavelkrolevets/go-ethereum/consensus"
|
||||
"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 {
|
||||
misc.ApplyDAOHardFork(statedb)
|
||||
}
|
||||
// Set out block dpos context
|
||||
// Iterate over and process the individual transactions
|
||||
for i, tx := range block.Transactions() {
|
||||
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 {
|
||||
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
|
||||
// for the transaction, gas used and an error if the transaction failed,
|
||||
// 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))
|
||||
if err != nil {
|
||||
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
|
||||
context := NewEVMContext(msg, header, bc, author)
|
||||
// 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 {
|
||||
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
|
||||
var root []byte
|
||||
if config.IsByzantium(header.Number) {
|
||||
|
|
@ -107,20 +120,40 @@ func ApplyTransaction(config *params.ChainConfig, bc ChainContext, author *commo
|
|||
} else {
|
||||
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
|
||||
// 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.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 msg.To() == nil {
|
||||
receipt.ContractAddress = crypto.CreateAddress(vmenv.Context.Origin, tx.Nonce())
|
||||
}
|
||||
|
||||
// Set the receipt logs and create a bloom for filtering
|
||||
receipt.Logs = statedb.GetLogs(tx.Hash())
|
||||
receipt.Bloom = types.CreateBloom(types.Receipts{receipt})
|
||||
|
||||
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
|
||||
|
||||
// transaction type
|
||||
type TxType uint8
|
||||
|
||||
var (
|
||||
ErrInvalidSig = errors.New("invalid transaction v, r, s values")
|
||||
)
|
||||
|
|
@ -387,6 +390,7 @@ type Message struct {
|
|||
gasPrice *big.Int
|
||||
data []byte
|
||||
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 {
|
||||
|
|
@ -410,3 +414,4 @@ func (m Message) Gas() uint64 { return m.gasLimit }
|
|||
func (m Message) Nonce() uint64 { return m.nonce }
|
||||
func (m Message) Data() []byte { return m.data }
|
||||
func (m Message) CheckNonce() bool { return m.checkNonce }
|
||||
func (m Message) Type() TxType { return m.txType }
|
||||
|
|
|
|||
Loading…
Reference in a new issue