interface.go 4.74 KB
Newer Older
贾浩@五瓣科技's avatar
贾浩@五瓣科技 committed
1 2 3 4 5
package core

import (
	"fmt"
	"math/big"
6
	"validator/tree"
贾浩@五瓣科技's avatar
贾浩@五瓣科技 committed
7 8 9 10 11 12

	"github.com/ethereum/go-ethereum/common"
	"github.com/ethereum/go-ethereum/crypto"
	log "github.com/sirupsen/logrus"
)

13 14
func (v *Validator) GetPendingWorkload(address common.Address) (workload, globalWorkload uint64) {
	wl, err := v.q.GetPendingWorkload(v.todayTimestamp(), address.Hex())
贾浩@五瓣科技's avatar
贾浩@五瓣科技 committed
15 16 17 18
	if err != nil {
		log.WithError(err).Error("failed to get pending workload")
		return
	}
贾浩@五瓣科技's avatar
贾浩@五瓣科技 committed
19 20 21 22
	log.WithFields(log.Fields{
		"address":  address.Hex(),
		"workload": wl,
	}).Debug("quest get pending workload")
23
	return wl, v.pendingWorkload
贾浩@五瓣科技's avatar
贾浩@五瓣科技 committed
24 25
}

26
func (v *Validator) GetMerkleProof(address common.Address, date string) (balance string, proofs []common.Hash) {
贾浩@五瓣科技's avatar
贾浩@五瓣科技 committed
27
	if date == "" {
28
		date = v.date
贾浩@五瓣科技's avatar
贾浩@五瓣科技 committed
29
	}
贾浩@五瓣科技's avatar
贾浩@五瓣科技 committed
30
	if ok := v.LoadMerkleTree(date); !ok {
贾浩@五瓣科技's avatar
贾浩@五瓣科技 committed
31
		log.WithFields(log.Fields{
贾浩@五瓣科技's avatar
贾浩@五瓣科技 committed
32 33
			"date": date,
		}).Error("load merkle proof empty")
贾浩@五瓣科技's avatar
贾浩@五瓣科技 committed
34 35
		return "0", nil
	}
贾浩@五瓣科技's avatar
贾浩@五瓣科技 committed
36 37 38
	v.Lock()
	cacheTree := v.mtTreeCache[date]
	v.Unlock()
贾浩@五瓣科技's avatar
贾浩@五瓣科技 committed
39
	var sdb *StateDB
40 41
	if date == v.date {
		sdb = v.state
贾浩@五瓣科技's avatar
贾浩@五瓣科技 committed
42
	} else {
贾浩@五瓣科技's avatar
贾浩@五瓣科技 committed
43 44 45 46 47 48 49 50 51
		dateStateRootKey := fmt.Sprintf("sroot:%s", date)
		dateStateRoot, err := v.lvdb.Get([]byte(dateStateRootKey))
		if err != nil {
			log.WithFields(log.Fields{
				"key": dateStateRootKey,
				"err": err.Error(),
			}).Error("failed to get state root")
			return "0", nil
		}
52
		sdb, err = NewStateDB(v.lvdb, common.BytesToHash(dateStateRoot))
贾浩@五瓣科技's avatar
贾浩@五瓣科技 committed
53 54 55 56 57 58 59 60 61
		if err != nil {
			log.WithError(err).Error("failed to create state db")
			return "0", nil
		}
	}
	object := sdb.GetMinerObject(address)
	if object == nil {
		return "0", nil
	}
贾浩@五瓣科技's avatar
贾浩@五瓣科技 committed
62 63 64
	if object.Balance == "" {
		object.Balance = "0"
	}
贾浩@五瓣科技's avatar
贾浩@五瓣科技 committed
65 66 67
	bigBalance, _ := new(big.Int).SetString(object.Balance, 10)
	payload := append(common.HexToAddress(object.Miner).Bytes(), common.LeftPadBytes(bigBalance.Bytes(), 32)...)
	leaf := crypto.Keccak256Hash(payload)
贾浩@五瓣科技's avatar
贾浩@五瓣科技 committed
68
	log.WithFields(log.Fields{
贾浩@五瓣科技's avatar
贾浩@五瓣科技 committed
69 70 71 72
		"date":    date,
		"root":    cacheTree.GetRoot().Hex(),
		"payload": payload,
		"leaf":    leaf.Hex(),
贾浩@五瓣科技's avatar
贾浩@五瓣科技 committed
73 74 75 76 77 78 79
	}).Debug("cacheTree.GetProof(leaf)")

	// 遍历tree
	for i, layer := range cacheTree.Layers() {
		log.WithField("depth", i).Debug(layer)
	}

贾浩@五瓣科技's avatar
贾浩@五瓣科技 committed
80
	proofs, err := cacheTree.GetProof(leaf)
贾浩@五瓣科技's avatar
贾浩@五瓣科技 committed
81 82 83 84
	if err != nil {
		log.WithError(err).Error("failed to get merkle proof")
		return "0", make([]common.Hash, 0)
	}
贾浩@五瓣科技's avatar
贾浩@五瓣科技 committed
85
	if len(proofs) == 0 {
贾浩@五瓣科技's avatar
贾浩@五瓣科技 committed
86
		return "0", make([]common.Hash, 0)
贾浩@五瓣科技's avatar
贾浩@五瓣科技 committed
87 88
	}

贾浩@五瓣科技's avatar
贾浩@五瓣科技 committed
89 90 91
	return object.Balance, proofs
}

92
func (v *Validator) GetDailyMerkleNodes(date string, depth int, rootHash common.Hash) (nodes [][]common.Hash) {
贾浩@五瓣科技's avatar
贾浩@五瓣科技 committed
93
	if date == "" {
94
		date = v.date
贾浩@五瓣科技's avatar
贾浩@五瓣科技 committed
95
	}
贾浩@五瓣科技's avatar
贾浩@五瓣科技 committed
96 97 98 99 100
	if ok := v.LoadMerkleTree(date); !ok {
		log.WithFields(log.Fields{
			"date": date,
		}).Error("load merkle proof empty")
		return nil
贾浩@五瓣科技's avatar
贾浩@五瓣科技 committed
101
	}
102
	v.Lock()
贾浩@五瓣科技's avatar
贾浩@五瓣科技 committed
103
	cacheTree := v.mtTreeCache[date]
104
	v.Unlock()
贾浩@五瓣科技's avatar
贾浩@五瓣科技 committed
105 106 107 108 109 110 111 112 113 114

	rootNode := cacheTree.GetRootNode()
	if rootHash.Hex() == (common.Hash{}).Hex() {
		rootNode = cacheTree.GetRootNode()
	} else if rootHash.Hex() != rootNode.Hash.Hex() {
		rootNode = cacheTree.FindMerkleNode(rootHash)
	}
	return tree.MerkleTreeTraversal(rootNode, depth)
}

115
func (v *Validator) GetDailyMerkleSumNodes(date string, depth int, rootHash common.Hash) (nodesHash [][]common.Hash, nodesVal [][]string) {
贾浩@五瓣科技's avatar
贾浩@五瓣科技 committed
116
	if date == "" {
117
		date = v.date
贾浩@五瓣科技's avatar
贾浩@五瓣科技 committed
118
	}
119 120 121
	v.Lock()
	cacheTree, ok := v.mstTreeCache[date]
	v.Unlock()
贾浩@五瓣科技's avatar
贾浩@五瓣科技 committed
122
	if !ok {
123
		if ok = v.LoadMerkleSumTree(date); !ok {
贾浩@五瓣科技's avatar
贾浩@五瓣科技 committed
124 125 126 127 128 129
			log.WithFields(log.Fields{
				"date": date,
			}).Error("load merkle sum proof empty")
			return nil, nil
		}
	}
130 131 132
	v.Lock()
	cacheTree = v.mstTreeCache[date]
	v.Unlock()
贾浩@五瓣科技's avatar
贾浩@五瓣科技 committed
133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152

	rootNode := cacheTree.GetRoot()
	if rootHash.Hex() == (common.Hash{}).Hex() {
		rootNode = cacheTree.GetRoot()
	} else if rootHash.Hex() != rootNode.Value.Hash.Hex() {
		rootNode = cacheTree.FindMerkleSumNode(rootHash)
	}
	vlss := tree.MerkleSumTreeTraversal(rootNode, depth)
	for i := 0; i < len(vlss); i++ {
		_nodesHash := make([]common.Hash, 0)
		_nodesVal := make([]string, 0)
		for j := 0; j < len(vlss[i]); j++ {
			_nodesHash = append(_nodesHash, vlss[i][j].Hash)
			_nodesVal = append(_nodesVal, vlss[i][j].BigValue.String())
		}
		nodesHash = append(nodesHash, _nodesHash)
		nodesVal = append(nodesVal, _nodesVal)
	}
	return nodesHash, nodesVal
}
贾浩@五瓣科技's avatar
贾浩@五瓣科技 committed
153 154 155 156 157 158 159 160 161 162 163 164

// GetWorkload /api/v1/workload
func (v *Validator) GetWorkload(timestampList []uint64) (ret []map[string]string, err error) {

	for _, timestamp := range timestampList {
		r, w, wei, err := v.rpc.GetWeiPerWorkload(timestamp)
		if err != nil {
			return nil, err
		}
		ret = append(ret, map[string]string{
			"date":           v.timestampToDate(int64(timestamp)),
			"weiPerWorkload": wei.String(),
贾浩@五瓣科技's avatar
贾浩@五瓣科技 committed
165 166
			"reward":         r.String(),
			"workload":       w.String(),
贾浩@五瓣科技's avatar
贾浩@五瓣科技 committed
167 168 169 170 171 172 173 174 175 176 177
		})
	}
	return ret, nil
}

// GetReward /api/v1/reward
func (v *Validator) GetReward(address common.Address) (reward *big.Int) {
	object := v.state.GetMinerObject(address)
	if object == nil {
		return big.NewInt(0)
	}
贾浩@五瓣科技's avatar
贾浩@五瓣科技 committed
178 179 180 181
	b, ok := big.NewInt(0).SetString(object.Balance, 10)
	if !ok {
		return big.NewInt(0)
	}
贾浩@五瓣科技's avatar
贾浩@五瓣科技 committed
182 183
	return b
}