From 6d6189d1adaa06361c4a2bb94898956ef439fa81 Mon Sep 17 00:00:00 2001 From: Cassandra Heart Date: Mon, 28 Oct 2024 19:44:22 -0500 Subject: [PATCH] v2.0.2.3 --- client/cmd/all.go | 306 +++++++++++++++++++++++++---------------- client/cmd/balance.go | 42 +++++- client/cmd/coins.go | 39 ++++++ node/config/version.go | 2 +- node/main.go | 2 +- node/p2p/blossomsub.go | 74 ++++++++++ 6 files changed, 344 insertions(+), 121 deletions(-) diff --git a/client/cmd/all.go b/client/cmd/all.go index 2aaf069..1a67b57 100644 --- a/client/cmd/all.go +++ b/client/cmd/all.go @@ -6,13 +6,19 @@ import ( "encoding/binary" "fmt" "os" - - gotime "time" + "strings" + "time" "github.com/iden3/go-iden3-crypto/poseidon" + "github.com/libp2p/go-libp2p/core/crypto" + "github.com/libp2p/go-libp2p/core/peer" + "github.com/pkg/errors" "github.com/spf13/cobra" "go.uber.org/zap" - "source.quilibrium.com/quilibrium/monorepo/node/execution/intrinsics/token" + "google.golang.org/grpc" + "source.quilibrium.com/quilibrium/monorepo/node/config" + "source.quilibrium.com/quilibrium/monorepo/node/execution/intrinsics/token/application" + "source.quilibrium.com/quilibrium/monorepo/node/p2p" "source.quilibrium.com/quilibrium/monorepo/node/protobufs" "source.quilibrium.com/quilibrium/monorepo/node/store" ) @@ -27,12 +33,6 @@ var allCmd = &cobra.Command{ os.Exit(1) } - conn, err := GetGRPCClient() - if err != nil { - panic(err) - } - defer conn.Close() - if !LightNode { fmt.Println( "mint all cannot be run unless node is not running. ensure your node " + @@ -41,8 +41,6 @@ var allCmd = &cobra.Command{ os.Exit(1) } - client := protobufs.NewNodeServiceClient(conn) - db := store.NewPebbleDB(NodeConfig.DB) logger, _ := zap.NewProduction() dataProofStore := store.NewPebbleDataProofStore(db, logger) @@ -57,137 +55,213 @@ var allCmd = &cobra.Command{ panic(err) } + pubSub := p2p.NewBlossomSub(NodeConfig.P2P, logger) + logger.Info("connecting to network") + time.Sleep(5 * time.Second) + increment, _, _, err := dataProofStore.GetLatestDataTimeProof( []byte(peerId), ) + if err != nil { + if errors.Is(err, store.ErrNotFound) { + logger.Info("could not find pre-2.0 proofs") + return + } - addr, err := poseidon.HashBytes([]byte(peerId)) + panic(err) + } + + addrBI, err := poseidon.HashBytes([]byte(peerId)) if err != nil { panic(err) } + addr := addrBI.FillBytes(make([]byte, 32)) + + genesis := config.GetGenesis() + bpub, err := crypto.UnmarshalEd448PublicKey(genesis.Beacon) if err != nil { panic(err) } - resp, err := client.GetPreCoinProofsByAccount( - context.Background(), - &protobufs.GetPreCoinProofsByAccountRequest{ - Address: addr.FillBytes(make([]byte, 32)), - }, - ) + bpeerId, err := peer.IDFromPublicKey(bpub) if err != nil { - panic(err) + panic(errors.Wrap(err, "error getting peer id")) } resume := make([]byte, 32) - for _, pr := range resp.Proofs { - if pr.IndexProof != nil { - resume, err = token.GetAddressOfPreCoinProof(pr) - if err != nil { - panic(err) - } - increment = pr.Difficulty - 1 - } - } - - if increment == 0 && !bytes.Equal(resume, make([]byte, 32)) { - fmt.Println("already completed pre-midnight mint") - return - } - - proofs := [][]byte{ - []byte("pre-dusk"), - resume, - } - - batchCount := 0 - for i := int(increment); i >= 0; i-- { - _, parallelism, input, output, err := dataProofStore.GetDataTimeProof( - []byte(peerId), - uint32(i), + cc, err := pubSub.GetDirectChannel([]byte(bpeerId), "worker") + if err != nil { + logger.Info( + "could not establish direct channel, waiting...", + zap.Error(err), ) - if err == nil { - p := []byte{} - p = binary.BigEndian.AppendUint32(p, uint32(i)) - p = binary.BigEndian.AppendUint32(p, parallelism) - p = binary.BigEndian.AppendUint64(p, uint64(len(input))) - p = append(p, input...) - p = binary.BigEndian.AppendUint64(p, uint64(len(output))) - p = append(p, output...) - - proofs = append(proofs, p) - } else { - fmt.Println("could not find data time proof for peer and increment, stopping at increment", i) - panic(err) + time.Sleep(10 * time.Second) + } + for { + if cc == nil { + cc, err = pubSub.GetDirectChannel([]byte(bpeerId), "worker") + if err != nil { + logger.Info( + "could not establish direct channel, waiting...", + zap.Error(err), + ) + cc = nil + time.Sleep(10 * time.Second) + continue + } } - batchCount++ - if batchCount == 200 || i == 0 { - fmt.Println("publishing proof batch, increment", i) - payload := []byte("mint") - for _, i := range proofs { - payload = append(payload, i...) - } - sig, err := privKey.Sign(payload) - if err != nil { - panic(err) + client := protobufs.NewDataServiceClient(cc) + + if bytes.Equal(resume, make([]byte, 32)) { + status, err := client.GetPreMidnightMintStatus( + context.Background(), + &protobufs.PreMidnightMintStatusRequest{ + Owner: addr, + }, + grpc.MaxCallSendMsgSize(1*1024*1024), + grpc.MaxCallRecvMsgSize(1*1024*1024), + ) + if err != nil || status == nil { + logger.Error( + "got error response, waiting...", + zap.Error(err), + ) + time.Sleep(10 * time.Second) + cc.Close() + cc = nil + err = pubSub.Reconnect([]byte(peerId)) + if err != nil { + logger.Error( + "got error response, waiting...", + zap.Error(err), + ) + time.Sleep(10 * time.Second) + } + continue } - _, err = client.SendMessage( - context.Background(), - &protobufs.TokenRequest{ - Request: &protobufs.TokenRequest_Mint{ - Mint: &protobufs.MintCoinRequest{ - Proofs: proofs, - Signature: &protobufs.Ed448Signature{ - PublicKey: &protobufs.Ed448PublicKey{ - KeyValue: pub, - }, - Signature: sig, + resume = status.Address + + if status.Increment != 0 { + increment = status.Increment - 1 + } else if !bytes.Equal(status.Address, make([]byte, 32)) { + increment = 0 + } + } + + proofs := [][]byte{ + []byte("pre-dusk"), + resume, + } + + batchCount := 0 + // the cast is important, it underflows without: + for i := int(increment); i >= 0; i-- { + _, parallelism, input, output, err := dataProofStore.GetDataTimeProof( + []byte(peerId), + uint32(i), + ) + if err == nil { + p := []byte{} + p = binary.BigEndian.AppendUint32(p, uint32(i)) + p = binary.BigEndian.AppendUint32(p, parallelism) + p = binary.BigEndian.AppendUint64(p, uint64(len(input))) + p = append(p, input...) + p = binary.BigEndian.AppendUint64(p, uint64(len(output))) + p = append(p, output...) + + proofs = append(proofs, p) + } else { + logger.Error( + "could not find data time proof for peer and increment, stopping worker", + zap.String("peer_id", peerId.String()), + zap.Int("increment", i), + ) + cc.Close() + cc = nil + return + } + + batchCount++ + if batchCount == 200 || i == 0 { + logger.Info("publishing proof batch", zap.Int("increment", i)) + + payload := []byte("mint") + for _, i := range proofs { + payload = append(payload, i...) + } + sig, err := pubSub.SignMessage(payload) + if err != nil { + cc.Close() + panic(err) + } + + resp, err := client.HandlePreMidnightMint( + context.Background(), + &protobufs.MintCoinRequest{ + Proofs: proofs, + Signature: &protobufs.Ed448Signature{ + PublicKey: &protobufs.Ed448PublicKey{ + KeyValue: pub, }, + Signature: sig, }, }, - }, - ) - if err != nil { - panic(err) - } - - waitForConf: - for { - gotime.Sleep(20 * gotime.Second) - resp, err := client.GetPreCoinProofsByAccount( - context.Background(), - &protobufs.GetPreCoinProofsByAccountRequest{ - Address: addr.FillBytes(make([]byte, 32)), - }, + grpc.MaxCallSendMsgSize(1*1024*1024), + grpc.MaxCallRecvMsgSize(1*1024*1024), ) - if err != nil { - for _, pr := range resp.Proofs { - if pr.IndexProof != nil { - newResume, err := token.GetAddressOfPreCoinProof(pr) - if err != nil { - panic(err) - } - if bytes.Equal(newResume, resume) { - fmt.Println("waiting for confirmation...") - continue waitForConf - } - } - } - } - break - } - batchCount = 0 - proofs = [][]byte{ - []byte("pre-dusk"), - resume, - } - if i == 0 { - fmt.Println("all proofs submitted, returning") - return + if err != nil { + if strings.Contains( + err.Error(), + application.ErrInvalidStateTransition.Error(), + ) && i == 0 { + resume = make([]byte, 32) + logger.Info("pre-midnight proofs submitted, returning") + cc.Close() + cc = nil + return + } + + logger.Error( + "got error response, waiting...", + zap.Error(err), + ) + + resume = make([]byte, 32) + cc.Close() + cc = nil + time.Sleep(10 * time.Second) + err = pubSub.Reconnect([]byte(peerId)) + if err != nil { + logger.Error( + "got error response, waiting...", + zap.Error(err), + ) + time.Sleep(10 * time.Second) + } + break + } + + resume = resp.Address + batchCount = 0 + proofs = [][]byte{ + []byte("pre-dusk"), + resume, + } + + if i == 0 { + logger.Info("pre-midnight proofs submitted, returning") + cc.Close() + cc = nil + return + } else { + increment = uint32(i) - 1 + } + + break } } } diff --git a/client/cmd/balance.go b/client/cmd/balance.go index 2eb0975..ab1fc57 100644 --- a/client/cmd/balance.go +++ b/client/cmd/balance.go @@ -22,6 +22,16 @@ var balanceCmd = &cobra.Command{ client := protobufs.NewNodeServiceClient(conn) peerId := GetPeerIDFromConfig(NodeConfig) + privKey, err := GetPrivKeyFromConfig(NodeConfig) + if err != nil { + panic(err) + } + + pub, err := privKey.GetPublic().Raw() + if err != nil { + panic(err) + } + addr, err := poseidon.HashBytes([]byte(peerId)) if err != nil { panic(err) @@ -38,16 +48,42 @@ var balanceCmd = &cobra.Command{ panic(err) } - if info.OwnedTokens == nil { - panic("invalid response from RPC") - } tokens := new(big.Int).SetBytes(info.OwnedTokens) conversionFactor, _ := new(big.Int).SetString("1DCD65000", 16) r := new(big.Rat).SetFrac(tokens, conversionFactor) + + altAddr, err := poseidon.HashBytes([]byte(pub)) + if err != nil { + panic(err) + } + + altAddrBytes := altAddr.FillBytes(make([]byte, 32)) + info, err = client.GetTokenInfo( + context.Background(), + &protobufs.GetTokenInfoRequest{ + Address: altAddrBytes, + }, + ) + if err != nil { + panic(err) + } + + if info.OwnedTokens == nil { + panic("invalid response from RPC") + } + + tokens = new(big.Int).SetBytes(info.OwnedTokens) + r2 := new(big.Rat).SetFrac(tokens, conversionFactor) fmt.Println("Total balance:", r.FloatString(12), fmt.Sprintf( "QUIL (Account 0x%x)", addrBytes, )) + if r2.Cmp(big.NewRat(0, 1)) != 0 { + fmt.Println("Total balance:", r2.FloatString(12), fmt.Sprintf( + "QUIL (Account 0x%x)", + altAddrBytes, + )) + } }, } diff --git a/client/cmd/coins.go b/client/cmd/coins.go index 019a6b2..5e85a49 100644 --- a/client/cmd/coins.go +++ b/client/cmd/coins.go @@ -22,6 +22,16 @@ var coinsCmd = &cobra.Command{ client := protobufs.NewNodeServiceClient(conn) peerId := GetPeerIDFromConfig(NodeConfig) + privKey, err := GetPrivKeyFromConfig(NodeConfig) + if err != nil { + panic(err) + } + + pub, err := privKey.GetPublic().Raw() + if err != nil { + panic(err) + } + addr, err := poseidon.HashBytes([]byte(peerId)) if err != nil { panic(err) @@ -42,6 +52,26 @@ var coinsCmd = &cobra.Command{ panic("invalid response from RPC") } + altAddr, err := poseidon.HashBytes([]byte(pub)) + if err != nil { + panic(err) + } + + altAddrBytes := altAddr.FillBytes(make([]byte, 32)) + resp2, err := client.GetTokensByAccount( + context.Background(), + &protobufs.GetTokensByAccountRequest{ + Address: altAddrBytes, + }, + ) + if err != nil { + panic(err) + } + + if len(resp.Coins) != len(resp.FrameNumbers) { + panic("invalid response from RPC") + } + for i, coin := range resp.Coins { amount := new(big.Int).SetBytes(coin.Amount) conversionFactor, _ := new(big.Int).SetString("1DCD65000", 16) @@ -51,6 +81,15 @@ var coinsCmd = &cobra.Command{ fmt.Sprintf("QUIL (Coin 0x%x)", resp.Addresses[i]), ) } + for i, coin := range resp2.Coins { + amount := new(big.Int).SetBytes(coin.Amount) + conversionFactor, _ := new(big.Int).SetString("1DCD65000", 16) + r := new(big.Rat).SetFrac(amount, conversionFactor) + fmt.Println( + r.FloatString(12), + fmt.Sprintf("QUIL (Coin 0x%x)", resp.Addresses[i]), + ) + } }, } diff --git a/node/config/version.go b/node/config/version.go index b35e55d..7b93698 100644 --- a/node/config/version.go +++ b/node/config/version.go @@ -36,7 +36,7 @@ func FormatVersion(version []byte) string { } func GetPatchNumber() byte { - return 0x02 + return 0x03 } func GetRCNumber() byte { diff --git a/node/main.go b/node/main.go index b28f2b2..c330c67 100644 --- a/node/main.go +++ b/node/main.go @@ -429,7 +429,7 @@ func main() { return } - runtime.GOMAXPROCS(1) + // runtime.GOMAXPROCS(1) if nodeConfig.ListenGRPCMultiaddr != "" { srv, err := rpc.NewRPCServer( diff --git a/node/p2p/blossomsub.go b/node/p2p/blossomsub.go index ed1f1e3..507a945 100644 --- a/node/p2p/blossomsub.go +++ b/node/p2p/blossomsub.go @@ -92,6 +92,80 @@ func getPeerID(p2pConfig *config.P2PConfig) peer.ID { return id } +func NewBlossomSubStreamer( + p2pConfig *config.P2PConfig, + logger *zap.Logger, +) *BlossomSub { + ctx := context.Background() + + opts := []libp2pconfig.Option{ + libp2p.ListenAddrStrings(p2pConfig.ListenMultiaddr), + } + + bootstrappers := []peer.AddrInfo{} + + peerinfo, err := peer.AddrInfoFromString("/ip4/185.209.178.191/udp/8336/quic-v1/p2p/QmcKQjpQmLpbDsiif2MuakhHFyxWvqYauPsJDaXnLav7PJ") + if err != nil { + panic(err) + } + + bootstrappers = append(bootstrappers, *peerinfo) + + var privKey crypto.PrivKey + if p2pConfig.PeerPrivKey != "" { + peerPrivKey, err := hex.DecodeString(p2pConfig.PeerPrivKey) + if err != nil { + panic(errors.Wrap(err, "error unmarshaling peerkey")) + } + + privKey, err = crypto.UnmarshalEd448PrivateKey(peerPrivKey) + if err != nil { + panic(errors.Wrap(err, "error unmarshaling peerkey")) + } + + opts = append(opts, libp2p.Identity(privKey)) + } + + bs := &BlossomSub{ + ctx: ctx, + logger: logger, + bitmaskMap: make(map[string]*blossomsub.Bitmask), + signKey: privKey, + peerScore: make(map[string]int64), + isBootstrapPeer: false, + network: p2pConfig.Network, + } + + h, err := libp2p.New(opts...) + if err != nil { + panic(errors.Wrap(err, "error constructing p2p")) + } + + logger.Info("established peer id", zap.String("peer_id", h.ID().String())) + + kademliaDHT := initDHT( + ctx, + p2pConfig, + logger, + h, + false, + bootstrappers, + ) + routingDiscovery := routing.NewRoutingDiscovery(kademliaDHT) + util.Advertise(ctx, routingDiscovery, getNetworkNamespace(p2pConfig.Network)) + + if err != nil { + panic(err) + } + + peerID := h.ID() + bs.peerID = peerID + bs.h = h + bs.signKey = privKey + + return bs +} + func NewBlossomSub( p2pConfig *config.P2PConfig, logger *zap.Logger,