Commit e94c6651 authored by 贾浩@五瓣科技's avatar 贾浩@五瓣科技

update

parent 5a27a0b6
FROM golang:1.19-alpine AS base
FROM golang:1.21-alpine AS base
# Set up dependencies
ENV PACKAGES git openssh-client build-base
......
......@@ -73,6 +73,7 @@ func (s *Server) PushProof(ctx context.Context, req *witnessv1.PushProofRequest)
managerHashPayload.Write(proof.ContainerSignature)
managerHashPayload.Write(proof.MinerSignature)
managerHashPayload.Write(big.NewInt(int64(proof.Workload)).Bytes())
managerHashPayload.Write(big.NewInt(int64(proof.Timestamp)).Bytes())
managerPubKey, err := crypto.SigToPub(crypto.Keccak256(managerHashPayload.Bytes()), proof.ManagerSignature)
if err != nil {
log.WithError(err).Error("failed to verify manager signature")
......
......@@ -3,10 +3,10 @@ package api
import (
"encoding/json"
"net/http"
"time"
"witness/core"
"github.com/ethereum/go-ethereum/common"
geth "github.com/ethereum/go-ethereum/mobile"
log "github.com/sirupsen/logrus"
)
......@@ -79,9 +79,9 @@ func rpcHandle(w http.ResponseWriter, r *http.Request) {
}
func getWithdrawProofs(params []byte, resp *jsonrpcMessage) {
addressList := make([]string, 0)
err := json.Unmarshal(params, &addressList)
if err != nil || len(addressList) != 1 {
paramList := make([]string, 0)
err := json.Unmarshal(params, &paramList)
if err != nil || len(paramList) < 1 || len(paramList) > 2 {
resp.Error = &jsonError{
Code: -32602,
Message: "invalid params",
......@@ -89,8 +89,7 @@ func getWithdrawProofs(params []byte, resp *jsonrpcMessage) {
return
}
_, err = geth.NewAddressFromHex(addressList[0])
if err != nil {
if !common.IsHexAddress(paramList[0]) {
resp.Error = &jsonError{
Code: -32602,
Message: "invalid params",
......@@ -98,7 +97,20 @@ func getWithdrawProofs(params []byte, resp *jsonrpcMessage) {
return
}
workload, proofs := witness.GetMerkleProof(common.HexToAddress(addressList[0]))
var date string
if len(paramList) > 1 {
_, err = time.Parse("2006-01-02", paramList[1])
if err != nil {
resp.Error = &jsonError{
Code: -32602,
Message: "invalid params",
}
return
}
date = paramList[1]
}
workload, proofs := witness.GetMerkleProof(common.HexToAddress(paramList[0]), date)
temp := map[string]interface{}{
"workload": workload,
......@@ -120,8 +132,7 @@ func getPendingWorkload(params []byte, resp *jsonrpcMessage) {
return
}
_, err = geth.NewAddressFromHex(addressList[0])
if err != nil {
if !common.IsHexAddress(addressList[0]) {
resp.Error = &jsonError{
Code: -32602,
Message: "invalid params",
......
......@@ -66,6 +66,89 @@ var (
Name: "witness-contract",
Usage: "The address of the reward contract",
}
commitTimeFlag = &cli.IntFlag{
Name: "commit-time",
Usage: "The time to commit the proof",
}
commitExpireFlag = &cli.IntFlag{
Name: "commit-expire",
Usage: "The time to expire the proof",
}
)
// p2p flags
var (
p2pUseDiscoveryFlag = &cli.BoolFlag{
Name: "p2p-use-discovery",
Usage: "Whether to use discovery",
Value: true,
}
p2pStaticPeersFlag = &cli.StringSliceFlag{
Name: "p2p-static-peers",
Usage: "Static peers",
}
p2pBootstrapNodeAddrFlag = &cli.StringSliceFlag{
Name: "p2p-bootstrap-node-addr",
Usage: "Bootstrap node address",
}
p2pLocalIPFlag = &cli.StringFlag{
Name: "p2p-local-ip",
Usage: "The local ip address to listen for incoming data.",
Value: "",
}
p2pHostFlag = &cli.StringFlag{
Name: "p2p-host-ip",
Usage: "The IP address advertised by libp2p. This may be used to advertise an external IP.",
Value: "",
}
p2pPrivKeyFlag = &cli.StringFlag{
Name: "p2p-private-key",
Usage: "The file path of the private key to use in communications with other peers.",
EnvVars: []string{"P2P_PRIVATE_KEY"},
}
p2pTCPPortFlag = &cli.IntFlag{
Name: "p2p-tcp-port",
Usage: "The port used by libp2p.",
Value: 30333,
}
p2pUDPPortFlag = &cli.IntFlag{
Name: "p2p-udp-port",
Usage: "The port used by discv5.",
Value: 30334,
}
p2pMaxPeersFlag = &cli.IntFlag{
Name: "p2p-max-peers",
Usage: "The max number of p2p peers to maintain.",
Value: 16,
}
p2pMaxInboundPeersFlag = &cli.IntFlag{
Name: "p2p-max-inbound-peers",
Usage: "The max number of inbound p2p peers to maintain.",
Value: 10,
}
p2pMaxOutboundPeersFlag = &cli.IntFlag{
Name: "p2p-max-outbound-peers",
Usage: "The max number of outbound p2p peers to maintain.",
Value: 10,
}
ignoreLocalIPFlag = &cli.BoolFlag{
Name: "ignore-local-ip",
Usage: "The node is not connected to the local IP address",
Value: false,
}
)
func loadFlagsFromConfig(cliCtx *cli.Context, flags []cli.Flag) error {
......
package main
import (
"context"
"net/http"
"os"
"witness/api"
"witness/conf"
"witness/core"
"witness/p2p"
"witness/version"
"github.com/prometheus/client_golang/prometheus/promhttp"
......@@ -25,12 +27,29 @@ var (
chainRPCFlag,
storeContractFlag,
witnessContractFlag,
commitTimeFlag,
commitExpireFlag,
}
p2pFlags = []cli.Flag{
p2pUseDiscoveryFlag,
p2pStaticPeersFlag,
p2pBootstrapNodeAddrFlag,
p2pLocalIPFlag,
p2pPrivKeyFlag,
p2pHostFlag,
p2pTCPPortFlag,
p2pUDPPortFlag,
p2pMaxPeersFlag,
p2pMaxInboundPeersFlag,
p2pMaxOutboundPeersFlag,
ignoreLocalIPFlag,
}
)
func main() {
app := cli.App{}
app.Flags = wrapFlags(appFlags)
app.Flags = wrapFlags(append(appFlags, p2pFlags...))
app.Name = "witness"
app.Usage = "this is witness"
app.Version = version.Version
......@@ -57,10 +76,13 @@ func run(ctx *cli.Context) {
StoreContract: ctx.String(storeContractFlag.Name),
WitnessContract: ctx.String(witnessContractFlag.Name),
DataDir: ctx.String(dataDirFlag.Name),
CommitTime: ctx.Int(commitTimeFlag.Name),
CommitExpire: ctx.Int(commitExpireFlag.Name),
}
p2pSrv := runP2PServer(ctx)
setLogLevel(cfg.LogLevel)
runMetrics(cfg.MetricsListenAddr)
w := core.NewWitness(cfg)
w := core.RunWitness(p2pSrv, cfg)
runGrpcServer(cfg.GRPCListenAddr, w)
runJSONRPCServer(cfg.RPCListenAddr, w)
select {}
......@@ -93,3 +115,27 @@ func runGrpcServer(listen string, w *core.Witness) {
func runJSONRPCServer(listen string, w *core.Witness) {
go api.StartJSONRPC(listen, w)
}
func runP2PServer(ctx *cli.Context) *p2p.Service {
p2pCfg := &p2p.Config{
UseDiscovery: ctx.Bool(p2pUseDiscoveryFlag.Name),
StaticPeers: ctx.StringSlice(p2pStaticPeersFlag.Name),
BootstrapNodeAddr: ctx.StringSlice(p2pBootstrapNodeAddrFlag.Name),
LocalIP: ctx.String(p2pLocalIPFlag.Name),
HostAddress: ctx.String(p2pHostFlag.Name),
PrivateKeyPath: ctx.String(p2pPrivKeyFlag.Name),
TCPPort: ctx.Uint(p2pTCPPortFlag.Name),
UDPPort: ctx.Uint(p2pUDPPortFlag.Name),
MaxPeers: ctx.Uint(p2pMaxPeersFlag.Name),
MaxInboundPeers: ctx.Uint(p2pMaxInboundPeersFlag.Name),
MaxOutboundPeers: ctx.Uint(p2pMaxOutboundPeersFlag.Name),
IgnoreLocalIP: ctx.Bool(ignoreLocalIPFlag.Name),
}
svs, err := p2p.NewService(context.Background(), p2pCfg)
if err != nil {
log.WithError(err).Fatal("failed to create p2p service")
}
svs.Start()
return svs
}
......@@ -11,4 +11,6 @@ type Config struct {
WitnessContract string
RewardContract string
DataDir string
CommitTime int
CommitExpire int
}
......@@ -6,10 +6,14 @@ grpc-listen = "0.0.0.0:20011"
rpc-listen = "0.0.0.0:20012"
chain-rpc = "https://1rpc.io/holesky"
chain-rpc = "https://ethereum-holesky-rpc.publicnode.com"
private-key = "529f4efb80ac534f17d873104c71881c0970dbd5a886f183f63c5c6bb7a1fcd9"
store-contract = "0x7Cd36Bc2a477f60A14f08442179B2f626bE026Ea"
witness-contract = "0xf49133dD7B7ed75fA0f877413D293c05Bff0D8F0"
\ No newline at end of file
witness-contract = "0xf49133dD7B7ed75fA0f877413D293c05Bff0D8F0"
commit-time = 3600 # utc + n seconds
commit-expire = 3600
\ No newline at end of file
......@@ -3,6 +3,7 @@ package core
import (
"context"
"crypto/ecdsa"
"errors"
"fmt"
"math/big"
"time"
......@@ -75,6 +76,11 @@ func (r *ChainRPC) GetNMAddresses() (addrs []common.Address, err error) {
return r.storageContract.GetNmAddresses(nil)
}
func (r *ChainRPC) GetWorkloadThreshold(totalWorkload uint64) (threshold *big.Int, err error) {
// return r.storageContract.GetWorkloadPercent(nil)
return big.NewInt(1), nil
}
func (r *ChainRPC) SubmitProofs(date string, merkleSumTreeRoot, merkleTreeRoot common.Hash) (txHash common.Hash, err error) {
ctx, cancel := context.WithTimeout(context.Background(), time.Minute)
defer cancel()
......@@ -83,21 +89,22 @@ func (r *ChainRPC) SubmitProofs(date string, merkleSumTreeRoot, merkleTreeRoot c
return
}
opts.Context = ctx
signedTx, err := r.witnessContract.SubmitMerkleRoot(opts, date, merkleSumTreeRoot, merkleTreeRoot)
if err != nil {
return
}
receipt, err := r.WaitForReceipt(ctx, signedTx.Hash())
if err != nil {
return
}
if receipt.Status != types.ReceiptStatusSuccessful {
return common.Hash{}, fmt.Errorf("tx %s failed", signedTx.Hash().Hex())
for i := 0; i < 3; i++ {
signedTx, err := r.witnessContract.SubmitMerkleRoot(opts, date, merkleSumTreeRoot, merkleTreeRoot)
if err != nil {
time.Sleep(time.Second * 3)
continue
}
receipt, err := r.WaitForReceipt(ctx, signedTx.Hash())
if err != nil {
return common.Hash{}, err
}
if receipt.Status != types.ReceiptStatusSuccessful {
return common.Hash{}, fmt.Errorf("tx %s failed", signedTx.Hash().Hex())
}
return signedTx.Hash(), nil
}
return signedTx.Hash(), nil
return common.Hash{}, errors.New("failed to submit proofs, max retry")
}
func (r *ChainRPC) WaitForReceipt(ctx context.Context, txHash common.Hash) (receipt *types.Receipt, err error) {
......
......@@ -2,8 +2,11 @@ package core
import (
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core/rawdb"
"github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum/go-ethereum/ethdb"
"github.com/ethereum/go-ethereum/trie"
"github.com/ethereum/go-ethereum/trie/trienode"
"github.com/gogo/protobuf/proto"
witnessv1 "github.com/odysseus/odysseus-protocol/gen/proto/go/witness/v1"
log "github.com/sirupsen/logrus"
......@@ -14,13 +17,15 @@ type StateDB struct {
trie *trie.Trie
}
func NewStateDB(db *trie.Database, root common.Hash) (statedb *StateDB, err error) {
t, err := trie.New(common.Hash{}, root, db)
func NewStateDB(lvdb ethdb.KeyValueStore, root common.Hash) (statedb *StateDB, err error) {
trieDB := trie.NewDatabase(rawdb.NewDatabase(lvdb), nil)
// owner 如果是0x0,启用的是用户树,此处并没有使用 stateaccount
t, err := trie.New(trieID(root), trieDB)
if err != nil {
return nil, err
}
return &StateDB{
db: db,
db: trieDB,
trie: t,
}, nil
}
......@@ -28,7 +33,7 @@ func NewStateDB(db *trie.Database, root common.Hash) (statedb *StateDB, err erro
func (s *StateDB) GetMinerObject(miner common.Address) (object *witnessv1.MinerObject) {
object = &witnessv1.MinerObject{}
k := crypto.Keccak256(miner.Bytes())
v, err := s.trie.TryGet(k)
v, err := s.trie.Get(k)
if err != nil {
return nil
}
......@@ -46,7 +51,7 @@ func (s *StateDB) UpdateMinerObject(miner common.Address, object *witnessv1.Mine
return
}
err = s.trie.TryUpdate(k, v)
err = s.trie.Update(k, v)
return
}
......@@ -55,24 +60,28 @@ func (s *StateDB) Commit() (root common.Hash, err error) {
if err != nil {
return
}
nodesSet := trie.NewMergedNodeSet()
nodesSet := trienode.NewMergedNodeSet()
if nodes != nil {
err = nodesSet.Merge(nodes)
if err != nil {
return
}
}
err = s.db.Update(nodesSet)
// block states 在 hashtrie 中未使用
err = s.db.Update(root, common.Hash{}, 0, nodesSet, nil)
if err != nil {
return
}
err = s.db.Commit(root, true, nil)
err = s.db.Commit(root, true)
return root, err
}
func (s *StateDB) IterAllObject() (objects []*witnessv1.MinerObject) {
iter := s.trie.NodeIterator(nil)
iter, err := s.trie.NodeIterator(nil)
if err != nil {
return
}
for iter.Next(true) {
if !iter.Leaf() {
continue
......@@ -83,8 +92,16 @@ func (s *StateDB) IterAllObject() (objects []*witnessv1.MinerObject) {
if err != nil {
continue
}
log.WithField("workload", object.Workload).Debug("miner object")
log.WithField("balance", object.Balance).Debug("miner object")
objects = append(objects, object)
}
return
}
func trieID(root common.Hash) (id *trie.ID) {
return &trie.ID{
StateRoot: root,
Owner: common.HexToHash("0x1"),
Root: root,
}
}
package core
import (
pubsub "github.com/libp2p/go-libp2p-pubsub"
)
var (
msgTopic *pubsub.Topic
)
func (w *Witness) JoinTopic(topic string) (err error) {
msgTopic, err = w.p2pSrv.JoinTopic("topic")
return err
}
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
......@@ -17,6 +17,4 @@ type Config struct {
MaxOutboundPeers uint
IgnoreLocalIP bool
SingleNode bool
EnableProm bool
NebulaGrpcAddress string
}
package p2p
import (
"context"
"runtime"
"github.com/libp2p/go-libp2p/core/control"
......@@ -60,3 +61,18 @@ func (s *Service) validateDial(addr multiaddr.Multiaddr) bool {
_, err := manet.ToIP(addr)
return err == nil
}
func onConnectSuccess(ctx context.Context, peerID peer.ID) error {
log.WithField("peerID", peerID).Info("on connect success")
return nil
}
func onConnectFail(ctx context.Context, peerID peer.ID) error {
log.WithField("peerID", peerID).Info("on connect fail")
return nil
}
func onDisconnect(ctx context.Context, peerID peer.ID) error {
log.WithField("peerID", peerID).Info("on disconnect")
return nil
}
......@@ -22,7 +22,7 @@ func logIPAddr(id peer.ID, addrs ...ma.Multiaddr) {
log.WithField(
"multiAddr",
correctAddr.String()+"/p2p/"+id.String(),
).Info("Node started p2p server")
).Info("p2p node started")
}
}
......
......@@ -13,18 +13,17 @@ import (
"witness/p2p/peers"
"github.com/libp2p/go-libp2p"
"github.com/multiformats/go-multiaddr"
"github.com/prysmaticlabs/prysm/v3/async/event"
"github.com/ethereum/go-ethereum/p2p/enode"
"github.com/ethereum/go-ethereum/p2p/enr"
"github.com/libp2p/go-libp2p"
pubsub "github.com/libp2p/go-libp2p-pubsub"
"github.com/libp2p/go-libp2p/core/host"
"github.com/libp2p/go-libp2p/core/network"
"github.com/libp2p/go-libp2p/core/peer"
"github.com/libp2p/go-libp2p/core/protocol"
"github.com/multiformats/go-multiaddr"
"github.com/pkg/errors"
"github.com/prysmaticlabs/prysm/v3/async/event"
prysmnetwork "github.com/prysmaticlabs/prysm/v3/network"
)
......@@ -133,6 +132,17 @@ func NewService(ctx context.Context, cfg *Config) (*Service, error) {
return s, nil
}
func (s *Service) StartP2PNode(cfg *Config) (err error) {
srv, err := NewService(context.Background(), cfg)
if err != nil {
return err
}
srv.AddConnectionHandler(onConnectSuccess, onConnectFail)
srv.AddDisconnectionHandler(onDisconnect)
srv.Start()
return nil
}
// Start the p2p service.
func (s *Service) Start() {
if s.started {
......
......@@ -26,4 +26,11 @@ state:
lastday -> 2023-01-01
sroot:2020-01-01 -> root
sroot:2020-01-01 -> root(32bytes)
txid:2020-0101 -> txhash(32bytes)
unconfirmed proof:
proof:2020-01-01 -> json(map[common.Address]*witnessv1.ValidatedProof)
\ No newline at end of file
package util
import (
"math/big"
)
func MustStringToBigInt(v string) *big.Int {
if len(v) == 0 {
return big.NewInt(0)
}
b, _ := big.NewInt(0).SetString(v, 10)
return b
}
func MustAddStringToBigInt(v1, v2 string) *big.Int {
b1 := MustStringToBigInt(v1)
b2 := MustStringToBigInt(v2)
return new(big.Int).Add(b1, b2)
}
func MustSubStringToBigInt(v1, v2 string) *big.Int {
b1 := MustStringToBigInt(v1)
b2 := MustStringToBigInt(v2)
return new(big.Int).Sub(b1, b2)
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment