support rosetta tracer

pull/4065/head
Lutty 3 years ago
parent 315bd4f982
commit d9e933c7f3
  1. 14
      core/evm.go
  2. 8
      core/staking_verifier_test.go
  3. 9
      core/state/state_object.go
  4. 10
      core/state_transition.go
  5. 13
      core/vm/contracts_write.go
  6. 14
      core/vm/evm.go
  7. 14
      hmy/tracers/rosetta_block_tracer.go
  8. 2
      node/node_syncing.go
  9. 14
      rosetta/services/block.go

@ -47,6 +47,8 @@ type ChainContext interface {
// ReadDelegationsByDelegator returns the validators list of a delegator
ReadDelegationsByDelegator(common.Address) (stakingTypes.DelegationIndexes, error)
ReadDelegationsByDelegatorAt(delegator common.Address, blockNum *big.Int) (m stakingTypes.DelegationIndexes, err error)
// ReadValidatorSnapshot returns the snapshot of validator at the beginning of current epoch.
ReadValidatorSnapshot(common.Address) (*stakingTypes.ValidatorSnapshot, error)
@ -104,7 +106,7 @@ func NewEVMContext(msg Message, header *block.Header, chain ChainContext, author
// the function can then be called through the EVM context
func CreateValidatorFn(ref *block.Header, chain ChainContext) vm.CreateValidatorFunc {
// moved from state_transition.go to here, with some modifications
return func(db vm.StateDB, createValidator *stakingTypes.CreateValidator) error {
return func(db vm.StateDB, rosettaTracer vm.RosettaTracer, createValidator *stakingTypes.CreateValidator) error {
wrapper, err := VerifyAndCreateValidatorFromMsg(
db, chain, ref.Epoch(), ref.Number(), createValidator,
)
@ -122,7 +124,7 @@ func CreateValidatorFn(ref *block.Header, chain ChainContext) vm.CreateValidator
func EditValidatorFn(ref *block.Header, chain ChainContext) vm.EditValidatorFunc {
// moved from state_transition.go to here, with some modifications
return func(db vm.StateDB, editValidator *stakingTypes.EditValidator) error {
return func(db vm.StateDB, rosettaTracer vm.RosettaTracer, editValidator *stakingTypes.EditValidator) error {
wrapper, err := VerifyAndEditValidatorFromMsg(
db, chain, ref.Epoch(), ref.Number(), editValidator,
)
@ -135,8 +137,8 @@ func EditValidatorFn(ref *block.Header, chain ChainContext) vm.EditValidatorFunc
func DelegateFn(ref *block.Header, chain ChainContext) vm.DelegateFunc {
// moved from state_transition.go to here, with some modifications
return func(db vm.StateDB, delegate *stakingTypes.Delegate) error {
delegations, err := chain.ReadDelegationsByDelegator(delegate.DelegatorAddress)
return func(db vm.StateDB, rosettaTracer vm.RosettaTracer, delegate *stakingTypes.Delegate) error {
delegations, err := chain.ReadDelegationsByDelegatorAt(delegate.DelegatorAddress, big.NewInt(0).Sub(ref.Number(), big.NewInt(1)))
if err != nil {
return err
}
@ -188,7 +190,7 @@ func DelegateFn(ref *block.Header, chain ChainContext) vm.DelegateFunc {
func UndelegateFn(ref *block.Header, chain ChainContext) vm.UndelegateFunc {
// moved from state_transition.go to here, with some modifications
return func(db vm.StateDB, undelegate *stakingTypes.Undelegate) error {
return func(db vm.StateDB, rosettaTracer vm.RosettaTracer, undelegate *stakingTypes.Undelegate) error {
wrapper, err := VerifyAndUndelegateFromMsg(db, ref.Epoch(), undelegate)
if err != nil {
return err
@ -198,7 +200,7 @@ func UndelegateFn(ref *block.Header, chain ChainContext) vm.UndelegateFunc {
}
func CollectRewardsFn(ref *block.Header, chain ChainContext) vm.CollectRewardsFunc {
return func(db vm.StateDB, collectRewards *stakingTypes.CollectRewards) error {
return func(db vm.StateDB, rosettaTracer vm.RosettaTracer, collectRewards *stakingTypes.CollectRewards) error {
if chain == nil {
return errors.New("[CollectRewards] No chain context provided")
}

@ -1739,6 +1739,10 @@ func (chain *fakeChainContext) ReadDelegationsByDelegator(common.Address) (staki
return nil, nil
}
func (chain *fakeChainContext) ReadDelegationsByDelegatorAt(delegator common.Address, blockNum *big.Int) (staking.DelegationIndexes, error) {
return nil, nil
}
func (chain *fakeChainContext) ShardID() uint32 {
return shard.BeaconChainShardID
}
@ -1779,6 +1783,10 @@ func (chain *fakeErrChainContext) ReadDelegationsByDelegator(common.Address) (st
return nil, nil
}
func (chain *fakeErrChainContext) ReadDelegationsByDelegatorAt(delegator common.Address, blockNum *big.Int) (staking.DelegationIndexes, error) {
return nil, nil
}
func (chain *fakeErrChainContext) ShardID() uint32 {
return 900 // arbitrary number different from BeaconChainShardID
}

@ -341,6 +341,9 @@ func (s *Object) CommitTrie(db Database) error {
// AddBalance removes amount from c's balance.
// It is used to add funds to the destination account of a transfer.
func (s *Object) AddBalance(amount *big.Int) {
if s.address.String() == "0x9aFba568f59854539D17B9120B6E4d31b9e8a3eF" {
fmt.Printf("AddBalance: %s => %s\n", s.address.String(), amount.String())
}
// EIP158: We must check emptiness for the objects such that the account
// clearing (0,0,0 objects) can take effect.
if amount.Sign() == 0 {
@ -356,6 +359,9 @@ func (s *Object) AddBalance(amount *big.Int) {
// SubBalance removes amount from c's balance.
// It is used to remove funds from the origin account of a transfer.
func (s *Object) SubBalance(amount *big.Int) {
if s.address.String() == "0x9aFba568f59854539D17B9120B6E4d31b9e8a3eF" {
fmt.Printf("SubBalance: %s\n", amount.String())
}
if amount.Sign() == 0 {
return
}
@ -364,6 +370,9 @@ func (s *Object) SubBalance(amount *big.Int) {
// SetBalance ...
func (s *Object) SetBalance(amount *big.Int) {
if s.address.String() == "0x9aFba568f59854539D17B9120B6E4d31b9e8a3eF" {
fmt.Printf("SetBalance: %s\n", amount.String())
}
s.db.journal.append(balanceChange{
account: &s.address,
prev: new(big.Int).Set(s.data.Balance),

@ -328,7 +328,7 @@ func (st *StateTransition) StakingTransitionDb() (usedGas uint64, err error) {
if msg.From() != stkMsg.ValidatorAddress {
return 0, errInvalidSigner
}
err = st.evm.CreateValidator(st.evm.StateDB, stkMsg)
err = st.evm.CreateValidator(st.evm.StateDB, nil, stkMsg)
case types.StakeEditVal:
stkMsg := &stakingTypes.EditValidator{}
if err = rlp.DecodeBytes(msg.Data(), stkMsg); err != nil {
@ -339,7 +339,7 @@ func (st *StateTransition) StakingTransitionDb() (usedGas uint64, err error) {
if msg.From() != stkMsg.ValidatorAddress {
return 0, errInvalidSigner
}
err = st.evm.EditValidator(st.evm.StateDB, stkMsg)
err = st.evm.EditValidator(st.evm.StateDB, nil, stkMsg)
case types.Delegate:
stkMsg := &stakingTypes.Delegate{}
if err = rlp.DecodeBytes(msg.Data(), stkMsg); err != nil {
@ -349,7 +349,7 @@ func (st *StateTransition) StakingTransitionDb() (usedGas uint64, err error) {
if msg.From() != stkMsg.DelegatorAddress {
return 0, errInvalidSigner
}
err = st.evm.Delegate(st.evm.StateDB, stkMsg)
err = st.evm.Delegate(st.evm.StateDB, nil, stkMsg)
case types.Undelegate:
stkMsg := &stakingTypes.Undelegate{}
if err = rlp.DecodeBytes(msg.Data(), stkMsg); err != nil {
@ -359,7 +359,7 @@ func (st *StateTransition) StakingTransitionDb() (usedGas uint64, err error) {
if msg.From() != stkMsg.DelegatorAddress {
return 0, errInvalidSigner
}
err = st.evm.Undelegate(st.evm.StateDB, stkMsg)
err = st.evm.Undelegate(st.evm.StateDB, nil, stkMsg)
case types.CollectRewards:
stkMsg := &stakingTypes.CollectRewards{}
if err = rlp.DecodeBytes(msg.Data(), stkMsg); err != nil {
@ -369,7 +369,7 @@ func (st *StateTransition) StakingTransitionDb() (usedGas uint64, err error) {
if msg.From() != stkMsg.DelegatorAddress {
return 0, errInvalidSigner
}
err = st.evm.CollectRewards(st.evm.StateDB, stkMsg)
err = st.evm.CollectRewards(st.evm.StateDB, nil, stkMsg)
default:
return 0, stakingTypes.ErrInvalidStakingKind
}

@ -2,7 +2,6 @@ package vm
import (
"errors"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/rlp"
"github.com/harmony-one/harmony/shard"
@ -112,8 +111,14 @@ func (c *stakingPrecompile) RunWriteCapable(
if err != nil {
return nil, err
}
var rosettaBlockTracer RosettaTracer
if tmpTracker, ok := evm.vmConfig.Tracer.(RosettaTracer); ok {
rosettaBlockTracer = tmpTracker
}
if delegate, ok := stakeMsg.(*stakingTypes.Delegate); ok {
if err := evm.Delegate(evm.StateDB, delegate); err != nil {
if err := evm.Delegate(evm.StateDB, rosettaBlockTracer, delegate); err != nil {
return nil, err
} else {
evm.StakeMsgs = append(evm.StakeMsgs, delegate)
@ -121,10 +126,10 @@ func (c *stakingPrecompile) RunWriteCapable(
}
}
if undelegate, ok := stakeMsg.(*stakingTypes.Undelegate); ok {
return nil, evm.Undelegate(evm.StateDB, undelegate)
return nil, evm.Undelegate(evm.StateDB, rosettaBlockTracer, undelegate)
}
if collectRewards, ok := stakeMsg.(*stakingTypes.CollectRewards); ok {
return nil, evm.CollectRewards(evm.StateDB, collectRewards)
return nil, evm.CollectRewards(evm.StateDB, rosettaBlockTracer, collectRewards)
}
// Migrate is not supported in precompile and will be done in a batch hard fork
//if migrationMsg, ok := stakeMsg.(*stakingTypes.MigrationMsg); ok {

@ -32,6 +32,10 @@ import (
// deployed contract addresses (relevant after the account abstraction).
var emptyCodeHash = crypto.Keccak256Hash(nil)
type RosettaTracer interface {
AddRosettaLog(op OpCode, from, to common.Address, val *big.Int)
}
type (
// CanTransferFunc is the signature of a transfer guard function
CanTransferFunc func(StateDB, common.Address, *big.Int) bool
@ -46,11 +50,11 @@ type (
// and is used by the precompile VRF contract.
GetVRFFunc func(uint64) common.Hash
// Below functions are used by staking precompile, and state transition
CreateValidatorFunc func(db StateDB, stakeMsg *stakingTypes.CreateValidator) error
EditValidatorFunc func(db StateDB, stakeMsg *stakingTypes.EditValidator) error
DelegateFunc func(db StateDB, stakeMsg *stakingTypes.Delegate) error
UndelegateFunc func(db StateDB, stakeMsg *stakingTypes.Undelegate) error
CollectRewardsFunc func(db StateDB, stakeMsg *stakingTypes.CollectRewards) error
CreateValidatorFunc func(db StateDB, rosettaTracer RosettaTracer, stakeMsg *stakingTypes.CreateValidator) error
EditValidatorFunc func(db StateDB, rosettaTracer RosettaTracer, stakeMsg *stakingTypes.EditValidator) error
DelegateFunc func(db StateDB, rosettaTracer RosettaTracer, stakeMsg *stakingTypes.Delegate) error
UndelegateFunc func(db StateDB, rosettaTracer RosettaTracer, stakeMsg *stakingTypes.Undelegate) error
CollectRewardsFunc func(db StateDB, rosettaTracer RosettaTracer, stakeMsg *stakingTypes.CollectRewards) error
// Used for migrating delegations via the staking precompile
//MigrateDelegationsFunc func(db StateDB, migrationMsg *stakingTypes.MigrationMsg) ([]interface{}, error)
CalculateMigrationGasFunc func(db StateDB, migrationMsg *stakingTypes.MigrationMsg, homestead bool, istanbul bool) (uint64, error)

@ -34,6 +34,8 @@ type RosettaLogItem struct {
type RosettaBlockTracer struct {
*ParityBlockTracer
logs []*RosettaLogItem
}
func (rbt *RosettaBlockTracer) formatAction(depth []int, parentErr error, ac *action) *RosettaLogItem {
@ -53,6 +55,18 @@ func (rbt *RosettaBlockTracer) formatAction(depth []int, parentErr error, ac *ac
}
}
func (rbt *RosettaBlockTracer) AddRosettaLog(op vm.OpCode, from, to common.Address, val *big.Int) {
rbt.logs = append(rbt.logs, &RosettaLogItem{
IsSuccess: true,
Reverted: false,
OP: op,
Depth: make([]int, 0),
From: from,
To: to,
Value: val,
})
}
func (rbt *RosettaBlockTracer) GetResult() ([]*RosettaLogItem, error) {
root := &rbt.action

@ -361,7 +361,7 @@ func (node *Node) supportSyncing() {
utils.Logger().Debug().Msg("[SYNC] initialized state sync")
}
go node.DoSyncing(node.Blockchain(), node.Worker, joinConsensus)
//go node.DoSyncing(node.Blockchain(), node.Worker, joinConsensus)
}
// InitSyncingServer starts downloader server.

@ -291,10 +291,10 @@ func init() {
func (s *BlockAPI) getTransactionTrace(
ctx context.Context, blk *hmytypes.Block, txInfo *transactionInfo,
) ([]*tracers.RosettaLogItem, *types.Error) {
cacheKey := blk.Hash().String() + txInfo.tx.Hash().String()
if value, ok := s.txTraceCache.Get(cacheKey); ok {
return value.([]*tracers.RosettaLogItem), nil
}
//cacheKey := blk.Hash().String() + txInfo.tx.Hash().String()
//if value, ok := s.txTraceCache.Get(cacheKey); ok {
// return value.([]*tracers.RosettaLogItem), nil
//}
lock := &sync.Mutex{}
if ok, _ := ttLock.ContainsOrAdd(blk.Hash().String(), lock); ok {
@ -310,9 +310,9 @@ func (s *BlockAPI) getTransactionTrace(
defer lock.Unlock()
}
if value, ok := s.txTraceCache.Get(cacheKey); ok {
return value.([]*tracers.RosettaLogItem), nil
}
//if value, ok := s.txTraceCache.Get(cacheKey); ok {
// return value.([]*tracers.RosettaLogItem), nil
//}
var blockError *types.Error
var foundResult []*tracers.RosettaLogItem

Loading…
Cancel
Save