Skip to content

Commit

Permalink
add dpos api
Browse files Browse the repository at this point in the history
  • Loading branch information
findbug2019 committed May 9, 2019
1 parent 1957dea commit 1fd0493
Show file tree
Hide file tree
Showing 15 changed files with 232 additions and 42 deletions.
12 changes: 6 additions & 6 deletions consensus/consensus.go
Original file line number Diff line number Diff line change
Expand Up @@ -102,17 +102,17 @@ type IEngine interface {

GetDelegatedByTime(state *state.StateDB, candidate string, timestamp uint64) (stake *big.Int, err error)

GetLatestEpcho(state *state.StateDB) (epcho uint64, err error)
GetLatestEpoch(state *state.StateDB) (epoch uint64, err error)

GetPrevEpcho(state *state.StateDB, epcho uint64) (pecho uint64, err error)
GetPrevEpoch(state *state.StateDB, epoch uint64) (pecho uint64, err error)

GetActivedCandidateSize(state *state.StateDB, epcho uint64) (size uint64, err error)
GetActivedCandidateSize(state *state.StateDB, epoch uint64) (size uint64, err error)

GetActivedCandidate(state *state.StateDB, epcho uint64, index uint64) (name string, stake *big.Int, counter uint64, actualCounter uint64, replace uint64, err error)
GetActivedCandidate(state *state.StateDB, epoch uint64, index uint64) (name string, stake *big.Int, counter uint64, actualCounter uint64, replace uint64, err error)

GetCandidateStake(state *state.StateDB, epcho uint64, candidate string) (stake *big.Int, err error)
GetCandidateStake(state *state.StateDB, epoch uint64, candidate string) (stake *big.Int, err error)

GetVoterStake(state *state.StateDB, epcho uint64, voter string, candidate string) (stake *big.Int, err error)
GetVoterStake(state *state.StateDB, epoch uint64, voter string, candidate string) (stake *big.Int, err error)

IAPI
}
Expand Down
6 changes: 3 additions & 3 deletions consensus/dpos/dpos.go
Original file line number Diff line number Diff line change
Expand Up @@ -427,15 +427,15 @@ func (dpos *Dpos) GetDelegatedByTime(state *state.StateDB, candidate string, tim
}

// GetLatestEpcho get latest epcho
func (dpos *Dpos) GetLatestEpcho(state *state.StateDB) (epcho uint64, err error) {
func (dpos *Dpos) GetLatestEpoch(state *state.StateDB) (epoch uint64, err error) {
sys := NewSystem(state, dpos.config)
return sys.GetLastestEpcho()
}

// GetPrevEpcho get pre epcho
func (dpos *Dpos) GetPrevEpcho(state *state.StateDB, epcho uint64) (uint64, error) {
func (dpos *Dpos) GetPrevEpoch(state *state.StateDB, epoch uint64) (uint64, error) {
sys := NewSystem(state, dpos.config)
gstate, err := sys.GetState(epcho)
gstate, err := sys.GetState(epoch)
if err != nil {
return 0, err
}
Expand Down
2 changes: 1 addition & 1 deletion ftservice/apibackend.go
Original file line number Diff line number Diff line change
Expand Up @@ -263,7 +263,7 @@ func (b *APIBackend) GetEVM(ctx context.Context, account *accountmanager.Account

evmcontext := &processor.EvmContext{
ChainContext: b.ftservice.BlockChain(),
EgnineContext: b.ftservice.Engine(),
EngineContext: b.ftservice.Engine(),
}

context := processor.NewEVMContext(from, assetID, gasPrice, header, evmcontext, nil)
Expand Down
8 changes: 8 additions & 0 deletions params/gas_table.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,10 @@ type GasTable struct {
CryptoByte uint64
DeductGas uint64
WithdrawFee uint64
GetEpoch uint64
GetCandidateNum uint64
GetCandidate uint64
GetVoterStake uint64
}

// Variables containing gas prices for different phases.
Expand Down Expand Up @@ -74,5 +78,9 @@ var (
CryptoCalc: 20000,
CryptoByte: 1000,
DeductGas: 200,
GetEpoch: 200,
GetCandidateNum: 200,
GetCandidate: 200,
GetVoterStake: 200,
}
)
40 changes: 22 additions & 18 deletions processor/evm.go
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ type ChainContext interface {
ForkUpdate(block *types.Block, statedb *state.StateDB) error
}

type EgnineContext interface {
type EngineContext interface {
// Author retrieves the address of the account that minted the given
// block, which may be different from the header's coinbase if a consensus
// engine is based on signatures.
Expand All @@ -82,22 +82,20 @@ type EgnineContext interface {

GetDelegatedByTime(state *state.StateDB, candidate string, timestamp uint64) (stake *big.Int, err error)

GetLatestEpcho(state *state.StateDB) (epcho uint64, err error)
GetLatestEpoch(state *state.StateDB) (epoch uint64, err error)

GetPrevEpcho(state *state.StateDB, epcho uint64) (pecho uint64, err error)
GetPrevEpoch(state *state.StateDB, epoch uint64) (peoch uint64, err error)

GetActivedCandidateSize(state *state.StateDB, epcho uint64) (size uint64, err error)
GetActivedCandidateSize(state *state.StateDB, epoch uint64) (size uint64, err error)

GetActivedCandidate(state *state.StateDB, epcho uint64, index uint64) (name string, stake *big.Int, counter uint64, actualCounter uint64, replace uint64, err error)
GetActivedCandidate(state *state.StateDB, epoch uint64, index uint64) (name string, stake *big.Int, counter uint64, actualCounter uint64, replace uint64, err error)

GetCandidateStake(state *state.StateDB, epcho uint64, candidate string) (stake *big.Int, err error)

GetVoterStake(state *state.StateDB, epcho uint64, voter string, candidate string) (stake *big.Int, err error)
GetVoterStake(state *state.StateDB, epoch uint64, voter string, candidate string) (stake *big.Int, err error)
}

type EvmContext struct {
ChainContext
EgnineContext
EngineContext
}

// NewEVMContext creates a new context for use in the EVM.
Expand All @@ -112,15 +110,21 @@ func NewEVMContext(sender common.Name, assetID uint64, gasPrice *big.Int, header
return vm.Context{
GetHash: GetHashFn(header, chain),
GetDelegatedByTime: chain.GetDelegatedByTime,
GetHeaderByNumber: chain.GetHeaderByNumber,
Origin: sender,
AssetID: assetID,
Coinbase: beneficiary,
BlockNumber: new(big.Int).Set(header.Number),
Time: new(big.Int).Set(header.Time),
Difficulty: new(big.Int).Set(header.Difficulty),
GasLimit: header.GasLimit,
GasPrice: new(big.Int).Set(gasPrice),
//Engine: chain,
GetLatestEpoch: chain.GetLatestEpoch,
GetPrevEpoch: chain.GetPrevEpoch,
GetActivedCandidateSize: chain.GetActivedCandidateSize,
GetActivedCandidate: chain.GetActivedCandidate,
GetVoterStake: chain.GetVoterStake,
GetHeaderByNumber: chain.GetHeaderByNumber,
Origin: sender,
AssetID: assetID,
Coinbase: beneficiary,
BlockNumber: new(big.Int).Set(header.Number),
Time: new(big.Int).Set(header.Time),
Difficulty: new(big.Int).Set(header.Difficulty),
GasLimit: header.GasLimit,
GasPrice: new(big.Int).Set(gasPrice),
}
}

Expand Down
2 changes: 1 addition & 1 deletion processor/processor.go
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,7 @@ func (p *StateProcessor) ApplyTransaction(author *common.Name, gp *common.GasPoo

evmcontext := &EvmContext{
ChainContext: p.bc,
EgnineContext: p.engine,
EngineContext: p.engine,
}
context := NewEVMContext(action.Sender(), assetID, tx.GasPrice(), header, evmcontext, author)
vmenv := vm.NewEVM(context, accountDB, statedb, config, cfg)
Expand Down
6 changes: 3 additions & 3 deletions processor/transition.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ var (
)

type StateTransition struct {
engine EgnineContext
engine EngineContext
from common.Name
gp *common.GasPool
action *types.Action
Expand All @@ -50,7 +50,7 @@ type StateTransition struct {
}

// NewStateTransition initialises and returns a new state transition object.
func NewStateTransition(accountDB *accountmanager.AccountManager, evm *vm.EVM, action *types.Action, gp *common.GasPool, gasPrice *big.Int, assetID uint64, config *params.ChainConfig, engine EgnineContext) *StateTransition {
func NewStateTransition(accountDB *accountmanager.AccountManager, evm *vm.EVM, action *types.Action, gp *common.GasPool, gasPrice *big.Int, assetID uint64, config *params.ChainConfig, engine EngineContext) *StateTransition {
return &StateTransition{
engine: engine,
from: action.Sender(),
Expand All @@ -65,7 +65,7 @@ func NewStateTransition(accountDB *accountmanager.AccountManager, evm *vm.EVM, a
}

// ApplyMessage computes the new state by applying the given message against the old state within the environment.
func ApplyMessage(accountDB *accountmanager.AccountManager, evm *vm.EVM, action *types.Action, gp *common.GasPool, gasPrice *big.Int, assetID uint64, config *params.ChainConfig, engine EgnineContext) ([]byte, uint64, bool, error, error) {
func ApplyMessage(accountDB *accountmanager.AccountManager, evm *vm.EVM, action *types.Action, gp *common.GasPool, gasPrice *big.Int, assetID uint64, config *params.ChainConfig, engine EngineContext) ([]byte, uint64, bool, error, error) {
return NewStateTransition(accountDB, evm, action, gp, gasPrice, assetID, config, engine).TransitionDb()
}

Expand Down
16 changes: 16 additions & 0 deletions processor/vm/gas_table.go
Original file line number Diff line number Diff line change
Expand Up @@ -424,6 +424,22 @@ func gasDelegateCall(gt params.GasTable, evm *EVM, contract *Contract, stack *St
return gas, nil
}

func gasGetEpoch(gt params.GasTable, evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) {
return gt.GetEpoch, nil
}

func gasGetCandidateNum(gt params.GasTable, evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) {
return gt.GetCandidateNum, nil
}

func gasGetCandidate(gt params.GasTable, evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) {
return gt.GetCandidate, nil
}

func gasGetVoterStake(gt params.GasTable, evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) {
return gt.GetVoterStake, nil
}

func gasIssueAsset(gt params.GasTable, evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) {
return gt.IssueAsset, nil
}
Expand Down
85 changes: 85 additions & 0 deletions processor/vm/instructions.go
Original file line number Diff line number Diff line change
Expand Up @@ -1022,6 +1022,91 @@ func opDelegateCall(pc *uint64, evm *EVM, contract *Contract, memory *Memory, st
}

//multi-asset
// opGetEpoch get epoch
func opGetEpoch(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
fmt.Println("in opGetEpoch")
epochID := stack.pop()
id := epochID.Uint64()
var num uint64
var err error
fmt.Println("in opGetEpoch 1")

if id == 0 {
num, err = evm.Context.GetLatestEpoch(evm.StateDB)

} else {
num, err = evm.Context.GetPrevEpoch(evm.StateDB, id)
}
fmt.Println("in opGetEpoch 2")
if err != nil {
stack.push(evm.interpreter.intPool.getZero())
} else {
stack.push(evm.interpreter.intPool.get().SetUint64(num))
}
return nil, nil
}

// opGetCandidateNum get Candidate num
func opGetCandidateNum(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
fmt.Println("in opGetCandidateNum")
epochID := stack.pop()
id := epochID.Uint64()
num, err := evm.Context.GetActivedCandidateSize(evm.StateDB, id)
if err != nil {
stack.push(evm.interpreter.intPool.getZero())
} else {
stack.push(evm.interpreter.intPool.get().SetUint64(num))
}
return nil, nil
}

// opGetCandidate
func opGetCandidate(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
fmt.Println("in opGetCandidate")
nameOffset, nameSize, index, epochID := stack.pop(), stack.pop(), stack.pop(), stack.pop()
id := epochID.Uint64()
i := index.Uint64()
//
name, stake, counter, actualCounter, replace, err := evm.Context.GetActivedCandidate(evm.StateDB, id, i)
nameBytes := []byte(name)
datalen := len(nameBytes)
if uint64(datalen) > nameSize.Uint64()*32 {
err = errors.New("out of space")
}
if err != nil {
stack.push(evm.interpreter.intPool.getZero())
stack.push(evm.interpreter.intPool.getZero())
stack.push(evm.interpreter.intPool.getZero())
stack.push(evm.interpreter.intPool.getZero())
//don't copy
} else {
stack.push(evm.interpreter.intPool.get().SetUint64(replace))
stack.push(evm.interpreter.intPool.get().SetUint64(actualCounter))
stack.push(evm.interpreter.intPool.get().SetUint64(counter))
stack.push(evm.interpreter.intPool.get().Set(stake))
memory.Set(nameOffset.Uint64(), uint64(datalen), nameBytes)
}
return nil, nil
}

// opGetVoterStake
func opGetVoterStake(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
fmt.Println("in opGetVoterStake")
candidateOffet, candidateSize, voterOffset, voterSize, epochID := stack.pop(), stack.pop(), stack.pop(), stack.pop(), stack.pop()
id := epochID.Uint64()
voter := memory.Get(voterOffset.Int64(), voterSize.Int64())

candidate := memory.Get(candidateOffet.Int64(), candidateSize.Int64())
//
num, err := evm.Context.GetVoterStake(evm.StateDB, id, string(voter), string(candidate))
if err != nil {
stack.push(evm.interpreter.intPool.getZero())
} else {
stack.push(evm.interpreter.intPool.get().Set(num))
}
return nil, nil
}

//Increase asset already exist
func opAddAsset(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) {
value, to, assetId := stack.pop(), stack.pop(), stack.pop()
Expand Down
32 changes: 32 additions & 0 deletions processor/vm/jump_table.go
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,38 @@ func NewByzantiumInstructionSet() [256]operation {
instructionSet := NewHomesteadInstructionSet()

//multi-asset InstructionSet
instructionSet[GETEPCHO] = operation{
execute: opGetEpoch,
gasCost: gasGetEpoch,
validateStack: makeStackFunc(1, 1),
valid: true,
returns: true,
}

instructionSet[GETCANDIDATENUM] = operation{
execute: opGetCandidateNum,
gasCost: gasGetCandidateNum,
validateStack: makeStackFunc(2, 1),
valid: true,
returns: true,
}

instructionSet[GETCANDIDATE] = operation{
execute: opGetCandidate,
gasCost: gasGetCandidate,
validateStack: makeStackFunc(2, 1),
valid: true,
returns: true,
}

instructionSet[GETVOTERSTAKE] = operation{
execute: opGetVoterStake,
gasCost: gasGetVoterStake,
validateStack: makeStackFunc(2, 1),
valid: true,
returns: true,
}

instructionSet[GETACCOUNTTIME] = operation{
execute: opGetAccountTime,
gasCost: gasGetAccountTime,
Expand Down
8 changes: 8 additions & 0 deletions processor/vm/opcodes.go
Original file line number Diff line number Diff line change
Expand Up @@ -220,6 +220,14 @@ const (
WITHDRAWFEE = 0xce
)

const (
//0xd0 range new add for dpos
GETEPCHO OpCode = 0xd0 + iota
GETCANDIDATENUM = 0xd1
GETCANDIDATE = 0xd2
GETVOTERSTAKE = 0xd3
)

const (
// 0xf0 range - closures
CREATE OpCode = 0xf0 + iota
Expand Down
14 changes: 7 additions & 7 deletions processor/vm/runtime/run_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,20 +32,20 @@ import (

//TestRunCode run runtime code directly
func TestRunCode(t *testing.T) {
fmt.Println("in TestRunCode ...")
//fmt.Println("in TestRunCode ...")
state, _ := state.New(common.Hash{}, state.NewDatabase(mdb.NewMemDatabase()))
account, _ := accountmanager.NewAccountManager(state)
fmt.Println("in TestRunCode2 ...")
//fmt.Println("in TestRunCode2 ...")
//sender
senderName := common.Name("jacobwolf")
senderPubkey := common.HexToPubKey("12345")
//
receiverName := common.Name("denverfolk")
receiverPubkey := common.HexToPubKey("12345")
//
toName := common.Name("fractal.account")
toName := common.Name("fractal.asset")

fmt.Println("in TestRunCode3 ...")
//fmt.Println("in TestRunCode3 ...")
if err := account.CreateAccount(senderName, "", 0, senderPubkey, ""); err != nil {
fmt.Println("create sender account error\n", err)
return
Expand All @@ -71,14 +71,14 @@ func TestRunCode(t *testing.T) {
FromPubkey: senderPubkey,
State: state,
Account: account,
AssetID: 1,
AssetID: 0,
GasLimit: 10000000000,
GasPrice: big.NewInt(0),
Value: big.NewInt(0),
BlockNumber: new(big.Int).SetUint64(0),
}

var code = common.Hex2Bytes("60806040526004361061004c576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff16806342d6c33514610051578063f1db54161461007c575b600080fd5b34801561005d57600080fd5b506100666100a7565b6040518082815260200191505060405180910390f35b34801561008857600080fd5b506100916100b2565b6040518082815260200191505060405180910390f35b60006001cb80905090565b600060608060606040805190810160405280600d81526020017f48656c6c6f2c20776f726c642e00000000000000000000000000000000000000815250925060c06040519081016040528060828152602001610177608291399150600a6040519080825280601f01601f1916602001820160405280156101415781602001602082028038833980820191505090505b5090508280519060200183805190602001848051906020016000cc80601f01601f191660405101604052935083935050505090560030343764623232376437303934636532313563336130663537653162636337333235353166653335316639343234393437313933343536376530663564633162663739353936326238636363623837613265623536623239666265333764363134653266346333633435623738396165346631663531663463623231393732666664a165627a7a7230582058439b3945a21edad9fde8f2430422ca01d9a2c5092de618efa65db15f44d60e0029")
var code = common.Hex2Bytes("608060405260043610610057576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff16806342d6c3351461005c57806359b5d50e14610073578063f1db541614610209575b600080fd5b34801561006857600080fd5b50610071610234565b005b34801561007f57600080fd5b506100a860048036038101908080359060200190929190803590602001909291905050506102b1565b60405180806020018060200180602001868152602001858152602001848103845289818151815260200191508051906020019080838360005b838110156100fc5780820151818401526020810190506100e1565b50505050905090810190601f1680156101295780820380516001836020036101000a031916815260200191505b50848103835288818151815260200191508051906020019080838360005b83811015610162578082015181840152602081019050610147565b50505050905090810190601f16801561018f5780820380516001836020036101000a031916815260200191505b50848103825287818151815260200191508051906020019080838360005b838110156101c85780820151818401526020810190506101ad565b50505050905090810190601f1680156101f55780820380516001836020036101000a031916815260200191505b509850505050505050505060405180910390f35b34801561021557600080fd5b5061021e6102c3565b6040518082815260200191505060405180910390f35b6060600080600080600080600080600060146040519080825280601f01601f1916602001820160405280156102785781602001602082028038833980820191505090505b5099506000d092506001d191506001808b805190602001d2809750819850829950839a50505050506001d3905050505050505050505050565b60608060606000809295509295909350565b600060608060606040805190810160405280600d81526020017f48656c6c6f2c20776f726c642e00000000000000000000000000000000000000815250925060c06040519081016040528060828152602001610388608291399150600a6040519080825280601f01601f1916602001820160405280156103525781602001602082028038833980820191505090505b5090508280519060200183805190602001848051906020016000cc80601f01601f191660405101604052935083935050505090560030343764623232376437303934636532313563336130663537653162636337333235353166653335316639343234393437313933343536376530663564633162663739353936326238636363623837613265623536623239666265333764363134653266346333633435623738396165346631663531663463623231393732666664a165627a7a72305820d22a7ad5b5cfe3f13dddb0c61e44fa503114ced03aaad620b89fd62b384f77a30029")
// myBinfile := "./contract/Ven/VEN.bin"
myAbifile := "./contract/crypto/testcrypto.abi"

Expand Down Expand Up @@ -108,7 +108,7 @@ func TestRunCode(t *testing.T) {
return
}

action = types.NewAction(types.Transfer, runtimeConfig.Origin, receiverName, 0, runtimeConfig.AssetID, runtimeConfig.GasLimit, runtimeConfig.Value, myInput, nil)
action = types.NewAction(types.CallContract, runtimeConfig.Origin, receiverName, 0, runtimeConfig.AssetID, runtimeConfig.GasLimit, runtimeConfig.Value, myInput, nil)

ret, _, err := Call(action, &runtimeConfig)
if err != nil {
Expand Down

0 comments on commit 1fd0493

Please sign in to comment.