From 1a77d688b4ca4f2617d9419450cf12aa4421b191 Mon Sep 17 00:00:00 2001 From: Maneesha-rubix Date: Fri, 5 Jan 2024 12:31:09 +0530 Subject: [PATCH 01/62] Created Light mode for PKI based signature --- client/did.go | 14 +++++- command/did.go | 36 +++++++++++++++ core/core.go | 2 + core/did.go | 2 +- did/did.go | 20 +++++++++ did/light.go | 107 ++++++++++++++++++++++++++++++++++++++++++++ did/model.go | 3 +- grpcclient/token.go | 2 + 8 files changed, 183 insertions(+), 3 deletions(-) create mode 100644 did/light.go diff --git a/client/did.go b/client/did.go index 1522c7ab..8dc12e5f 100644 --- a/client/did.go +++ b/client/did.go @@ -52,6 +52,14 @@ func (c *Client) CreateDID(cfg *did.DIDCreate) (string, bool) { return "Invalid DID mode", false } switch cfg.Type { + case did.LightDIDMode: + if !strings.Contains(cfg.PubKeyFile, did.PubKeyFileName) { + util.Filecopy(cfg.PubKeyFile, did.PubKeyFileName) + cfg.PubKeyFile = did.PubKeyFileName + } + cfg.ImgFile = "" + cfg.DIDImgFileName = "" + cfg.PubImgFile = "" case did.BasicDIDMode: if cfg.ImgFile == "" { c.log.Error("Image file requried") @@ -150,7 +158,7 @@ func (c *Client) CreateDID(cfg *did.DIDCreate) (string, bool) { } func (c *Client) SetupDID(dc *did.DIDCreate) (string, bool) { - if dc.Type < did.BasicDIDMode && dc.Type > did.WalletDIDMode { + if dc.Type < did.LightDIDMode && dc.Type > did.WalletDIDMode { return "Invalid DID mode", false } if !strings.Contains(dc.PubImgFile, did.PubShareFileName) || @@ -161,6 +169,10 @@ func (c *Client) SetupDID(dc *did.DIDCreate) (string, bool) { return "Required files are missing", false } switch dc.Type { + case did.LightDIDMode: + if !strings.Contains(dc.PrivKeyFile, did.PvtKeyFileName) { + return "Required files are missing", false + } case did.BasicDIDMode: if !strings.Contains(dc.PrivImgFile, did.PvtShareFileName) || !strings.Contains(dc.PrivKeyFile, did.PvtKeyFileName) { diff --git a/command/did.go b/command/did.go index 64b7cc79..13e489a5 100644 --- a/command/did.go +++ b/command/did.go @@ -50,6 +50,27 @@ func (cmd *Command) CreateDID() { } cmd.quorumPWD = pwd } + if cmd.didType == did.LightDIDMode { + if cmd.privKeyFile == "" || cmd.pubKeyFile == "" { + cmd.log.Error("private key & public key file names required") + return + } + pvtKey, pubKey, err := crypto.GenerateKeyPair(&crypto.CryptoConfig{Alg: crypto.ECDSAP256, Pwd: cmd.privPWD}) + if err != nil { + cmd.log.Error("failed to create keypair", "err", err) + return + } + err = util.FileWrite(cmd.privKeyFile, pvtKey) + if err != nil { + cmd.log.Error("failed to write private key file", "err", err) + return + } + err = util.FileWrite(cmd.pubKeyFile, pubKey) + if err != nil { + cmd.log.Error("failed to write public key file", "err", err) + return + } + } if cmd.didType == did.WalletDIDMode { f, err := os.Open(cmd.imgFile) if err != nil { @@ -248,6 +269,21 @@ func (cmd *Command) SignatureResponse(br *model.BasicResponse, timeout ...time.D Mode: sr.Mode, } switch sr.Mode { + case did.LightDIDMode: + privKey, err := ioutil.ReadFile(cmd.privKeyFile) + if err != nil { + return "Failed to open private key file, " + err.Error(), false + } + key, _, err := crypto.DecodeKeyPair(password, privKey, nil) + if err != nil { + return "Failed to decode private key file, " + err.Error(), false + } + cmd.log.Info("Doing the private key signature") + sig, err := crypto.Sign(key, sr.Hash) + if err != nil { + return "Failed to do signature, " + err.Error(), false + } + sresp.Signature.Signature = sig case did.BasicDIDMode: sresp.Password = password case did.StandardDIDMode: diff --git a/core/core.go b/core/core.go index 2ebf9b9f..8ee62b4f 100644 --- a/core/core.go +++ b/core/core.go @@ -504,6 +504,8 @@ func (c *Core) SetupDID(reqID string, didStr string) (did.DIDCrypto, error) { return nil, fmt.Errorf("faield to get did channel") } switch dt.Type { + case did.LightDIDMode: + return did.InitDIDLight(didStr, c.didDir, dc), nil case did.BasicDIDMode: return did.InitDIDBasic(didStr, c.didDir, dc), nil case did.StandardDIDMode: diff --git a/core/did.go b/core/did.go index 3adacdb3..cdca8618 100644 --- a/core/did.go +++ b/core/did.go @@ -36,7 +36,7 @@ func (c *Core) GetDIDAccess(req *model.GetDIDAccess) *model.DIDAccessResponse { resp.Message = "Invalid token" return resp } - dc := did.InitDIDBasic(req.DID, c.didDir, nil) + dc := did.InitDIDLight(req.DID, c.didDir, nil) ok, err := dc.PvtVerify([]byte(req.Token), req.Signature) if err != nil { c.log.Error("Failed to verify DID signature", "err", err) diff --git a/did/did.go b/did/did.go index 432dd889..ba86d4db 100644 --- a/did/did.go +++ b/did/did.go @@ -69,6 +69,26 @@ func (d *DID) CreateDID(didCreate *DIDCreate) (string, error) { return "", err } + if didCreate.Type == LightDIDMode { + if didCreate.PrivPWD == "" { + d.log.Error("password required for creating", "err", err) + return "", err + } + pvtKey, pubKey, err := crypto.GenerateKeyPair(&crypto.CryptoConfig{Alg: crypto.ECDSAP256, Pwd: didCreate.PrivPWD}) + if err != nil { + d.log.Error("failed to create keypair", "err", err) + return "", err + } + err = util.FileWrite(dirName+"/private/"+PvtKeyFileName, pvtKey) + if err != nil { + return "", err + } + err = util.FileWrite(dirName+"/public/"+PubKeyFileName, pubKey) + if err != nil { + return "", err + } + } + if didCreate.Type == BasicDIDMode || didCreate.Type == StandardDIDMode { f, err := os.Open(didCreate.ImgFile) if err != nil { diff --git a/did/light.go b/did/light.go new file mode 100644 index 00000000..92388729 --- /dev/null +++ b/did/light.go @@ -0,0 +1,107 @@ +package did + +import ( + // "bytes" + "fmt" + "io/ioutil" + "time" + + "github.com/rubixchain/rubixgoplatform/crypto" + "github.com/rubixchain/rubixgoplatform/util" +) + +// DIDLight will handle Light DID +type DIDLight struct { + did string + dir string + ch *DIDChan + pwd string +} + +// InitDIDLight will return the Light did handle +func InitDIDLight(did string, baseDir string, ch *DIDChan) *DIDLight { + return &DIDLight{did: did, dir: util.SanitizeDirPath(baseDir) + did + "/", ch: ch} +} + +func InitDIDLightWithPassword(did string, baseDir string, pwd string) *DIDLight { + return &DIDLight{did: did, dir: util.SanitizeDirPath(baseDir) + did + "/", pwd: pwd} +} + +func (d *DIDLight) getPassword() (string, error) { + if d.pwd != "" { + return d.pwd, nil + } + if d.ch == nil || d.ch.InChan == nil || d.ch.OutChan == nil { + return "", fmt.Errorf("Invalid configuration") + } + sr := &SignResponse{ + Status: true, + Message: "Password needed", + Result: SignReqData{ + ID: d.ch.ID, + Mode: LightDIDMode, + }, + } + d.ch.OutChan <- sr + var ch interface{} + select { + case ch = <-d.ch.InChan: + case <-time.After(d.ch.Timeout): + return "", fmt.Errorf("Timeout, failed to get password") + } + + srd, ok := ch.(SignRespData) + if !ok { + return "", fmt.Errorf("Invalid data received on the channel") + } + d.pwd = srd.Password + return d.pwd, nil +} + +func (d *DIDLight) GetDID() string { + return d.did +} + +func (d *DIDLight) Sign(hash string) ([]byte, []byte, error) { + pvtKeySign, err := d.PvtSign([]byte(hash)) + bs := []byte{} + + return bs, pvtKeySign, err +} +func (d *DIDLight) PvtSign(hash []byte) ([]byte, error) { + privKey, err := ioutil.ReadFile(d.dir + PvtKeyFileName) + if err != nil { + return nil, err + } + pwd, err := d.getPassword() + if err != nil { + return nil, err + } + PrivateKey, _, err := crypto.DecodeKeyPair(pwd, privKey, nil) + if err != nil { + return nil, err + } + pvtKeySign, err := crypto.Sign(PrivateKey, hash) + if err != nil { + return nil, err + } + return pvtKeySign, nil +} + +func (d *DIDLight) Verify(hash string, pvtShareSig []byte, pvtKeySIg []byte) (bool, error) { + return d.PvtVerify([]byte(hash), pvtKeySIg) +} +func (d *DIDLight) PvtVerify(hash []byte, sign []byte) (bool, error) { + pubKey, err := ioutil.ReadFile(d.dir + PubKeyFileName) + if err != nil { + return false, err + } + _, pubKeyByte, err := crypto.DecodeKeyPair("", nil, pubKey) + if err != nil { + return false, err + } + if !crypto.Verify(pubKeyByte, hash, sign) { + return false, fmt.Errorf("failed to verify private key singature") + } + return true, nil +} diff --git a/did/model.go b/did/model.go index 1ff71eb0..49aef460 100644 --- a/did/model.go +++ b/did/model.go @@ -1,7 +1,8 @@ package did const ( - BasicDIDMode int = iota + LightDIDMode int = iota + BasicDIDMode StandardDIDMode WalletDIDMode ChildDIDMode diff --git a/grpcclient/token.go b/grpcclient/token.go index 37c29126..19dfbcee 100644 --- a/grpcclient/token.go +++ b/grpcclient/token.go @@ -34,6 +34,8 @@ func (cmd *Command) GenerateRBT() { Mode: br.SignRequest.Mode, } switch int(br.SignRequest.Mode) { + case did.LightDIDMode: + resp.Password = cmd.privPWD case did.BasicDIDMode: resp.Password = cmd.privPWD case did.ChildDIDMode: From ec109915d2b6c5e3550c8f22d29e60d05559adf4 Mon Sep 17 00:00:00 2001 From: Maneesha-rubix Date: Fri, 5 Jan 2024 14:00:47 +0530 Subject: [PATCH 02/62] did created successfully --- client/did.go | 2 +- did/did.go | 6 ++++++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/client/did.go b/client/did.go index 8dc12e5f..64dd6a32 100644 --- a/client/did.go +++ b/client/did.go @@ -48,7 +48,7 @@ func (c *Client) GetAllDIDs() (*model.GetAccountInfo, error) { } func (c *Client) CreateDID(cfg *did.DIDCreate) (string, bool) { - if cfg.Type < did.BasicDIDMode && cfg.Type > did.WalletDIDMode { + if cfg.Type < did.LightDIDMode && cfg.Type > did.WalletDIDMode { return "Invalid DID mode", false } switch cfg.Type { diff --git a/did/did.go b/did/did.go index ba86d4db..c10e7936 100644 --- a/did/did.go +++ b/did/did.go @@ -79,14 +79,17 @@ func (d *DID) CreateDID(didCreate *DIDCreate) (string, error) { d.log.Error("failed to create keypair", "err", err) return "", err } + err = util.FileWrite(dirName+"/private/"+PvtKeyFileName, pvtKey) if err != nil { return "", err } + err = util.FileWrite(dirName+"/public/"+PubKeyFileName, pubKey) if err != nil { return "", err } + } if didCreate.Type == BasicDIDMode || didCreate.Type == StandardDIDMode { @@ -177,14 +180,17 @@ func (d *DID) CreateDID(didCreate *DIDCreate) (string, error) { d.log.Error("failed to create keypair", "err", err) return "", err } + err = util.FileWrite(dirName+"/private/"+PvtKeyFileName, pvtKey) if err != nil { return "", err } + err = util.FileWrite(dirName+"/public/"+PubKeyFileName, pubKey) if err != nil { return "", err } + } else { _, err := util.Filecopy(didCreate.PubKeyFile, dirName+"/public/"+PubKeyFileName) if err != nil { From d88e182a0ffc747d919cc2dc0b5db07de71c5754 Mon Sep 17 00:00:00 2001 From: harirubix Date: Wed, 17 Jan 2024 10:54:35 +0530 Subject: [PATCH 03/62] bip39 --- crypto/bip39.go | 107 +++++++++++++++++++++++++++++++++++++++++++ crypto/bip39_test.go | 41 +++++++++++++++++ go.mod | 2 + go.sum | 12 +++++ 4 files changed, 162 insertions(+) create mode 100644 crypto/bip39.go create mode 100644 crypto/bip39_test.go diff --git a/crypto/bip39.go b/crypto/bip39.go new file mode 100644 index 00000000..185ea652 --- /dev/null +++ b/crypto/bip39.go @@ -0,0 +1,107 @@ +package crypto + +import ( + "crypto" + "crypto/ecdsa" + "crypto/rand" + "encoding/pem" + "fmt" + + "github.com/tyler-smith/go-bip32" + "github.com/tyler-smith/go-bip39" +) + +const ( + BIP39 = iota +) + +// Generate a Bip32 HD wallet for the mnemonic and a user supplied randomness +// here we are reusing the password used for sealing for generating random seed +func BIPGenerateKeyPair(cfg *CryptoConfig) ([]byte, []byte, error) { + var privateKeyBytes []byte + var publicKeyBytes []byte + + var err error + if cfg.Alg == 0 { + entropy, _ := bip39.NewEntropy(256) + mnemonic, _ := bip39.NewMnemonic(entropy) + seed := bip39.NewSeed(mnemonic, cfg.Pwd) + masterKey, _ := bip32.NewMasterKey(seed) + privateKey, err := masterKey.NewChildKey(0) + if err != nil { + return nil, nil, err + } + publicKey := privateKey.PublicKey() + + privateKeyBytes = privateKey.Key + publicKeyBytes = publicKey.Key + } else { + return nil, nil, fmt.Errorf("unsupported algorithm") + } + if err != nil { + return nil, nil, err + } + var pemEncPriv []byte + if cfg.Pwd != "" { + encBlock, err := Seal(cfg.Pwd, privateKeyBytes) + if err != nil { + return nil, nil, err + } + _, err = UnSeal(cfg.Pwd, encBlock) + if err != nil { + return nil, nil, err + } + pemEncPriv = pem.EncodeToMemory(&pem.Block{Type: "ENCRYPTED PRIVATE KEY", Bytes: encBlock}) + } else { + pemEncPriv = pem.EncodeToMemory(&pem.Block{Type: "PRIVATE KEY", Bytes: privateKeyBytes}) + } + pemEncPub := pem.EncodeToMemory(&pem.Block{Type: "PUBLIC KEY", Bytes: publicKeyBytes}) + + return pemEncPriv, pemEncPub, nil +} + +// GenerateKeyPair will generate key pair based on the configuration +func BIPDecodeKeyPair(pwd string, privKey []byte, pubKey []byte) ([]byte, []byte, error) { + var cryptoPrivKey []byte + var cryptoPubKey []byte + var err error + if privKey != nil { + pemBlock, _ := pem.Decode(privKey) + if pemBlock == nil { + return nil, nil, fmt.Errorf("invalid private key") + } + fmt.Println(" pemBlock ", pemBlock.Bytes) + fmt.Println(" pwd ", pwd) + + if pemBlock.Type == "ENCRYPTED PRIVATE KEY" { + if pwd == "" { + return nil, nil, fmt.Errorf("key is encrypted need password to decrypt") + } + cryptoPrivKey, err = UnSeal(pwd, pemBlock.Bytes) + if err != nil { + return nil, nil, fmt.Errorf("key is invalid or password is wrong") + } + } + } + if pubKey != nil { + cryptoPubKey, _ := pem.Decode(pubKey) + if cryptoPubKey == nil { + return nil, nil, fmt.Errorf("invalid public key") + } + } + + return cryptoPrivKey, cryptoPubKey, nil +} + +func BIPSign(priv PrivateKey, data []byte) ([]byte, error) { + return priv.(crypto.Signer).Sign(rand.Reader, data, crypto.SHA256) +} + +func BIPVerify(pub PublicKey, data []byte, sig []byte) bool { + switch pub.(type) { + case *ecdsa.PublicKey: + return ecdsa.VerifyASN1(pub.(*ecdsa.PublicKey), data, sig) + default: + return false + } +} diff --git a/crypto/bip39_test.go b/crypto/bip39_test.go new file mode 100644 index 00000000..41577aaa --- /dev/null +++ b/crypto/bip39_test.go @@ -0,0 +1,41 @@ +package crypto + +import ( + "crypto/rand" + "testing" + + secp256k1 "github.com/decred/dcrd/dcrec/secp256k1/v4" +) + +func BIPtest(t *testing.T, alg CryptoAlgType, pwd string) { + + priv, pub, err := BIPGenerateKeyPair(&CryptoConfig{Alg: alg, Pwd: pwd}) + if err != nil { + t.Fatal("failed to generate key pair", "err", err) + } + privKeyBytes, _, err := BIPDecodeKeyPair(pwd, priv, pub) + if err != nil { + t.Fatal("failed to decode key pair", "err", err) + } + + data, err := GetRandBytes(rand.Reader, 20) + if err != nil { + t.Fatal("failed to generate random number", "err", err) + } + + privKey := secp256k1.PrivKeyFromBytes(privKeyBytes) + privKeySer := privKey.ToECDSA() + pubKeySer := privKey.PubKey().ToECDSA() + sig, err := BIPSign(privKeySer, data) + if err != nil { + t.Fatal("failed to do signature", "err", err) + } + + if !BIPVerify(pubKeySer, data, sig) { + t.Fatal("failed to do verify signature", "err", err) + } +} + +func TestBIPKeyGeneration(t *testing.T) { + BIPtest(t, BIP39, "hari") +} diff --git a/go.mod b/go.mod index 1c8877bd..c0b1a3ff 100644 --- a/go.mod +++ b/go.mod @@ -47,6 +47,8 @@ require ( github.com/stretchr/testify v1.8.3 // indirect github.com/swaggo/files v1.0.0 // indirect github.com/swaggo/http-swagger v1.3.4 + github.com/tyler-smith/go-bip32 v1.0.0 + github.com/tyler-smith/go-bip39 v1.1.0 github.com/whyrusleeping/tar-utils v0.0.0-20201201191210-20a61371de5b // indirect golang.org/x/net v0.10.0 golang.org/x/tools v0.9.3 // indirect diff --git a/go.sum b/go.sum index f090b70a..5ce22340 100644 --- a/go.sum +++ b/go.sum @@ -606,6 +606,10 @@ github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03 github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= github.com/EnsurityTechnologies/helper v1.0.0 h1:x6kaCFvqH35/P8eD8Vkx/IUUkbvDqyh4KVwqDJWIfWA= github.com/EnsurityTechnologies/helper v1.0.0/go.mod h1:KESBOBjgzlkimm3dDwr49wjbMXWtaoqrA3SiwhxGDwQ= +github.com/FactomProject/basen v0.0.0-20150613233007-fe3947df716e h1:ahyvB3q25YnZWly5Gq1ekg6jcmWaGj/vG/MhF4aisoc= +github.com/FactomProject/basen v0.0.0-20150613233007-fe3947df716e/go.mod h1:kGUqhHd//musdITWjFvNTHn90WG9bMLBEPQZ17Cmlpw= +github.com/FactomProject/btcutilecc v0.0.0-20130527213604-d3a63a5752ec h1:1Qb69mGp/UtRPn422BH4/Y4Q3SLUrD9KHuDkm8iodFc= +github.com/FactomProject/btcutilecc v0.0.0-20130527213604-d3a63a5752ec/go.mod h1:CD8UlnlLDiqb36L110uqiP2iSflVjx9g/3U9hCI4q2U= github.com/JohnCGriffin/overflow v0.0.0-20211019200055-46fa312c352c/go.mod h1:X0CRv0ky0k6m906ixxpzmDRLvX58TFUKS2eePweuyxk= github.com/KyleBanks/depth v1.2.1 h1:5h8fQADFrWtarTdtDudMmGsC7GPbOAu6RVB3ffsVFHc= github.com/KyleBanks/depth v1.2.1/go.mod h1:jzSb9d0L43HxTQfT+oSA1EEp2q+ne2uh6XgeJcm8brE= @@ -662,6 +666,7 @@ github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWR github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= +github.com/cmars/basen v0.0.0-20150613233007-fe3947df716e/go.mod h1:P13beTBKr5Q18lJe1rIoLUqjM+CB1zYrRg44ZqGuQSA= github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= github.com/cncf/udpa/go v0.0.0-20200629203442-efcf912fb354/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= @@ -1085,6 +1090,7 @@ github.com/spf13/afero v1.9.2/go.mod h1:iUV7ddyEEZPO5gA3zD4fJt6iStLlL+Lg4m2cihcD github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= +github.com/stretchr/testify v1.1.5-0.20170601210322-f6abca593680/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= @@ -1106,6 +1112,10 @@ github.com/swaggo/swag v1.16.1 h1:fTNRhKstPKxcnoKsytm4sahr8FaYzUcT7i1/3nd/fBg= github.com/swaggo/swag v1.16.1/go.mod h1:9/LMvHycG3NFHfR6LwvikHv5iFvmPADQ359cKikGxto= github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7 h1:epCh84lMvA70Z7CTTCmYQn2CKbY8j86K7/FAIr141uY= github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7/go.mod h1:q4W45IWZaF22tdD+VEXcAWRA037jwmWEB5VWYORlTpc= +github.com/tyler-smith/go-bip32 v1.0.0 h1:sDR9juArbUgX+bO/iblgZnMPeWY1KZMUC2AFUJdv5KE= +github.com/tyler-smith/go-bip32 v1.0.0/go.mod h1:onot+eHknzV4BVPwrzqY5OoVpyCvnwD7lMawL5aQupE= +github.com/tyler-smith/go-bip39 v1.1.0 h1:5eUemwrMargf3BSLRRCalXT93Ns6pQJIjYQN2nyfOP8= +github.com/tyler-smith/go-bip39 v1.1.0/go.mod h1:gUYDtqQw1JS3ZJ8UWVcGTGqqr6YIN3CWg+kkNaLt55U= github.com/urfave/cli/v2 v2.3.0/go.mod h1:LJmUH05zAU44vOAcrfzZQKsZbVcdbOG8rtL3/XcUArI= github.com/whyrusleeping/tar-utils v0.0.0-20180509141711-8c6c8ba81d5c/go.mod h1:xxcJeBb7SIUl/Wzkz1eVKJE/CB34YNrqX2TQI6jY9zs= github.com/whyrusleeping/tar-utils v0.0.0-20201201191210-20a61371de5b h1:wA3QeTsaAXybLL2kb2cKhCAQTHgYTMwuI8lBlJSv5V8= @@ -1132,6 +1142,7 @@ go.opencensus.io v0.23.0/go.mod h1:XItmlyltB5F7CS4xOC1DcqMoFqwtC6OG2xF7mCv7P7E= go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo= go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI= go.opentelemetry.io/proto/otlp v0.15.0/go.mod h1:H7XAot3MsfNsj7EXtrA2q5xSNQ10UqI405h3+duxN4U= +golang.org/x/crypto v0.0.0-20170613210332-850760c427c5/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20170930174604-9419663f5a44/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190325154230-a5d413f7728c/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= @@ -1838,6 +1849,7 @@ honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= honnef.co/go/tools v0.1.3/go.mod h1:NgwopIslSNH47DimFoV78dnkksY2EFtX0ajyb3K/las= +launchpad.net/gocheck v0.0.0-20140225173054-000000000087/go.mod h1:hj7XX3B/0A+80Vse0e+BUHsHMTEhd0O4cpUHr/e/BUM= lukechampine.com/blake3 v1.1.6 h1:H3cROdztr7RCfoaTpGZFQsrqvweFLrqS73j7L7cmR5c= lukechampine.com/blake3 v1.1.6/go.mod h1:tkKEOtDkNtklkXtLNEOGNq5tcV90tJiA1vAA12R78LA= lukechampine.com/uint128 v1.1.1/go.mod h1:c4eWIwlEGaxC/+H1VguhU4PHXNWDCDMUlWdIWl2j1gk= From 698929a5116d11a7f7cf36870b40045f4edca9d7 Mon Sep 17 00:00:00 2001 From: harirubix Date: Wed, 17 Jan 2024 16:08:07 +0530 Subject: [PATCH 04/62] added methods to generate master and child keys --- crypto/bip39.go | 72 +++++++++++++++++++++++--------------------- crypto/bip39_test.go | 15 ++++++--- 2 files changed, 47 insertions(+), 40 deletions(-) diff --git a/crypto/bip39.go b/crypto/bip39.go index 185ea652..f2bb7211 100644 --- a/crypto/bip39.go +++ b/crypto/bip39.go @@ -15,82 +15,84 @@ const ( BIP39 = iota ) -// Generate a Bip32 HD wallet for the mnemonic and a user supplied randomness -// here we are reusing the password used for sealing for generating random seed -func BIPGenerateKeyPair(cfg *CryptoConfig) ([]byte, []byte, error) { +// Generate child private and public keys for BIP39 masterkey and given path +// The child private key is regenerated on demand from master key hence never stored +// The child public key need to shared with other peers for verification +// Make sure the path of child is also stored along with public key +func BIPGenerateChild(masterKey string, childPath int) ([]byte, []byte, error) { var privateKeyBytes []byte var publicKeyBytes []byte + masterKeybip32, err := bip32.B58Deserialize(masterKey) + if err != nil { + return nil, nil, err + } + privateKey, err := masterKeybip32.NewChildKey(uint32(childPath)) + if err != nil { + return nil, nil, err + } + publicKey := privateKey.PublicKey() + privateKeyBytes = privateKey.Key + publicKeyBytes = publicKey.Key + return privateKeyBytes, publicKeyBytes, nil +} +// Generate a Bip32 HD wallet MasteKey for the mnemonic and a user provided randomness +// here we are reusing the password used for sealing masterkey as source of randomness also +func BIPGenerateMasterKey(cfg *CryptoConfig) ([]byte, error) { + var masterkeySeralise string var err error if cfg.Alg == 0 { entropy, _ := bip39.NewEntropy(256) mnemonic, _ := bip39.NewMnemonic(entropy) seed := bip39.NewSeed(mnemonic, cfg.Pwd) masterKey, _ := bip32.NewMasterKey(seed) - privateKey, err := masterKey.NewChildKey(0) + masterkeySeralise = masterKey.B58Serialize() if err != nil { - return nil, nil, err + return nil, err } - publicKey := privateKey.PublicKey() - - privateKeyBytes = privateKey.Key - publicKeyBytes = publicKey.Key } else { - return nil, nil, fmt.Errorf("unsupported algorithm") + return nil, fmt.Errorf("unsupported algorithm") } if err != nil { - return nil, nil, err + return nil, err } var pemEncPriv []byte if cfg.Pwd != "" { - encBlock, err := Seal(cfg.Pwd, privateKeyBytes) + encBlock, err := Seal(cfg.Pwd, []byte(masterkeySeralise)) if err != nil { - return nil, nil, err + return nil, err } _, err = UnSeal(cfg.Pwd, encBlock) if err != nil { - return nil, nil, err + return nil, err } pemEncPriv = pem.EncodeToMemory(&pem.Block{Type: "ENCRYPTED PRIVATE KEY", Bytes: encBlock}) } else { - pemEncPriv = pem.EncodeToMemory(&pem.Block{Type: "PRIVATE KEY", Bytes: privateKeyBytes}) + pemEncPriv = pem.EncodeToMemory(&pem.Block{Type: "PRIVATE KEY", Bytes: []byte(masterkeySeralise)}) } - pemEncPub := pem.EncodeToMemory(&pem.Block{Type: "PUBLIC KEY", Bytes: publicKeyBytes}) - - return pemEncPriv, pemEncPub, nil + return pemEncPriv, nil } -// GenerateKeyPair will generate key pair based on the configuration -func BIPDecodeKeyPair(pwd string, privKey []byte, pubKey []byte) ([]byte, []byte, error) { +// Decode the master public key +func BIPDecodeMasterKey(pwd string, privKey []byte) ([]byte, error) { var cryptoPrivKey []byte - var cryptoPubKey []byte var err error if privKey != nil { pemBlock, _ := pem.Decode(privKey) if pemBlock == nil { - return nil, nil, fmt.Errorf("invalid private key") + return nil, fmt.Errorf("invalid private key") } - fmt.Println(" pemBlock ", pemBlock.Bytes) - fmt.Println(" pwd ", pwd) - if pemBlock.Type == "ENCRYPTED PRIVATE KEY" { if pwd == "" { - return nil, nil, fmt.Errorf("key is encrypted need password to decrypt") + return nil, fmt.Errorf("key is encrypted need password to decrypt") } cryptoPrivKey, err = UnSeal(pwd, pemBlock.Bytes) if err != nil { - return nil, nil, fmt.Errorf("key is invalid or password is wrong") + return nil, fmt.Errorf("key is invalid or password is wrong") } } } - if pubKey != nil { - cryptoPubKey, _ := pem.Decode(pubKey) - if cryptoPubKey == nil { - return nil, nil, fmt.Errorf("invalid public key") - } - } - - return cryptoPrivKey, cryptoPubKey, nil + return cryptoPrivKey, nil } func BIPSign(priv PrivateKey, data []byte) ([]byte, error) { diff --git a/crypto/bip39_test.go b/crypto/bip39_test.go index 41577aaa..fa4ac2e3 100644 --- a/crypto/bip39_test.go +++ b/crypto/bip39_test.go @@ -9,21 +9,27 @@ import ( func BIPtest(t *testing.T, alg CryptoAlgType, pwd string) { - priv, pub, err := BIPGenerateKeyPair(&CryptoConfig{Alg: alg, Pwd: pwd}) + masterKey, err := BIPGenerateMasterKey(&CryptoConfig{Alg: alg, Pwd: pwd}) if err != nil { t.Fatal("failed to generate key pair", "err", err) } - privKeyBytes, _, err := BIPDecodeKeyPair(pwd, priv, pub) + + masterKeyDecoded, err := BIPDecodeMasterKey(pwd, masterKey) if err != nil { t.Fatal("failed to decode key pair", "err", err) } + priv, _, err := BIPGenerateChild(string(masterKeyDecoded), 0) + if err != nil { + t.Fatal("failed to generate child", "err", err) + } + data, err := GetRandBytes(rand.Reader, 20) if err != nil { t.Fatal("failed to generate random number", "err", err) } - privKey := secp256k1.PrivKeyFromBytes(privKeyBytes) + privKey := secp256k1.PrivKeyFromBytes(priv) privKeySer := privKey.ToECDSA() pubKeySer := privKey.PubKey().ToECDSA() sig, err := BIPSign(privKeySer, data) @@ -35,7 +41,6 @@ func BIPtest(t *testing.T, alg CryptoAlgType, pwd string) { t.Fatal("failed to do verify signature", "err", err) } } - func TestBIPKeyGeneration(t *testing.T) { - BIPtest(t, BIP39, "hari") + BIPtest(t, BIP39, "test") } From a2479fa8b085ce838a71c9a2694003795e9a04e6 Mon Sep 17 00:00:00 2001 From: harirubix Date: Fri, 19 Jan 2024 11:01:00 +0530 Subject: [PATCH 05/62] modularise fucntions --- crypto/bip39.go | 55 +++++++++++++++++++++++++++++-------------------- 1 file changed, 33 insertions(+), 22 deletions(-) diff --git a/crypto/bip39.go b/crypto/bip39.go index f2bb7211..72fd7454 100644 --- a/crypto/bip39.go +++ b/crypto/bip39.go @@ -36,33 +36,20 @@ func BIPGenerateChild(masterKey string, childPath int) ([]byte, []byte, error) { return privateKeyBytes, publicKeyBytes, nil } -// Generate a Bip32 HD wallet MasteKey for the mnemonic and a user provided randomness -// here we are reusing the password used for sealing masterkey as source of randomness also -func BIPGenerateMasterKey(cfg *CryptoConfig) ([]byte, error) { +// Generate BIPMasterKey from Mnemonic and user provided password +// Useful in key recovery / device migration through mnemonics +func BIPGenerateMasterKeyFromMnemonic(mnemonic string, pwd string) ([]byte, error) { var masterkeySeralise string - var err error - if cfg.Alg == 0 { - entropy, _ := bip39.NewEntropy(256) - mnemonic, _ := bip39.NewMnemonic(entropy) - seed := bip39.NewSeed(mnemonic, cfg.Pwd) - masterKey, _ := bip32.NewMasterKey(seed) - masterkeySeralise = masterKey.B58Serialize() - if err != nil { - return nil, err - } - } else { - return nil, fmt.Errorf("unsupported algorithm") - } - if err != nil { - return nil, err - } + seed := bip39.NewSeed(mnemonic, pwd) + masterKey, _ := bip32.NewMasterKey(seed) + masterkeySeralise = masterKey.B58Serialize() var pemEncPriv []byte - if cfg.Pwd != "" { - encBlock, err := Seal(cfg.Pwd, []byte(masterkeySeralise)) + if pwd != "" { + encBlock, err := Seal(pwd, []byte(masterkeySeralise)) if err != nil { return nil, err } - _, err = UnSeal(cfg.Pwd, encBlock) + _, err = UnSeal(pwd, encBlock) if err != nil { return nil, err } @@ -73,6 +60,30 @@ func BIPGenerateMasterKey(cfg *CryptoConfig) ([]byte, error) { return pemEncPriv, nil } +// Generate a random BIP mnemonic in rubix +func BIPGenerateMnemonic() string { + entropy, _ := bip39.NewEntropy(256) + mnemonic, _ := bip39.NewMnemonic(entropy) + return mnemonic +} + +// Generate a Bip32 HD wallet MasteKey for the mnemonic and a user provided randomness +// here we are reusing the password used for sealing masterkey as source of randomness also +func BIPGenerateMasterKey(cfg *CryptoConfig) ([]byte, error) { + var pemEncPriv []byte + var err error + if cfg.Alg == 0 { + mnemonic := BIPGenerateMnemonic() + pemEncPriv, err = BIPGenerateMasterKeyFromMnemonic(mnemonic, cfg.Pwd) + if err != nil { + return nil, err + } + } else { + return nil, fmt.Errorf("unsupported algorithm") + } + return pemEncPriv, nil +} + // Decode the master public key func BIPDecodeMasterKey(pwd string, privKey []byte) ([]byte, error) { var cryptoPrivKey []byte From 891864c800a129b7553edaea26c2b895c8b96ac6 Mon Sep 17 00:00:00 2001 From: ashi31 Date: Mon, 22 Jan 2024 14:04:35 +0530 Subject: [PATCH 06/62] sending transactions to explorer --- client/explorer.go | 39 ++++++++++++ command/command.go | 17 ++++++ command/explorer.go | 38 ++++++++++++ core/explorer.go | 128 +++++++++++++++++++++++++++++++++------ core/model/explorer.go | 13 ++++ server/config.go | 40 ++++++++++++ server/server.go | 3 + setup/setup.go | 3 + wrapper/ensweb/client.go | 24 ++++++++ 9 files changed, 286 insertions(+), 19 deletions(-) create mode 100644 client/explorer.go create mode 100644 command/explorer.go create mode 100644 core/model/explorer.go diff --git a/client/explorer.go b/client/explorer.go new file mode 100644 index 00000000..6bcd2b17 --- /dev/null +++ b/client/explorer.go @@ -0,0 +1,39 @@ +package client + +import ( + "github.com/rubixchain/rubixgoplatform/core/model" + "github.com/rubixchain/rubixgoplatform/setup" +) + +func (c *Client) AddExplorer(links []string) (string, bool) { + m := model.ExplorerLinks{ + Links: links, + } + var rm model.BasicResponse + err := c.sendJSONRequest("POST", setup.APIAddExplorer, nil, &m, &rm) + if err != nil { + return err.Error(), false + } + return rm.Message, rm.Status +} + +func (c *Client) RemoveExplorer(links []string) (string, bool) { + m := model.ExplorerLinks{ + Links: links, + } + var rm model.BasicResponse + err := c.sendJSONRequest("POST", setup.APIRemoveExplorer, nil, &m, &rm) + if err != nil { + return err.Error(), false + } + return rm.Message, rm.Status +} + +func (c *Client) GetAllExplorer() ([]string, string, bool) { + var rm model.ExplorerResponse + err := c.sendJSONRequest("GET", setup.APIGetAllExplorer, nil, nil, &rm) + if err != nil { + return nil, err.Error(), false + } + return rm.Result.Links, rm.Message, rm.Status +} diff --git a/command/command.go b/command/command.go index 7ba75d7e..f5ec9efc 100644 --- a/command/command.go +++ b/command/command.go @@ -76,6 +76,9 @@ const ( DumpSmartContractTokenChainCmd string = "dumpsmartcontracttokenchain" GetTokenBlock string = "gettokenblock" GetSmartContractData string = "getsmartcontractdata" + AddExplorerCmd string = "addexplorer" + RemoveExplorerCmd string = "removeexplorer" + GetAllExplorerCmd string = "getallexplorer" ) var commands = []string{VersionCmd, @@ -236,6 +239,7 @@ type Command struct { smartContractData string executorAddr string latest bool + links []string } func showVersion() { @@ -360,6 +364,7 @@ func Run(args []string) { cmd := &Command{} var peers string var timeout int + var links string flag.StringVar(&cmd.runDir, "p", "./", "Working directory path") flag.StringVar(&cmd.logFile, "logFile", "", "Log file name") @@ -426,6 +431,7 @@ func Run(args []string) { flag.IntVar(&cmd.publishType, "pubType", 0, "Smart contract event publishing type(Deploy & Execute)") flag.StringVar(&cmd.smartContractData, "sctData", "data", "Smart contract execution info") flag.StringVar(&cmd.executorAddr, "executorAddr", "", "Smart contract Executor Address") + flag.StringVar(&links, "links", "", "Explorer url") if len(os.Args) < 2 { fmt.Println("Invalid Command") @@ -444,6 +450,11 @@ func Run(args []string) { cmd.peers = strings.Split(peers, ",") } + if links != "" { + links = strings.ReplaceAll(links, " ", "") + cmd.links = strings.Split(links, ",") + } + cmd.timeout = time.Duration(timeout) * time.Minute if !cmd.validateOptions() { @@ -566,6 +577,12 @@ func Run(args []string) { cmd.getSmartContractData() case ExecuteSmartcontractCmd: cmd.executeSmartcontract() + case AddExplorerCmd: + cmd.addExplorer() + case RemoveExplorerCmd: + cmd.removeExplorer() + case GetAllExplorerCmd: + cmd.getAllExplorer() default: cmd.log.Error("Invalid command") } diff --git a/command/explorer.go b/command/explorer.go new file mode 100644 index 00000000..871d5012 --- /dev/null +++ b/command/explorer.go @@ -0,0 +1,38 @@ +package command + +func (cmd *Command) addExplorer() { + if len(cmd.links) == 0 { + cmd.log.Error("links required for Explorer") + return + } + msg, status := cmd.c.AddExplorer(cmd.links) + + if !status { + cmd.log.Error("Add Explorer command failed, " + msg) + } else { + cmd.log.Info("Add Explorer command finished, " + msg) + } +} + +func (cmd *Command) removeExplorer() { + if len(cmd.links) == 0 { + cmd.log.Error("links required for Explorer") + return + } + msg, status := cmd.c.RemoveExplorer(cmd.links) + if !status { + cmd.log.Error("Remove Explorer command failed, " + msg) + } else { + cmd.log.Info("Remove Explorer command finished, " + msg) + } +} + +func (cmd *Command) getAllExplorer() { + links, msg, status := cmd.c.GetAllExplorer() + if !status { + cmd.log.Error("Get all Explorer command failed, " + msg) + } else { + cmd.log.Info("Get all Explorer command finished, " + msg) + cmd.log.Info("Explorer links", "links", links) + } +} diff --git a/core/explorer.go b/core/explorer.go index 7661fdaf..c4298837 100644 --- a/core/explorer.go +++ b/core/explorer.go @@ -4,6 +4,7 @@ import ( "fmt" "net/http" + "github.com/rubixchain/rubixgoplatform/core/storage" "github.com/rubixchain/rubixgoplatform/wrapper/config" "github.com/rubixchain/rubixgoplatform/wrapper/ensweb" "github.com/rubixchain/rubixgoplatform/wrapper/helper/jsonutil" @@ -16,11 +17,13 @@ const ( ExplorerTransactionAPI string = "CreateOrUpdateRubixTransaction" ExplorerCreateDataTransAPI string = "create-datatokens" ExplorerMapDIDAPI string = "map-did" + ExplorerURLTable string = "ExplorerURLTable" ) type ExplorerClient struct { ensweb.Client log logger.Logger + es storage.Storage } type ExplorerDID struct { @@ -65,11 +68,33 @@ type ExplorerResponse struct { Status bool `json:"Status"` } +type ExplorerURL struct { + URL string `gorm:"column:url;primaryKey" json:"ExplorerURL"` + Port int `gorm:"column:port" json:"Explorerport"` +} + func (c *Core) InitRubixExplorer() error { + + err := c.s.Init(ExplorerURLTable, &ExplorerURL{}, true) + if err != nil { + c.log.Error("Failed to initialise storage ExplorerURL ", "err", err) + return err + } + url := "deamon-explorer.azurewebsites.net" if c.testNet { url = "rubix-deamon-api.ensurity.com" } + + err = c.s.Read(ExplorerURLTable, &ExplorerURL{}, "url=?", url) + if err != nil { + err = c.s.Write(ExplorerURLTable, &ExplorerURL{URL: url, Port: 443}) + } + + if err != nil { + return err + } + cl, err := ensweb.NewClient(&config.Config{ServerAddress: url, ServerPort: "443", Production: "true"}, c.log) if err != nil { return err @@ -77,33 +102,44 @@ func (c *Core) InitRubixExplorer() error { c.ec = &ExplorerClient{ Client: cl, log: c.log.Named("explorerclient"), + es: c.s, } return nil } func (ec *ExplorerClient) SendExploerJSONRequest(method string, path string, input interface{}, output interface{}) error { - req, err := ec.JSONRequest(method, ExplorerBasePath+path, input) - if err != nil { - return err - } - resp, err := ec.Do(req) + + var urls []string + urls, err := ec.GetAllExplorer() if err != nil { - ec.log.Error("Failed r get response from explorer", "err", err) return err } - defer resp.Body.Close() - if resp.StatusCode != http.StatusOK { - str := fmt.Sprintf("Http Request failed with status %d", resp.StatusCode) - ec.log.Error(str) - return fmt.Errorf(str) - } - if output == nil { - return nil - } - err = jsonutil.DecodeJSONFromReader(resp.Body, output) - if err != nil { - ec.log.Error("Invalid response from the node", "err", err) - return err + + for _, url := range urls { + req, err := ec.JSONRequestForExplorer(method, ExplorerBasePath+path, input, url) + if err != nil { + ec.log.Error("Request could not be sent to : "+url, "err", err) + continue + } + resp, err := ec.Do(req) + if err != nil { + ec.log.Error("Failed to get response from explorer : "+url, "err", err) + continue + } + defer resp.Body.Close() + if resp.StatusCode != http.StatusOK { + str := fmt.Sprintf("Http Request failed with status %d for "+url, resp.StatusCode) + ec.log.Error(str) + continue + } + if output == nil { + continue + } + err = jsonutil.DecodeJSONFromReader(resp.Body, output) + if err != nil { + ec.log.Error("Invalid response from the node", "err", err) + continue + } } return nil } @@ -168,3 +204,57 @@ func (ec *ExplorerClient) ExplorerDataTransaction(et *ExplorerDataTrans) error { } return nil } + +func (c *Core) AddExplorer(links []string) error { + + var eurl []ExplorerURL + + for _, url := range links { + + eur := ExplorerURL{ + URL: url, + Port: 0, + } + eurl = append(eurl, eur) + } + + err := c.s.Write(ExplorerURLTable, eurl) + if err != nil { + return err + } + return nil +} + +func (c *Core) RemoveExplorer(links []string) error { + + for _, link := range links { + err := c.s.Delete(ExplorerURLTable, &ExplorerURL{}, "url=?", link) + + if err != nil { + return err + } + } + return nil +} + +func (c *Core) GetAllExplorer() ([]string, error) { + var urls []string + urls, err := c.ec.GetAllExplorer() + if err != nil { + return nil, err + } + return urls, nil +} + +func (ec *ExplorerClient) GetAllExplorer() ([]string, error) { + var eurl []ExplorerURL + var urls []string + err := ec.es.Read(ExplorerURLTable, &eurl, "url!=?", "") + if err != nil { + return nil, err + } + for _, url := range eurl { + urls = append(urls, fmt.Sprintf("https://%s", url.URL)) + } + return urls, nil +} diff --git a/core/model/explorer.go b/core/model/explorer.go new file mode 100644 index 00000000..6956e7cc --- /dev/null +++ b/core/model/explorer.go @@ -0,0 +1,13 @@ +package model + +// ExplorerLinks +type ExplorerLinks struct { + Links []string `json:"links"` +} + +// ExplorerResponse used as model for the API responses +type ExplorerResponse struct { + Status bool `json:"status"` + Message string `json:"message"` + Result ExplorerLinks `json:"result"` +} diff --git a/server/config.go b/server/config.go index e6b7f959..f4aa3c63 100644 --- a/server/config.go +++ b/server/config.go @@ -112,3 +112,43 @@ func (s *Server) APISetupDB(req *ensweb.Request) *ensweb.Result { } return s.BasicResponse(req, true, "DB setup done successfully", nil) } + +// APIGetAllExplorer will get all explorer URLs from the db +func (s *Server) APIGetAllExplorer(req *ensweb.Request) *ensweb.Result { + links, err := s.c.GetAllExplorer() + if err != nil { + return s.BasicResponse(req, false, "Failed to get explorer urls"+err.Error(), nil) + } + m := model.ExplorerLinks{ + Links: links, + } + return s.BasicResponse(req, true, "Got all the explorer URLs successfully", m) +} + +// APIAddExplorer will add bootstrap peers to the configuration +func (s *Server) APIAddExplorer(req *ensweb.Request) *ensweb.Result { + var m model.ExplorerLinks + err := s.ParseJSON(req, &m) + if err != nil { + return s.BasicResponse(req, false, "invlid input request", nil) + } + err = s.c.AddExplorer(m.Links) + if err != nil { + return s.BasicResponse(req, false, "failed to add explorer, "+err.Error(), nil) + } + return s.BasicResponse(req, true, "explorer added successfully", nil) +} + +// APIRemoveExplorer will remove bootstrap peers from the configuration +func (s *Server) APIRemoveExplorer(req *ensweb.Request) *ensweb.Result { + var m model.ExplorerLinks + err := s.ParseJSON(req, &m) + if err != nil { + return s.BasicResponse(req, false, "invlid input request", nil) + } + err = s.c.RemoveExplorer(m.Links) + if err != nil { + return s.BasicResponse(req, false, "failed to remove explorer, "+err.Error(), nil) + } + return s.BasicResponse(req, true, "explorer removed successfully", nil) +} diff --git a/server/server.go b/server/server.go index d867538a..189682e6 100644 --- a/server/server.go +++ b/server/server.go @@ -152,6 +152,9 @@ func (s *Server) RegisterRoutes() { s.AddRoute(setup.APIExecuteSmartContract, "POST", s.AuthHandle(s.APIExecuteSmartContract, true, s.AuthError, false)) s.AddRoute(setup.APIGetSmartContractTokenData, "POST", s.AuthHandle(s.APIGetSmartContractTokenChainData, true, s.AuthError, false)) s.AddRoute(setup.APIRegisterCallBackURL, "POST", s.AuthHandle(s.APIRegisterCallbackURL, true, s.AuthError, false)) + s.AddRoute(setup.APIGetAllExplorer, "GET", s.AuthHandle(s.APIGetAllExplorer, false, s.AuthError, true)) + s.AddRoute(setup.APIAddExplorer, "POST", s.AuthHandle(s.APIAddExplorer, false, s.AuthError, true)) + s.AddRoute(setup.APIRemoveExplorer, "POST", s.AuthHandle(s.APIRemoveExplorer, false, s.AuthError, true)) } func (s *Server) ExitFunc() error { diff --git a/setup/setup.go b/setup/setup.go index df4c52c5..51384ab2 100644 --- a/setup/setup.go +++ b/setup/setup.go @@ -59,6 +59,9 @@ const ( APIDumpSmartContractTokenChainBlock string = "/api/dump-smart-contract-token-chain" APIGetSmartContractTokenData string = "/api/get-smart-contract-token-chain-data" APIRegisterCallBackURL string = "/api/register-callback-url" + APIGetAllExplorer string = "/api/get-all-explorer" + APIAddExplorer string = "/api/add-explorer" + APIRemoveExplorer string = "/api/remove-explorer" ) // jwt.RegisteredClaims diff --git a/wrapper/ensweb/client.go b/wrapper/ensweb/client.go index bb996c91..31571457 100644 --- a/wrapper/ensweb/client.go +++ b/wrapper/ensweb/client.go @@ -128,6 +128,30 @@ func (c *Client) JSONRequest(method string, requestPath string, model interface{ return req, err } +func (c *Client) JSONRequestForExplorer(method string, requestPath string, model interface{}, explorerURL string) (*http.Request, error) { + var body *bytes.Buffer + if model != nil { + j, err := json.Marshal(model) + if err != nil { + return nil, err + } + body = bytes.NewBuffer(j) + } else { + body = bytes.NewBuffer(make([]byte, 0)) + } + + url := explorerURL + requestPath + + req, err := http.NewRequest(method, url, body) + if err != nil { + return nil, err + } + + req.Header.Set("Content-Type", "application/json") + + return req, err +} + func (c *Client) MultiFormRequest(method string, requestPath string, field map[string]string, files map[string]string) (*http.Request, error) { var b bytes.Buffer w := multipart.NewWriter(&b) From 68e1a9b3b954e0444f0684b5a0957c58880fd5fc Mon Sep 17 00:00:00 2001 From: Maneesha-rubix Date: Wed, 24 Jan 2024 11:28:28 +0530 Subject: [PATCH 07/62] sign version check --- block/block.go | 13 +++++++ block/transaction.go | 1 + command/did.go | 1 + contract/contract.go | 60 +++++++++++++++++++++++++----- core/quorum_initiator.go | 7 ++++ core/quorum_recv.go | 12 +++++- did/basic.go | 9 +++++ did/child.go | 4 ++ did/did.go | 1 + did/light.go | 79 ++++++++++++++++++++++++++++++++++++++-- did/model.go | 9 +++++ did/quorum.go | 4 ++ did/standard.go | 4 ++ did/wallet.go | 4 ++ rac/rac.go | 3 ++ 15 files changed, 197 insertions(+), 14 deletions(-) diff --git a/block/block.go b/block/block.go index b6a43262..06b34bb6 100644 --- a/block/block.go +++ b/block/block.go @@ -40,6 +40,10 @@ const ( TCSmartContractDataKey string = "9" ) +// const ( +// PkiSignVersion int = iota +// ) + const ( TokenMintedType string = "01" TokenTransferredType string = "02" @@ -166,6 +170,11 @@ func (b *Block) blkDecode() error { return fmt.Errorf("invalid block, missing block content") } hb := util.CalculateHash(bc.([]byte), "SHA3-256") + + // sigVersion := make([]byte, 1) + // sigVersion[0] = byte(1) + // new_hb := append(hb, sigVersion...) + var tcb map[string]interface{} err = cbor.Unmarshal(bc.([]byte), &tcb) if err != nil { @@ -199,6 +208,10 @@ func (b *Block) blkEncode() error { return err } hb := util.CalculateHash(bc, "SHA3-256") + // sigVersion := make([]byte, 1) + // sigVersion[0] = byte(1) + // new_hb := append(hb, sigVersion...) + b.bm[TCBlockHashKey] = util.HexToStr(hb) m := make(map[string]interface{}) m[TCBlockContentKey] = bc diff --git a/block/transaction.go b/block/transaction.go index 589179da..a5f98857 100644 --- a/block/transaction.go +++ b/block/transaction.go @@ -78,6 +78,7 @@ type TransInfo struct { Tokens []TransTokens `json:"tokens"` DeployerDID string `json:"deployerDID"` ExecutorDID string `json:"executorDID"` + // SignVersion int `json:"signVersion"` } func newTransToken(b *Block, tt *TransTokens) map[string]interface{} { diff --git a/command/did.go b/command/did.go index 13e489a5..11a8bf82 100644 --- a/command/did.go +++ b/command/did.go @@ -284,6 +284,7 @@ func (cmd *Command) SignatureResponse(br *model.BasicResponse, timeout ...time.D return "Failed to do signature, " + err.Error(), false } sresp.Signature.Signature = sig + sresp.Password = password case did.BasicDIDMode: sresp.Password = password case did.StandardDIDMode: diff --git a/contract/contract.go b/contract/contract.go index faa6ce58..56ad429a 100644 --- a/contract/contract.go +++ b/contract/contract.go @@ -215,23 +215,30 @@ func (c *Contract) GetType() uint64 { } func (c *Contract) GetHashSig(did string) (string, string, string, error) { + fmt.Println("entered GetHashSig") hi, ok := c.sm[SCBlockHashKey] + fmt.Println("fetched blockhash key from db", hi) if !ok { return "", "", "", fmt.Errorf("invalid smart contract, hash block is missing") } ssi, ok := c.sm[SCShareSignatureKey] + fmt.Println("fetched share sign key from db", ssi) if !ok { return "", "", "", fmt.Errorf("invalid smart contract, share signature block is missing") } ksi, ok := c.sm[SCKeySignatureKey] + fmt.Println("fetched pvt sign key from db", ksi) if !ok { return "", "", "", fmt.Errorf("invalid smart contract, key signature block is missing") } ss := util.GetStringFromMap(ssi, did) + fmt.Println("fetched share sign from db", ss) ks := util.GetStringFromMap(ksi, did) - if ss == "" || ks == "" { + fmt.Println("fetched pvt sign from db", ks) + // ss == "" || + if ks == "" { return "", "", "", fmt.Errorf("invalid smart contract, share/key signature block is missing") } return hi.(string), ss, ks, nil @@ -377,15 +384,25 @@ func (c *Contract) GetCommitedTokensInfo() []TokenInfo { } func (c *Contract) UpdateSignature(dc did.DIDCrypto) error { + fmt.Println("updating signature") did := dc.GetDID() hash, err := c.GetHash() if err != nil { return fmt.Errorf("Failed to get hash of smart contract, " + err.Error()) } - ssig, psig, err := dc.Sign(hash) + fmt.Println("calling sign function") + ssig, psig, _ := dc.Sign(hash) + hs, _, _, _ := c.GetHashSig(did) + ok, err := dc.PvtVerify([]byte(hs), psig) if err != nil { - return fmt.Errorf("Failed to get signature, " + err.Error()) + return err + } + if !ok { + return fmt.Errorf("did signature verification failed line 401") } + // if err != nil { + // return fmt.Errorf("Failed to get signature, " + err.Error()) + // } if c.sm[SCShareSignatureKey] == nil { ksm := make(map[string]interface{}) ksm[did] = util.HexToStr(ssig) @@ -428,18 +445,43 @@ func (c *Contract) UpdateSignature(dc did.DIDCrypto) error { } func (c *Contract) VerifySignature(dc did.DIDCrypto) error { + fmt.Println("entered VerifySignature") did := dc.GetDID() + fmt.Println("got did") hs, ss, ps, err := c.GetHashSig(did) + fmt.Println("got hash sig") + fmt.Println(hs) + fmt.Println(ss) + fmt.Println(util.StrToHex(ps)) + fmt.Println(err) if err != nil { c.log.Error("err", err) return err } - ok, err := dc.Verify(hs, util.StrToHex(ss), util.StrToHex(ps)) - if err != nil { - return err - } - if !ok { - return fmt.Errorf("did signature verification failed") + fmt.Println("getting sign version") + sign_vers := dc.GetSignVersion() + fmt.Println("calling verify func") + fmt.Println(sign_vers) + // switch sign_vers {} + if ss != "" { + ok, err := dc.Verify(hs, util.StrToHex(ss), util.StrToHex(ps)) + if err != nil { + return err + } + if !ok { + return fmt.Errorf("did signature verification failed") + } + } else { + ok, err := dc.PvtVerify([]byte(hs), util.StrToHex(ps)) + if err != nil { + return err + } + if !ok { + return fmt.Errorf("did signature verification failed") + } } + + fmt.Println("verified sign") + return nil } diff --git a/core/quorum_initiator.go b/core/quorum_initiator.go index f6c05b4a..57b93cc2 100644 --- a/core/quorum_initiator.go +++ b/core/quorum_initiator.go @@ -225,6 +225,7 @@ func (c *Core) sendQuorumCredit(cr *ConensusRequest) { } func (c *Core) initiateConsensus(cr *ConensusRequest, sc *contract.Contract, dc did.DIDCrypto) (*wallet.TransactionDetails, map[string]map[string]float64, error) { + fmt.Println("consensus initiated") cs := ConsensusStatus{ Credit: CreditScore{ Credit: make([]CreditSignature, 0), @@ -268,6 +269,12 @@ func (c *Core) initiateConsensus(cr *ConensusRequest, sc *contract.Contract, dc tid := util.HexToStr(util.CalculateHash(sc.GetBlock(), "SHA3-256")) lastCharTID := string(tid[len(tid)-1]) + //the last-char "1" of the new transaction id represents the light-mode of the signature + if dc.GetSignVersion() == did.PkiVersion { + tid = tid + "1" + fmt.Println("tid is ", tid) + } + ql := c.qm.GetQuorum(cr.Type, lastCharTID) //passing lastCharTID as a parameter. Made changes in GetQuorum function to take 2 arguments if ql == nil || len(ql) < MinQuorumRequired { c.log.Error("Failed to get required quorums") diff --git a/core/quorum_recv.go b/core/quorum_recv.go index 74e0260a..d1461b4b 100644 --- a/core/quorum_recv.go +++ b/core/quorum_recv.go @@ -37,16 +37,21 @@ func (c *Core) creditStatus(req *ensweb.Request) *ensweb.Result { } func (c *Core) verifyContract(cr *ConensusRequest) (bool, *contract.Contract) { + fmt.Println("entered verifyContract") sc := contract.InitContract(cr.ContractBlock, nil) + fmt.Println("contract initiated") // setup the did to verify the signature dc, err := c.SetupForienDID(sc.GetSenderDID()) + fmt.Println("did set up done") if err != nil { c.log.Error("Failed to get DID", "err", err) return false, nil } + fmt.Println("will verify signature") err = sc.VerifySignature(dc) + fmt.Println("signature verified") if err != nil { - c.log.Error("Failed to verify sender signature", "err", err) + c.log.Error("Failed to verify sender signature in verifyContract", "err", err) return false, nil } return true, sc @@ -104,15 +109,19 @@ func (c *Core) quorumDTConsensus(req *ensweb.Request, did string, qdc didcrypto. } func (c *Core) quorumRBTConsensus(req *ensweb.Request, did string, qdc didcrypto.DIDCrypto, cr *ConensusRequest) *ensweb.Result { + fmt.Println("entered quorumRBTConsensus") crep := ConensusReply{ ReqID: cr.ReqID, Status: false, } + fmt.Println("will verify contract") ok, sc := c.verifyContract(cr) + fmt.Println("contract verification done") if !ok { crep.Message = "Failed to verify sender signature" return c.l.RenderJSON(req, &crep, http.StatusOK) } + fmt.Println("verified contract") //check if token has multiple pins ti := sc.GetTransTokenInfo() results := make([]MultiPinCheckRes, len(ti)) @@ -485,6 +494,7 @@ func (c *Core) quorumConensus(req *ensweb.Request) *ensweb.Result { switch cr.Mode { case RBTTransferMode: c.log.Debug("RBT consensus started") + // fmt.Println(req, "/n", did, "/n", qdc, "/n", &cr) return c.quorumRBTConsensus(req, did, qdc, &cr) case DTCommitMode: c.log.Debug("Data consensus started") diff --git a/did/basic.go b/did/basic.go index d3f83290..208a7cbb 100644 --- a/did/basic.go +++ b/did/basic.go @@ -63,8 +63,14 @@ func (d *DIDBasic) GetDID() string { return d.did } +func (d *DIDBasic) GetSignVersion() int { + fmt.Println("NlssVersion") + return NlssVersion +} + // Sign will return the singature of the DID func (d *DIDBasic) Sign(hash string) ([]byte, []byte, error) { + fmt.Println("nlss sign in basic mode") byteImg, err := util.GetPNGImagePixels(d.dir + PvtShareFileName) if err != nil { @@ -108,6 +114,7 @@ func (d *DIDBasic) Sign(hash string) ([]byte, []byte, error) { // Sign will verifyt he signature func (d *DIDBasic) Verify(hash string, pvtShareSig []byte, pvtKeySIg []byte) (bool, error) { + fmt.Println("verifying sign from basic mode") // read senderDID didImg, err := util.GetPNGImagePixels(d.dir + DIDImgFileName) if err != nil { @@ -160,6 +167,7 @@ func (d *DIDBasic) Verify(hash string, pvtShareSig []byte, pvtKeySIg []byte) (bo } func (d *DIDBasic) PvtSign(hash []byte) ([]byte, error) { + fmt.Println("pvt signing in basic mode") privKey, err := ioutil.ReadFile(d.dir + PvtKeyFileName) if err != nil { return nil, err @@ -179,6 +187,7 @@ func (d *DIDBasic) PvtSign(hash []byte) ([]byte, error) { return pvtKeySign, nil } func (d *DIDBasic) PvtVerify(hash []byte, sign []byte) (bool, error) { + fmt.Println("verifying pvt sign from basic mode") pubKey, err := ioutil.ReadFile(d.dir + PubKeyFileName) if err != nil { return false, err diff --git a/did/child.go b/did/child.go index 229a8afd..7159ed05 100644 --- a/did/child.go +++ b/did/child.go @@ -64,6 +64,10 @@ func (d *DIDChild) GetDID() string { return d.did } +func (d *DIDChild) GetSignVersion() int { + return NlssVersion +} + // Sign will return the singature of the DID func (d *DIDChild) Sign(hash string) ([]byte, []byte, error) { diff --git a/did/did.go b/did/did.go index c10e7936..501391c5 100644 --- a/did/did.go +++ b/did/did.go @@ -38,6 +38,7 @@ type DID struct { type DIDCrypto interface { GetDID() string + GetSignVersion() int Sign(hash string) ([]byte, []byte, error) Verify(hash string, didSig []byte, pvtSig []byte) (bool, error) PvtSign(hash []byte) ([]byte, error) diff --git a/did/light.go b/did/light.go index 92388729..ad9a3a75 100644 --- a/did/light.go +++ b/did/light.go @@ -1,12 +1,13 @@ package did import ( - // "bytes" + "bytes" "fmt" "io/ioutil" "time" "github.com/rubixchain/rubixgoplatform/crypto" + "github.com/rubixchain/rubixgoplatform/nlss" "github.com/rubixchain/rubixgoplatform/util" ) @@ -55,6 +56,7 @@ func (d *DIDLight) getPassword() (string, error) { return "", fmt.Errorf("Invalid data received on the channel") } d.pwd = srd.Password + fmt.Println("getting pwd in light mode") return d.pwd, nil } @@ -62,25 +64,94 @@ func (d *DIDLight) GetDID() string { return d.did } +func (d *DIDLight) GetSignVersion() int { + fmt.Println("PkiVersion") + return PkiVersion +} + func (d *DIDLight) Sign(hash string) ([]byte, []byte, error) { pvtKeySign, err := d.PvtSign([]byte(hash)) bs := []byte{} + fmt.Println("pki sign in light mode") + fmt.Println("signing data:", hash) return bs, pvtKeySign, err } + +func (d *DIDLight) Verify(hash string, pvtShareSig []byte, pvtKeySIg []byte) (bool, error) { + fmt.Println("verifying nlss sign from light mode") + // if signVersion == PkiVersion { + // return d.PvtVerify([]byte(hash), pvtKeySIg) + // } else { + // read senderDID + didImg, err := util.GetPNGImagePixels(d.dir + DIDImgFileName) + if err != nil { + return false, err + } + pubImg, err := util.GetPNGImagePixels(d.dir + PubShareFileName) + + if err != nil { + return false, err + } + + pSig := util.BytesToBitstream(pvtShareSig) + + ps := util.StringToIntArray(pSig) + + didBin := util.ByteArraytoIntArray(didImg) + pubBin := util.ByteArraytoIntArray(pubImg) + pubPos := util.RandomPositions("verifier", hash, 32, ps) + pubPosInt := util.GetPrivatePositions(pubPos.PosForSign, pubBin) + pubStr := util.IntArraytoStr(pubPosInt) + orgPos := make([]int, len(pubPos.OriginalPos)) + for i := range pubPos.OriginalPos { + orgPos[i] = pubPos.OriginalPos[i] / 8 + } + didPosInt := util.GetPrivatePositions(orgPos, didBin) + didStr := util.IntArraytoStr(didPosInt) + cb := nlss.Combine2Shares(nlss.ConvertBitString(pSig), nlss.ConvertBitString(pubStr)) + + db := nlss.ConvertBitString(didStr) + + if !bytes.Equal(cb, db) { + return false, fmt.Errorf("failed to verify") + } + + //create a signature using the private key + //1. read and extrqct the private key + pubKey, err := ioutil.ReadFile(d.dir + PubKeyFileName) + if err != nil { + return false, err + } + _, pubKeyByte, err := crypto.DecodeKeyPair("", nil, pubKey) + if err != nil { + return false, err + } + hashPvtSign := util.HexToStr(util.CalculateHash([]byte(pSig), "SHA3-256")) + if !crypto.Verify(pubKeyByte, []byte(hashPvtSign), pvtKeySIg) { + return false, fmt.Errorf("failed to verify private key singature") + } + return true, nil + // } + +} + func (d *DIDLight) PvtSign(hash []byte) ([]byte, error) { privKey, err := ioutil.ReadFile(d.dir + PvtKeyFileName) if err != nil { return nil, err } + fmt.Println("pvt sign in light mode") pwd, err := d.getPassword() if err != nil { return nil, err } + fmt.Println("got pwd in light mode") PrivateKey, _, err := crypto.DecodeKeyPair(pwd, privKey, nil) if err != nil { return nil, err } + fmt.Println("pvt key decoded in light mode") pvtKeySign, err := crypto.Sign(PrivateKey, hash) if err != nil { return nil, err @@ -88,10 +159,10 @@ func (d *DIDLight) PvtSign(hash []byte) ([]byte, error) { return pvtKeySign, nil } -func (d *DIDLight) Verify(hash string, pvtShareSig []byte, pvtKeySIg []byte) (bool, error) { - return d.PvtVerify([]byte(hash), pvtKeySIg) -} func (d *DIDLight) PvtVerify(hash []byte, sign []byte) (bool, error) { + fmt.Println("verifying pvt sign from light mode") + fmt.Println("verifying data:", hash) + fmt.Println("verifying sign:", sign) pubKey, err := ioutil.ReadFile(d.dir + PubKeyFileName) if err != nil { return false, err diff --git a/did/model.go b/did/model.go index 49aef460..85688c85 100644 --- a/did/model.go +++ b/did/model.go @@ -8,6 +8,11 @@ const ( ChildDIDMode ) +const ( + PkiVersion int = iota + NlssVersion +) + const ( ImgFileName string = "image.png" DIDImgFileName string = "did.png" @@ -48,6 +53,10 @@ type DIDSignature struct { Signature []byte } +// type Sign_Version struct { +// Version int `json:"version"` +// } + type SignReqData struct { ID string `json:"id"` Mode int `json:"mode"` diff --git a/did/quorum.go b/did/quorum.go index 3542f5e7..480dc107 100644 --- a/did/quorum.go +++ b/did/quorum.go @@ -48,6 +48,10 @@ func (d *DIDQuorum) GetDID() string { return d.did } +func (d *DIDQuorum) GetSignVersion() int { + return NlssVersion +} + // Sign will return the singature of the DID func (d *DIDQuorum) Sign(hash string) ([]byte, []byte, error) { if d.privKey == nil { diff --git a/did/standard.go b/did/standard.go index ecb2466d..2d65cfa0 100644 --- a/did/standard.go +++ b/did/standard.go @@ -55,6 +55,10 @@ func (d *DIDStandard) GetDID() string { return d.did } +func (d *DIDStandard) GetSignVersion() int { + return NlssVersion +} + // Sign will return the singature of the DID func (d *DIDStandard) Sign(hash string) ([]byte, []byte, error) { byteImg, err := util.GetPNGImagePixels(d.dir + PvtShareFileName) diff --git a/did/wallet.go b/did/wallet.go index 1a07f8c0..e451d862 100644 --- a/did/wallet.go +++ b/did/wallet.go @@ -56,6 +56,10 @@ func (d *DIDWallet) GetDID() string { return d.did } +func (d *DIDWallet) GetSignVersion() int { + return NlssVersion +} + // Sign will return the singature of the DID func (d *DIDWallet) Sign(hash string) ([]byte, []byte, error) { bs, pvtKeySign, err := d.getSignature([]byte(hash), false) diff --git a/rac/rac.go b/rac/rac.go index 44b5b9cb..51226fb1 100644 --- a/rac/rac.go +++ b/rac/rac.go @@ -221,14 +221,17 @@ func (r *RacBlock) GetRacMap() map[string]interface{} { } func (r *RacBlock) UpdateSignature(dc didmodule.DIDCrypto) error { + fmt.Println("updating signature") ha, err := r.GetHash() if err != nil { return err } + fmt.Println("got hash") sig, err := dc.PvtSign([]byte(ha)) if err != nil { return err } + fmt.Println("got pvt sig") r.bm[RacSignKey] = util.HexToStr(sig) return r.blkEncode() } From 99cdbf16d03363d3724a9459828cfb512293a961 Mon Sep 17 00:00:00 2001 From: Maneesha-rubix Date: Tue, 30 Jan 2024 20:54:52 +0530 Subject: [PATCH 08/62] succesful testRBT transfer in light mode --- block/block.go | 34 +++------ client/did.go | 48 ++++--------- contract/contract.go | 68 ++++++++---------- core/migrate.go | 31 ++------- core/part_token.go | 10 +-- core/quorum_initiator.go | 7 -- core/quorum_recv.go | 9 --- core/token_pin_check.go | 2 +- core/wallet/token_test.go | 2 +- crypto/BIP39.go | 120 ++++++++++++++++++++++++++++++++ did/basic.go | 9 +-- did/child.go | 2 +- did/did.go | 140 ++++++++++++++++++++------------------ did/dummy.go | 2 +- did/light.go | 23 ++----- did/model.go | 16 ++--- did/quorum.go | 30 +++----- did/standard.go | 2 +- did/wallet.go | 2 +- go.mod | 2 + go.sum | 12 ++++ grpcserver/did.go | 17 +---- rac/rac.go | 3 - server/did.go | 27 +------- 24 files changed, 302 insertions(+), 316 deletions(-) create mode 100644 crypto/BIP39.go diff --git a/block/block.go b/block/block.go index 06b34bb6..44e5eaee 100644 --- a/block/block.go +++ b/block/block.go @@ -171,10 +171,6 @@ func (b *Block) blkDecode() error { } hb := util.CalculateHash(bc.([]byte), "SHA3-256") - // sigVersion := make([]byte, 1) - // sigVersion[0] = byte(1) - // new_hb := append(hb, sigVersion...) - var tcb map[string]interface{} err = cbor.Unmarshal(bc.([]byte), &tcb) if err != nil { @@ -188,7 +184,14 @@ func (b *Block) blkDecode() error { } tcb[TCSignatureKey] = ksb } + + //appending 1 to the block hash to signify PKI-sign-version + // sigVersion := make([]byte, 1) + // sigVersion[0] = byte(1) + // new_hb := append(hb, sigVersion...) + tcb[TCBlockHashKey] = util.HexToStr(hb) + b.bm = tcb return nil } @@ -208,11 +211,14 @@ func (b *Block) blkEncode() error { return err } hb := util.CalculateHash(bc, "SHA3-256") + + //appending 1 to the block hash to signify PKI-sign-version // sigVersion := make([]byte, 1) // sigVersion[0] = byte(1) // new_hb := append(hb, sigVersion...) b.bm[TCBlockHashKey] = util.HexToStr(hb) + m := make(map[string]interface{}) m[TCBlockContentKey] = bc if sok { @@ -326,6 +332,7 @@ func (b *Block) GetSigner() ([]string, error) { func (b *Block) GetHashSig(did string) (string, string, error) { h, ok := b.bm[TCBlockHashKey] + if !ok { return "", "", fmt.Errorf("invalid token chain block, missing block hash") } @@ -640,25 +647,6 @@ func (b *Block) GetCommitedTokenDetials(t string) ([]string, error) { return nil, nil } -// func (b *Block) GetTokenPledgeMap() map[string]interface{} { -// tokenPledge := b.bm[TCTokensPledgeMapKey] -// tokenPledgeMap, ok := tokenPledge.(map[interface{}]interface{}) -// if !ok { -// return nil -// } - -// result := make(map[string]interface{}) -// for k, v := range tokenPledgeMap { -// kStr, kOk := k.(string) -// if !kOk { -// return nil -// } -// result[kStr] = v -// } - -// return result -// } - func (b *Block) GetSmartContractData() string { return b.getBlkString(TCSmartContractDataKey) } diff --git a/client/did.go b/client/did.go index 64dd6a32..20e183e8 100644 --- a/client/did.go +++ b/client/did.go @@ -57,9 +57,7 @@ func (c *Client) CreateDID(cfg *did.DIDCreate) (string, bool) { util.Filecopy(cfg.PubKeyFile, did.PubKeyFileName) cfg.PubKeyFile = did.PubKeyFileName } - cfg.ImgFile = "" - cfg.DIDImgFileName = "" - cfg.PubImgFile = "" + case did.BasicDIDMode: if cfg.ImgFile == "" { c.log.Error("Image file requried") @@ -131,15 +129,7 @@ func (c *Client) CreateDID(cfg *did.DIDCreate) (string, bool) { fields := make(map[string]string) fields[setup.DIDConfigField] = string(jd) files := make(map[string]string) - if cfg.ImgFile != "" { - files["image"] = cfg.ImgFile - } - if cfg.DIDImgFileName != "" { - files["did_image"] = cfg.DIDImgFileName - } - if cfg.PubImgFile != "" { - files["pub_image"] = cfg.PubImgFile - } + if cfg.PubKeyFile != "" { files["pub_key"] = cfg.PubKeyFile } @@ -161,25 +151,24 @@ func (c *Client) SetupDID(dc *did.DIDCreate) (string, bool) { if dc.Type < did.LightDIDMode && dc.Type > did.WalletDIDMode { return "Invalid DID mode", false } - if !strings.Contains(dc.PubImgFile, did.PubShareFileName) || - !strings.Contains(dc.DIDImgFileName, did.DIDImgFileName) || - !strings.Contains(dc.PubKeyFile, did.PubKeyFileName) || - !strings.Contains(dc.QuorumPubKeyFile, did.QuorumPubKeyFileName) || - !strings.Contains(dc.QuorumPrivKeyFile, did.QuorumPvtKeyFileName) { - return "Required files are missing", false - } + switch dc.Type { case did.LightDIDMode: - if !strings.Contains(dc.PrivKeyFile, did.PvtKeyFileName) { + if !strings.Contains(dc.PubKeyFile, did.PubKeyFileName) || + !strings.Contains(dc.PrivKeyFile, did.PvtKeyFileName) { return "Required files are missing", false } case did.BasicDIDMode: if !strings.Contains(dc.PrivImgFile, did.PvtShareFileName) || + !strings.Contains(dc.PubImgFile, did.PubShareFileName) || + !strings.Contains(dc.DIDImgFileName, did.DIDImgFileName) || !strings.Contains(dc.PrivKeyFile, did.PvtKeyFileName) { return "Required files are missing", false } case did.StandardDIDMode: - if !strings.Contains(dc.PrivImgFile, did.PvtShareFileName) { + if !strings.Contains(dc.PubImgFile, did.PubShareFileName) || + !strings.Contains(dc.DIDImgFileName, did.DIDImgFileName) || + !strings.Contains(dc.PrivImgFile, did.PvtShareFileName) { return "Required files are missing", false } } @@ -191,27 +180,14 @@ func (c *Client) SetupDID(dc *did.DIDCreate) (string, bool) { fields := make(map[string]string) fields[setup.DIDConfigField] = string(jd) files := make(map[string]string) - if dc.PubImgFile != "" { - files["pub_image"] = dc.PubImgFile - } - if dc.DIDImgFileName != "" { - files["did_image"] = dc.DIDImgFileName - } - if dc.PrivImgFile != "" { - files["priv_image"] = dc.PrivImgFile - } + if dc.PubKeyFile != "" { files["pub_key"] = dc.PubKeyFile } if dc.PrivKeyFile != "" { files["priv_key"] = dc.PrivKeyFile } - if dc.QuorumPubKeyFile != "" { - files["quorum_pub_key"] = dc.QuorumPubKeyFile - } - if dc.QuorumPrivKeyFile != "" { - files["quorum_priv_key"] = dc.QuorumPrivKeyFile - } + var br model.BasicResponse err = c.sendMutiFormRequest("POST", setup.APISetupDID, nil, fields, files, &br) if err != nil { diff --git a/contract/contract.go b/contract/contract.go index 56ad429a..e0ee8dac 100644 --- a/contract/contract.go +++ b/contract/contract.go @@ -105,7 +105,13 @@ func (c *Contract) blkDecode() error { if err != nil { return err } - tcb[SCBlockHashKey] = util.HexToStr(hb) + + //appending 1 to the block hash to signify PKI-sign-version + sigVersion := make([]byte, 1) + sigVersion[0] = byte(1) + new_hb := append(hb, sigVersion...) + + tcb[SCBlockHashKey] = util.HexToStr(new_hb) if sok { var ksb map[string]interface{} err = cbor.Unmarshal(ssi.([]byte), &ksb) @@ -148,7 +154,13 @@ func (c *Contract) blkEncode() error { return err } hb := util.CalculateHash(bc, "SHA3-256") - c.sm[SCBlockHashKey] = util.HexToStr(hb) + + //appending 1 to the block hash to signify PKI-sign-version + sigVersion := make([]byte, 1) + sigVersion[0] = byte(1) + new_hb := append(hb, sigVersion...) + + c.sm[SCBlockHashKey] = util.HexToStr(new_hb) m := make(map[string]interface{}) m[SCBlockContentKey] = bc if ssok { @@ -215,28 +227,22 @@ func (c *Contract) GetType() uint64 { } func (c *Contract) GetHashSig(did string) (string, string, string, error) { - fmt.Println("entered GetHashSig") hi, ok := c.sm[SCBlockHashKey] - fmt.Println("fetched blockhash key from db", hi) if !ok { return "", "", "", fmt.Errorf("invalid smart contract, hash block is missing") } ssi, ok := c.sm[SCShareSignatureKey] - fmt.Println("fetched share sign key from db", ssi) if !ok { return "", "", "", fmt.Errorf("invalid smart contract, share signature block is missing") } ksi, ok := c.sm[SCKeySignatureKey] - fmt.Println("fetched pvt sign key from db", ksi) if !ok { return "", "", "", fmt.Errorf("invalid smart contract, key signature block is missing") } ss := util.GetStringFromMap(ssi, did) - fmt.Println("fetched share sign from db", ss) ks := util.GetStringFromMap(ksi, did) - fmt.Println("fetched pvt sign from db", ks) // ss == "" || if ks == "" { return "", "", "", fmt.Errorf("invalid smart contract, share/key signature block is missing") @@ -384,25 +390,16 @@ func (c *Contract) GetCommitedTokensInfo() []TokenInfo { } func (c *Contract) UpdateSignature(dc did.DIDCrypto) error { - fmt.Println("updating signature") did := dc.GetDID() hash, err := c.GetHash() if err != nil { return fmt.Errorf("Failed to get hash of smart contract, " + err.Error()) } - fmt.Println("calling sign function") - ssig, psig, _ := dc.Sign(hash) - hs, _, _, _ := c.GetHashSig(did) - ok, err := dc.PvtVerify([]byte(hs), psig) + ssig, psig, err := dc.Sign(hash) if err != nil { - return err - } - if !ok { - return fmt.Errorf("did signature verification failed line 401") + return fmt.Errorf("Failed to get signature, " + err.Error()) } - // if err != nil { - // return fmt.Errorf("Failed to get signature, " + err.Error()) - // } + if c.sm[SCShareSignatureKey] == nil { ksm := make(map[string]interface{}) ksm[did] = util.HexToStr(ssig) @@ -445,43 +442,36 @@ func (c *Contract) UpdateSignature(dc did.DIDCrypto) error { } func (c *Contract) VerifySignature(dc did.DIDCrypto) error { - fmt.Println("entered VerifySignature") did := dc.GetDID() - fmt.Println("got did") hs, ss, ps, err := c.GetHashSig(did) - fmt.Println("got hash sig") - fmt.Println(hs) - fmt.Println(ss) - fmt.Println(util.StrToHex(ps)) - fmt.Println(err) + if err != nil { c.log.Error("err", err) return err } - fmt.Println("getting sign version") - sign_vers := dc.GetSignVersion() - fmt.Println("calling verify func") - fmt.Println(sign_vers) - // switch sign_vers {} - if ss != "" { - ok, err := dc.Verify(hs, util.StrToHex(ss), util.StrToHex(ps)) + + //check if the the last char of the block hash is 1 + // lastCharHs := string(hs[len(hs)-1]) + // fmt.Println("block hash with last char 1:", hs) + + if ss == "" { + ok, err := dc.PvtVerify([]byte(hs), util.StrToHex(ps)) + if err != nil { return err } if !ok { - return fmt.Errorf("did signature verification failed") + return fmt.Errorf("did Pki signature verification failed") } } else { - ok, err := dc.PvtVerify([]byte(hs), util.StrToHex(ps)) + ok, err := dc.NlssVerify(hs, util.StrToHex(ss), util.StrToHex(ps)) if err != nil { return err } if !ok { - return fmt.Errorf("did signature verification failed") + return fmt.Errorf("did Nlss signature verification failed") } } - fmt.Println("verified sign") - return nil } diff --git a/core/migrate.go b/core/migrate.go index cd5fda66..3cb9a0b9 100644 --- a/core/migrate.go +++ b/core/migrate.go @@ -158,25 +158,12 @@ func (c *Core) migrateNode(reqID string, m *MigrateRequest, didDir string) error } if !resume { didCreate := didm.DIDCreate{ - Dir: didDir, - Type: m.DIDType, - PrivPWD: m.PrivPWD, - QuorumPWD: m.QuorumPWD, - DIDImgFileName: rubixDir + "DATA/" + d[0].DID + "/DID.png", - PubImgFile: rubixDir + "DATA/" + d[0].DID + "/PublicShare.png", - PrivImgFile: rubixDir + "DATA/" + d[0].DID + "/PrivateShare.png", + Dir: didDir, + Type: m.DIDType, + PrivPWD: m.PrivPWD, + QuorumPWD: m.QuorumPWD, } - _, err = os.Stat(didCreate.DIDImgFileName) - if err != nil { - c.log.Error("Failed to migrate, missing DID.png file", "err", err) - return fmt.Errorf("failed to migrate, missing DID.png file") - } - _, err = os.Stat(didCreate.PubImgFile) - if err != nil { - c.log.Error("Failed to migrate, missing PublicShare.png file", "err", err) - return fmt.Errorf("failed to migrate, missing PublicShare.png file") - } did, err = c.d.MigrateDID(&didCreate) if err != nil { c.log.Error("Failed to migrate, failed in creation of new DID address", "err", err, "msg", did) @@ -646,15 +633,7 @@ func (c *Core) migrateNode(reqID string, m *MigrateRequest, didDir string) error fp.Close() } } - // if len(migrateTokens) > 0 { - // fp, err := os.Open("migratedtokens.txt") - // if err == nil { - // for i := range migrateTokens { - // fp.WriteString(migrateTokens[i]) - // } - // fp.Close() - // } - // } + creditFiles, err := util.GetAllFiles(rubixDir + "Wallet/WALLET_DATA/Credits/") if err != nil { c.log.Error("Failed to migrate, failed to read credit files", "err", err) diff --git a/core/part_token.go b/core/part_token.go index 4e8e19a1..db5a5360 100644 --- a/core/part_token.go +++ b/core/part_token.go @@ -75,7 +75,7 @@ func (c *Core) GetTokens(dc did.DIDCrypto, did string, value float64) ([]wallet. return wt, nil } if rem < 1 { - for i := range pt { + for i, _ := range pt { if pt[i].TokenValue == rem { wt = append(wt, pt[i]) pt = append(pt[:i], pt[i+1:]...) @@ -86,7 +86,7 @@ func (c *Core) GetTokens(dc did.DIDCrypto, did string, value float64) ([]wallet. } idx := make([]int, 0) rpt := make([]wallet.Token, 0) - for i := range pt { + for i, _ := range pt { if pt[i].TokenValue <= rem { wt = append(wt, pt[i]) rem = floatPrecision(rem-pt[i].TokenValue, 10) @@ -157,7 +157,7 @@ func (c *Core) createPartToken(dc did.DIDCrypto, did string, tkn string, parts [ // check part split not crossing RBT amount := float64(0) - for i := range parts { + for i, _ := range parts { amount = amount + parts[i] amount = floatPrecision(amount, 10) if amount > t.TokenValue { @@ -181,7 +181,7 @@ func (c *Core) createPartToken(dc did.DIDCrypto, did string, tkn string, parts [ c.log.Error("failed to get parent detials", "err", err) return nil, err } - for i := range parts { + for i, _ := range parts { rt := &rac.RacType{ Type: c.RACPartTokenType(), DID: did, @@ -288,7 +288,7 @@ func (c *Core) createPartToken(dc did.DIDCrypto, did string, tkn string, parts [ return nil, err } npt := make([]wallet.Token, 0) - for i := range parts { + for i, _ := range parts { ptkn := &wallet.Token{ TokenID: pts[i], ParentTokenID: tkn, diff --git a/core/quorum_initiator.go b/core/quorum_initiator.go index 57b93cc2..f6c05b4a 100644 --- a/core/quorum_initiator.go +++ b/core/quorum_initiator.go @@ -225,7 +225,6 @@ func (c *Core) sendQuorumCredit(cr *ConensusRequest) { } func (c *Core) initiateConsensus(cr *ConensusRequest, sc *contract.Contract, dc did.DIDCrypto) (*wallet.TransactionDetails, map[string]map[string]float64, error) { - fmt.Println("consensus initiated") cs := ConsensusStatus{ Credit: CreditScore{ Credit: make([]CreditSignature, 0), @@ -269,12 +268,6 @@ func (c *Core) initiateConsensus(cr *ConensusRequest, sc *contract.Contract, dc tid := util.HexToStr(util.CalculateHash(sc.GetBlock(), "SHA3-256")) lastCharTID := string(tid[len(tid)-1]) - //the last-char "1" of the new transaction id represents the light-mode of the signature - if dc.GetSignVersion() == did.PkiVersion { - tid = tid + "1" - fmt.Println("tid is ", tid) - } - ql := c.qm.GetQuorum(cr.Type, lastCharTID) //passing lastCharTID as a parameter. Made changes in GetQuorum function to take 2 arguments if ql == nil || len(ql) < MinQuorumRequired { c.log.Error("Failed to get required quorums") diff --git a/core/quorum_recv.go b/core/quorum_recv.go index d1461b4b..00a306d0 100644 --- a/core/quorum_recv.go +++ b/core/quorum_recv.go @@ -37,19 +37,14 @@ func (c *Core) creditStatus(req *ensweb.Request) *ensweb.Result { } func (c *Core) verifyContract(cr *ConensusRequest) (bool, *contract.Contract) { - fmt.Println("entered verifyContract") sc := contract.InitContract(cr.ContractBlock, nil) - fmt.Println("contract initiated") // setup the did to verify the signature dc, err := c.SetupForienDID(sc.GetSenderDID()) - fmt.Println("did set up done") if err != nil { c.log.Error("Failed to get DID", "err", err) return false, nil } - fmt.Println("will verify signature") err = sc.VerifySignature(dc) - fmt.Println("signature verified") if err != nil { c.log.Error("Failed to verify sender signature in verifyContract", "err", err) return false, nil @@ -109,19 +104,15 @@ func (c *Core) quorumDTConsensus(req *ensweb.Request, did string, qdc didcrypto. } func (c *Core) quorumRBTConsensus(req *ensweb.Request, did string, qdc didcrypto.DIDCrypto, cr *ConensusRequest) *ensweb.Result { - fmt.Println("entered quorumRBTConsensus") crep := ConensusReply{ ReqID: cr.ReqID, Status: false, } - fmt.Println("will verify contract") ok, sc := c.verifyContract(cr) - fmt.Println("contract verification done") if !ok { crep.Message = "Failed to verify sender signature" return c.l.RenderJSON(req, &crep, http.StatusOK) } - fmt.Println("verified contract") //check if token has multiple pins ti := sc.GetTransTokenInfo() results := make([]MultiPinCheckRes, len(ti)) diff --git a/core/token_pin_check.go b/core/token_pin_check.go index c7c519e3..ce7c9a04 100644 --- a/core/token_pin_check.go +++ b/core/token_pin_check.go @@ -113,7 +113,7 @@ func (c *Core) pinCheck(token string, index int, senderPeerId string, receiverPe } } - for peerId, _ := range peerIdRolemap { + for peerId := range peerIdRolemap { if peerIdRolemap[peerId] == wallet.OwnerRole { c.log.Error("Token has multiple Pins") result.Status = true diff --git a/core/wallet/token_test.go b/core/wallet/token_test.go index 237ff76b..1fd7b90c 100644 --- a/core/wallet/token_test.go +++ b/core/wallet/token_test.go @@ -49,7 +49,7 @@ func (d *DIDDummy) Sign(hash string) ([]byte, []byte, error) { } // Sign will verifyt he signature -func (d *DIDDummy) Verify(hash string, pvtShareSig []byte, pvtKeySIg []byte) (bool, error) { +func (d *DIDDummy) NlssVerify(hash string, pvtShareSig []byte, pvtKeySIg []byte) (bool, error) { // read senderDID _, pubKeyByte, err := crypto.DecodeKeyPair("", nil, d.pubKey) diff --git a/crypto/BIP39.go b/crypto/BIP39.go new file mode 100644 index 00000000..72fd7454 --- /dev/null +++ b/crypto/BIP39.go @@ -0,0 +1,120 @@ +package crypto + +import ( + "crypto" + "crypto/ecdsa" + "crypto/rand" + "encoding/pem" + "fmt" + + "github.com/tyler-smith/go-bip32" + "github.com/tyler-smith/go-bip39" +) + +const ( + BIP39 = iota +) + +// Generate child private and public keys for BIP39 masterkey and given path +// The child private key is regenerated on demand from master key hence never stored +// The child public key need to shared with other peers for verification +// Make sure the path of child is also stored along with public key +func BIPGenerateChild(masterKey string, childPath int) ([]byte, []byte, error) { + var privateKeyBytes []byte + var publicKeyBytes []byte + masterKeybip32, err := bip32.B58Deserialize(masterKey) + if err != nil { + return nil, nil, err + } + privateKey, err := masterKeybip32.NewChildKey(uint32(childPath)) + if err != nil { + return nil, nil, err + } + publicKey := privateKey.PublicKey() + privateKeyBytes = privateKey.Key + publicKeyBytes = publicKey.Key + return privateKeyBytes, publicKeyBytes, nil +} + +// Generate BIPMasterKey from Mnemonic and user provided password +// Useful in key recovery / device migration through mnemonics +func BIPGenerateMasterKeyFromMnemonic(mnemonic string, pwd string) ([]byte, error) { + var masterkeySeralise string + seed := bip39.NewSeed(mnemonic, pwd) + masterKey, _ := bip32.NewMasterKey(seed) + masterkeySeralise = masterKey.B58Serialize() + var pemEncPriv []byte + if pwd != "" { + encBlock, err := Seal(pwd, []byte(masterkeySeralise)) + if err != nil { + return nil, err + } + _, err = UnSeal(pwd, encBlock) + if err != nil { + return nil, err + } + pemEncPriv = pem.EncodeToMemory(&pem.Block{Type: "ENCRYPTED PRIVATE KEY", Bytes: encBlock}) + } else { + pemEncPriv = pem.EncodeToMemory(&pem.Block{Type: "PRIVATE KEY", Bytes: []byte(masterkeySeralise)}) + } + return pemEncPriv, nil +} + +// Generate a random BIP mnemonic in rubix +func BIPGenerateMnemonic() string { + entropy, _ := bip39.NewEntropy(256) + mnemonic, _ := bip39.NewMnemonic(entropy) + return mnemonic +} + +// Generate a Bip32 HD wallet MasteKey for the mnemonic and a user provided randomness +// here we are reusing the password used for sealing masterkey as source of randomness also +func BIPGenerateMasterKey(cfg *CryptoConfig) ([]byte, error) { + var pemEncPriv []byte + var err error + if cfg.Alg == 0 { + mnemonic := BIPGenerateMnemonic() + pemEncPriv, err = BIPGenerateMasterKeyFromMnemonic(mnemonic, cfg.Pwd) + if err != nil { + return nil, err + } + } else { + return nil, fmt.Errorf("unsupported algorithm") + } + return pemEncPriv, nil +} + +// Decode the master public key +func BIPDecodeMasterKey(pwd string, privKey []byte) ([]byte, error) { + var cryptoPrivKey []byte + var err error + if privKey != nil { + pemBlock, _ := pem.Decode(privKey) + if pemBlock == nil { + return nil, fmt.Errorf("invalid private key") + } + if pemBlock.Type == "ENCRYPTED PRIVATE KEY" { + if pwd == "" { + return nil, fmt.Errorf("key is encrypted need password to decrypt") + } + cryptoPrivKey, err = UnSeal(pwd, pemBlock.Bytes) + if err != nil { + return nil, fmt.Errorf("key is invalid or password is wrong") + } + } + } + return cryptoPrivKey, nil +} + +func BIPSign(priv PrivateKey, data []byte) ([]byte, error) { + return priv.(crypto.Signer).Sign(rand.Reader, data, crypto.SHA256) +} + +func BIPVerify(pub PublicKey, data []byte, sig []byte) bool { + switch pub.(type) { + case *ecdsa.PublicKey: + return ecdsa.VerifyASN1(pub.(*ecdsa.PublicKey), data, sig) + default: + return false + } +} diff --git a/did/basic.go b/did/basic.go index 208a7cbb..39ac4fe2 100644 --- a/did/basic.go +++ b/did/basic.go @@ -64,13 +64,12 @@ func (d *DIDBasic) GetDID() string { } func (d *DIDBasic) GetSignVersion() int { - fmt.Println("NlssVersion") return NlssVersion } // Sign will return the singature of the DID func (d *DIDBasic) Sign(hash string) ([]byte, []byte, error) { - fmt.Println("nlss sign in basic mode") + // fmt.Println("nlss sign in basic mode") byteImg, err := util.GetPNGImagePixels(d.dir + PvtShareFileName) if err != nil { @@ -113,8 +112,7 @@ func (d *DIDBasic) Sign(hash string) ([]byte, []byte, error) { } // Sign will verifyt he signature -func (d *DIDBasic) Verify(hash string, pvtShareSig []byte, pvtKeySIg []byte) (bool, error) { - fmt.Println("verifying sign from basic mode") +func (d *DIDBasic) NlssVerify(hash string, pvtShareSig []byte, pvtKeySIg []byte) (bool, error) { // read senderDID didImg, err := util.GetPNGImagePixels(d.dir + DIDImgFileName) if err != nil { @@ -167,7 +165,7 @@ func (d *DIDBasic) Verify(hash string, pvtShareSig []byte, pvtKeySIg []byte) (bo } func (d *DIDBasic) PvtSign(hash []byte) ([]byte, error) { - fmt.Println("pvt signing in basic mode") + // fmt.Println("pvt signing in basic mode") privKey, err := ioutil.ReadFile(d.dir + PvtKeyFileName) if err != nil { return nil, err @@ -187,7 +185,6 @@ func (d *DIDBasic) PvtSign(hash []byte) ([]byte, error) { return pvtKeySign, nil } func (d *DIDBasic) PvtVerify(hash []byte, sign []byte) (bool, error) { - fmt.Println("verifying pvt sign from basic mode") pubKey, err := ioutil.ReadFile(d.dir + PubKeyFileName) if err != nil { return false, err diff --git a/did/child.go b/did/child.go index 7159ed05..47fc7d15 100644 --- a/did/child.go +++ b/did/child.go @@ -117,7 +117,7 @@ func (d *DIDChild) Sign(hash string) ([]byte, []byte, error) { } // Sign will verifyt he signature -func (d *DIDChild) Verify(hash string, pvtShareSig []byte, pvtKeySIg []byte) (bool, error) { +func (d *DIDChild) NlssVerify(hash string, pvtShareSig []byte, pvtKeySIg []byte) (bool, error) { rb, err := ioutil.ReadFile(d.dir + MasterDIDFileName) if err != nil { return false, err diff --git a/did/did.go b/did/did.go index 501391c5..262239be 100644 --- a/did/did.go +++ b/did/did.go @@ -1,6 +1,7 @@ package did import ( + "bytes" "context" "encoding/json" "errors" @@ -40,7 +41,7 @@ type DIDCrypto interface { GetDID() string GetSignVersion() int Sign(hash string) ([]byte, []byte, error) - Verify(hash string, didSig []byte, pvtSig []byte) (bool, error) + NlssVerify(hash string, didSig []byte, pvtSig []byte) (bool, error) PvtSign(hash []byte) ([]byte, error) PvtVerify(hash []byte, sign []byte) (bool, error) } @@ -70,11 +71,14 @@ func (d *DID) CreateDID(didCreate *DIDCreate) (string, error) { return "", err } + //In light mode, did is simply the SHA-256 hash of the public key if didCreate.Type == LightDIDMode { if didCreate.PrivPWD == "" { d.log.Error("password required for creating", "err", err) return "", err } + + //generating private and public key pair pvtKey, pubKey, err := crypto.GenerateKeyPair(&crypto.CryptoConfig{Alg: crypto.ECDSAP256, Pwd: didCreate.PrivPWD}) if err != nil { d.log.Error("failed to create keypair", "err", err) @@ -90,6 +94,13 @@ func (d *DID) CreateDID(didCreate *DIDCreate) (string, error) { if err != nil { return "", err } + if didCreate.QuorumPWD == "" { + if didCreate.PrivPWD != "" { + didCreate.QuorumPWD = didCreate.PrivPWD + } else { + didCreate.QuorumPWD = DefaultPWD + } + } } @@ -192,12 +203,6 @@ func (d *DID) CreateDID(didCreate *DIDCreate) (string, error) { return "", err } - } else { - _, err := util.Filecopy(didCreate.PubKeyFile, dirName+"/public/"+PubKeyFileName) - if err != nil { - d.log.Error("failed to copy pub key", "err", err) - return "", err - } } if didCreate.Type == ChildDIDMode { @@ -208,30 +213,9 @@ func (d *DID) CreateDID(didCreate *DIDCreate) (string, error) { if err != nil { return "", err } - } else { - if didCreate.QuorumPWD == "" { - if didCreate.PrivPWD != "" { - didCreate.QuorumPWD = didCreate.PrivPWD - } else { - didCreate.QuorumPWD = DefaultPWD - } - } - - pvtKey, pubKey, err := crypto.GenerateKeyPair(&crypto.CryptoConfig{Alg: crypto.ECDSAP256, Pwd: didCreate.QuorumPWD}) - if err != nil { - d.log.Error("failed to create keypair", "err", err) - return "", err - } - err = util.FileWrite(dirName+"/private/"+QuorumPvtKeyFileName, pvtKey) - if err != nil { - return "", err - } - err = util.FileWrite(dirName+"/public/"+QuorumPubKeyFileName, pubKey) - if err != nil { - return "", err - } } + //passing the diroctory of public key file to add it to ipfs and exctract the hash did, err := d.getDirHash(dirName + "/public/") if err != nil { return "", err @@ -279,21 +263,6 @@ func (d *DID) MigrateDID(didCreate *DIDCreate) (string, error) { return "", err } - _, err = util.Filecopy(didCreate.DIDImgFileName, dirName+"/public/"+DIDImgFileName) - if err != nil { - d.log.Error("failed to copy did image", "err", err) - return "", err - } - _, err = util.Filecopy(didCreate.PubImgFile, dirName+"/public/"+PubShareFileName) - if err != nil { - d.log.Error("failed to copy public share", "err", err) - return "", err - } - _, err = util.Filecopy(didCreate.PrivImgFile, dirName+"/private/"+PvtShareFileName) - if err != nil { - d.log.Error("failed to copy private share key", "err", err) - return "", err - } if didCreate.Type == BasicDIDMode { if didCreate.PrivKeyFile == "" || didCreate.PubKeyFile == "" { if didCreate.PrivPWD == "" { @@ -340,30 +309,6 @@ func (d *DID) MigrateDID(didCreate *DIDCreate) (string, error) { didCreate.QuorumPWD = DefaultPWD } } - if didCreate.QuorumPrivKeyFile == "" || didCreate.QuorumPubKeyFile == "" { - pvtKey, pubKey, err := crypto.GenerateKeyPair(&crypto.CryptoConfig{Alg: crypto.ECDSAP256, Pwd: didCreate.QuorumPWD}) - if err != nil { - d.log.Error("failed to create keypair", "err", err) - return "", err - } - err = util.FileWrite(dirName+"/private/"+QuorumPvtKeyFileName, pvtKey) - if err != nil { - return "", err - } - err = util.FileWrite(dirName+"/public/"+QuorumPubKeyFileName, pubKey) - if err != nil { - return "", err - } - } else { - _, err = util.Filecopy(didCreate.QuorumPrivKeyFile, dirName+"/private/"+QuorumPvtKeyFileName) - if err != nil { - return "", err - } - _, err = util.Filecopy(didCreate.QuorumPubKeyFile, dirName+"/public/"+QuorumPubKeyFileName) - if err != nil { - return "", err - } - } did, err := d.getDirHash(dirName + "/public/") if err != nil { @@ -400,21 +345,76 @@ type object struct { Hash string } +// This function takes file content as input, adds it to IPFS, +// without creating a physical file in the file system, and exctracts the hash +func (d *DID) addFileToIPFS(fileData []byte) (string, error) { + fmt.Println("calculating ipfs hash") + // Create a reader for the file data + reader := bytes.NewReader(fileData) + + // Send a request to IPFS to add the file data + resp, err := d.ipfs.Request("add"). + Option("cid-version", 1). + Option("hash", "sha3-256"). + Body(reader). + Send(context.Background()) + if err != nil { + return "", err + } + defer resp.Close() + + // Check for errors in the response + if resp.Error != nil { + return "", resp.Error + } + defer resp.Output.Close() + + // Decode the JSON response and extract the hash + dec := json.NewDecoder(resp.Output) + var final string + for { + var out object + err = dec.Decode(&out) + if err != nil { + if err == io.EOF { + break + } + return "", err + } + final = out.Hash + } + + // Check if the final hash is empty + if final == "" { + return "", errors.New("no results received") + } + + return final, nil +} + +// Calculate the hash of a directory using IPFS func (d *DID) getDirHash(dir string) (string, error) { + // Get information about the directory stat, err := os.Lstat(dir) if err != nil { return "", err } + // Create a new SerialFile using the directory information sf, err := files.NewSerialFile(dir, false, stat) if err != nil { return "", err } defer sf.Close() + + // Create a new SliceDirectory with the SerialFile slf := files.NewSliceDirectory([]files.DirEntry{files.FileEntry(filepath.Base(dir), sf)}) defer slf.Close() + + // Create a MultiFileReader with the SliceDirectory reader := files.NewMultiFileReader(slf, true) + // Send a request to IPFS to add the directory resp, err := d.ipfs.Request("add"). Option("recursive", true). Option("cid-version", 1). @@ -427,10 +427,13 @@ func (d *DID) getDirHash(dir string) (string, error) { defer resp.Close() + // Check for errors in the response if resp.Error != nil { return "", resp.Error } defer resp.Output.Close() + + // Decode the JSON response and extract the hash dec := json.NewDecoder(resp.Output) var final string for { @@ -445,6 +448,7 @@ func (d *DID) getDirHash(dir string) (string, error) { final = out.Hash } + // Check if the final hash is empty if final == "" { return "", errors.New("no results received") } diff --git a/did/dummy.go b/did/dummy.go index be1b1667..4b098ac0 100644 --- a/did/dummy.go +++ b/did/dummy.go @@ -40,7 +40,7 @@ func (d *DIDDummy) Sign(hash string) ([]byte, []byte, error) { } // Sign will verifyt he signature -func (d *DIDDummy) Verify(hash string, pvtShareSig []byte, pvtKeySIg []byte) (bool, error) { +func (d *DIDDummy) NlssVerify(hash string, pvtShareSig []byte, pvtKeySIg []byte) (bool, error) { // read senderDID _, pubKeyByte, err := crypto.DecodeKeyPair("", nil, d.pubKey) diff --git a/did/light.go b/did/light.go index ad9a3a75..d1e2f2d3 100644 --- a/did/light.go +++ b/did/light.go @@ -56,7 +56,6 @@ func (d *DIDLight) getPassword() (string, error) { return "", fmt.Errorf("Invalid data received on the channel") } d.pwd = srd.Password - fmt.Println("getting pwd in light mode") return d.pwd, nil } @@ -65,25 +64,21 @@ func (d *DIDLight) GetDID() string { } func (d *DIDLight) GetSignVersion() int { - fmt.Println("PkiVersion") return PkiVersion } +// PKI based sign in light mode func (d *DIDLight) Sign(hash string) ([]byte, []byte, error) { pvtKeySign, err := d.PvtSign([]byte(hash)) bs := []byte{} - fmt.Println("pki sign in light mode") - fmt.Println("signing data:", hash) + // fmt.Println("pki sign in light mode") return bs, pvtKeySign, err } -func (d *DIDLight) Verify(hash string, pvtShareSig []byte, pvtKeySIg []byte) (bool, error) { - fmt.Println("verifying nlss sign from light mode") - // if signVersion == PkiVersion { - // return d.PvtVerify([]byte(hash), pvtKeySIg) - // } else { - // read senderDID +// verify nlss based signatures +func (d *DIDLight) NlssVerify(hash string, pvtShareSig []byte, pvtKeySIg []byte) (bool, error) { + //read senderDID didImg, err := util.GetPNGImagePixels(d.dir + DIDImgFileName) if err != nil { return false, err @@ -132,7 +127,6 @@ func (d *DIDLight) Verify(hash string, pvtShareSig []byte, pvtKeySIg []byte) (bo return false, fmt.Errorf("failed to verify private key singature") } return true, nil - // } } @@ -141,17 +135,14 @@ func (d *DIDLight) PvtSign(hash []byte) ([]byte, error) { if err != nil { return nil, err } - fmt.Println("pvt sign in light mode") pwd, err := d.getPassword() if err != nil { return nil, err } - fmt.Println("got pwd in light mode") PrivateKey, _, err := crypto.DecodeKeyPair(pwd, privKey, nil) if err != nil { return nil, err } - fmt.Println("pvt key decoded in light mode") pvtKeySign, err := crypto.Sign(PrivateKey, hash) if err != nil { return nil, err @@ -159,10 +150,8 @@ func (d *DIDLight) PvtSign(hash []byte) ([]byte, error) { return pvtKeySign, nil } +// Verify PKI based signature func (d *DIDLight) PvtVerify(hash []byte, sign []byte) (bool, error) { - fmt.Println("verifying pvt sign from light mode") - fmt.Println("verifying data:", hash) - fmt.Println("verifying sign:", sign) pubKey, err := ioutil.ReadFile(d.dir + PubKeyFileName) if err != nil { return false, err diff --git a/did/model.go b/did/model.go index 85688c85..509d67cc 100644 --- a/did/model.go +++ b/did/model.go @@ -14,15 +14,13 @@ const ( ) const ( - ImgFileName string = "image.png" - DIDImgFileName string = "did.png" - MasterDIDFileName string = "master.txt" - PvtShareFileName string = "pvtShare.png" - PubShareFileName string = "pubShare.png" - PvtKeyFileName string = "pvtKey.pem" - PubKeyFileName string = "pubKey.pem" - QuorumPvtKeyFileName string = "quorumPrivKey.pem" - QuorumPubKeyFileName string = "quorumPubKey.pem" + ImgFileName string = "image.png" + DIDImgFileName string = "did.png" + MasterDIDFileName string = "master.txt" + PvtShareFileName string = "pvtShare.png" + PubShareFileName string = "pubShare.png" + PvtKeyFileName string = "pvtKey.pem" + PubKeyFileName string = "pubKey.pem" ) const ( diff --git a/did/quorum.go b/did/quorum.go index 480dc107..90492739 100644 --- a/did/quorum.go +++ b/did/quorum.go @@ -23,7 +23,7 @@ type DIDQuorum struct { func InitDIDQuorumc(did string, baseDir string, pwd string) *DIDQuorum { d := &DIDQuorum{did: did, dir: util.SanitizeDirPath(baseDir) + did + "/", pwd: pwd} if d.pwd != "" { - privKey, err := ioutil.ReadFile(d.dir + QuorumPvtKeyFileName) + privKey, err := ioutil.ReadFile(d.dir + PvtKeyFileName) if err != nil { return nil } @@ -33,7 +33,7 @@ func InitDIDQuorumc(did string, baseDir string, pwd string) *DIDQuorum { } } - pubKey, err := ioutil.ReadFile(d.dir + QuorumPubKeyFileName) + pubKey, err := ioutil.ReadFile(d.dir + PubKeyFileName) if err != nil { return nil } @@ -49,7 +49,7 @@ func (d *DIDQuorum) GetDID() string { } func (d *DIDQuorum) GetSignVersion() int { - return NlssVersion + return PkiVersion } // Sign will return the singature of the DID @@ -57,34 +57,20 @@ func (d *DIDQuorum) Sign(hash string) ([]byte, []byte, error) { if d.privKey == nil { return nil, nil, fmt.Errorf("private key is not initialized") } - byteImg, err := util.GetPNGImagePixels(d.dir + PvtShareFileName) + pvtKeySign, err := d.PvtSign([]byte(hash)) + // byteImg, err := util.GetPNGImagePixels(d.dir + PvtShareFileName) if err != nil { fmt.Println(err) return nil, nil, err } - ps := util.ByteArraytoIntArray(byteImg) - - randPosObject := util.RandomPositions("signer", hash, 32, ps) - - finalPos := randPosObject.PosForSign - pvtPos := util.GetPrivatePositions(finalPos, ps) - pvtPosStr := util.IntArraytoStr(pvtPos) - hashPvtSign := util.HexToStr(util.CalculateHash([]byte(pvtPosStr), "SHA3-256")) - pvtKeySign, err := crypto.Sign(d.privKey, []byte(hashPvtSign)) - if err != nil { - return nil, nil, err - } - bs, err := util.BitstreamToBytes(pvtPosStr) - if err != nil { - return nil, nil, err - } + bs := []byte{} return bs, pvtKeySign, err } -// Sign will verifyt he signature -func (d *DIDQuorum) Verify(hash string, pvtShareSig []byte, pvtKeySIg []byte) (bool, error) { +// verify the quorum's nlss based signature +func (d *DIDQuorum) NlssVerify(hash string, pvtShareSig []byte, pvtKeySIg []byte) (bool, error) { // read senderDID didImg, err := util.GetPNGImagePixels(d.dir + DIDImgFileName) if err != nil { diff --git a/did/standard.go b/did/standard.go index 2d65cfa0..561a168e 100644 --- a/did/standard.go +++ b/did/standard.go @@ -88,7 +88,7 @@ func (d *DIDStandard) Sign(hash string) ([]byte, []byte, error) { } // Sign will verifyt he signature -func (d *DIDStandard) Verify(hash string, pvtShareSig []byte, pvtKeySIg []byte) (bool, error) { +func (d *DIDStandard) NlssVerify(hash string, pvtShareSig []byte, pvtKeySIg []byte) (bool, error) { // read senderDID didImg, err := util.GetPNGImagePixels(d.dir + DIDImgFileName) if err != nil { diff --git a/did/wallet.go b/did/wallet.go index e451d862..85941bdf 100644 --- a/did/wallet.go +++ b/did/wallet.go @@ -70,7 +70,7 @@ func (d *DIDWallet) Sign(hash string) ([]byte, []byte, error) { } // Sign will verifyt he signature -func (d *DIDWallet) Verify(hash string, pvtShareSig []byte, pvtKeySIg []byte) (bool, error) { +func (d *DIDWallet) NlssVerify(hash string, pvtShareSig []byte, pvtKeySIg []byte) (bool, error) { // read senderDID didImg, err := util.GetPNGImagePixels(d.dir + DIDImgFileName) if err != nil { diff --git a/go.mod b/go.mod index 1c8877bd..703aa0b3 100644 --- a/go.mod +++ b/go.mod @@ -47,6 +47,8 @@ require ( github.com/stretchr/testify v1.8.3 // indirect github.com/swaggo/files v1.0.0 // indirect github.com/swaggo/http-swagger v1.3.4 + github.com/tyler-smith/go-bip32 v1.0.0 // indirect + github.com/tyler-smith/go-bip39 v1.1.0 // indirect github.com/whyrusleeping/tar-utils v0.0.0-20201201191210-20a61371de5b // indirect golang.org/x/net v0.10.0 golang.org/x/tools v0.9.3 // indirect diff --git a/go.sum b/go.sum index f090b70a..5ce22340 100644 --- a/go.sum +++ b/go.sum @@ -606,6 +606,10 @@ github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03 github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= github.com/EnsurityTechnologies/helper v1.0.0 h1:x6kaCFvqH35/P8eD8Vkx/IUUkbvDqyh4KVwqDJWIfWA= github.com/EnsurityTechnologies/helper v1.0.0/go.mod h1:KESBOBjgzlkimm3dDwr49wjbMXWtaoqrA3SiwhxGDwQ= +github.com/FactomProject/basen v0.0.0-20150613233007-fe3947df716e h1:ahyvB3q25YnZWly5Gq1ekg6jcmWaGj/vG/MhF4aisoc= +github.com/FactomProject/basen v0.0.0-20150613233007-fe3947df716e/go.mod h1:kGUqhHd//musdITWjFvNTHn90WG9bMLBEPQZ17Cmlpw= +github.com/FactomProject/btcutilecc v0.0.0-20130527213604-d3a63a5752ec h1:1Qb69mGp/UtRPn422BH4/Y4Q3SLUrD9KHuDkm8iodFc= +github.com/FactomProject/btcutilecc v0.0.0-20130527213604-d3a63a5752ec/go.mod h1:CD8UlnlLDiqb36L110uqiP2iSflVjx9g/3U9hCI4q2U= github.com/JohnCGriffin/overflow v0.0.0-20211019200055-46fa312c352c/go.mod h1:X0CRv0ky0k6m906ixxpzmDRLvX58TFUKS2eePweuyxk= github.com/KyleBanks/depth v1.2.1 h1:5h8fQADFrWtarTdtDudMmGsC7GPbOAu6RVB3ffsVFHc= github.com/KyleBanks/depth v1.2.1/go.mod h1:jzSb9d0L43HxTQfT+oSA1EEp2q+ne2uh6XgeJcm8brE= @@ -662,6 +666,7 @@ github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWR github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= +github.com/cmars/basen v0.0.0-20150613233007-fe3947df716e/go.mod h1:P13beTBKr5Q18lJe1rIoLUqjM+CB1zYrRg44ZqGuQSA= github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= github.com/cncf/udpa/go v0.0.0-20200629203442-efcf912fb354/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= @@ -1085,6 +1090,7 @@ github.com/spf13/afero v1.9.2/go.mod h1:iUV7ddyEEZPO5gA3zD4fJt6iStLlL+Lg4m2cihcD github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= +github.com/stretchr/testify v1.1.5-0.20170601210322-f6abca593680/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= @@ -1106,6 +1112,10 @@ github.com/swaggo/swag v1.16.1 h1:fTNRhKstPKxcnoKsytm4sahr8FaYzUcT7i1/3nd/fBg= github.com/swaggo/swag v1.16.1/go.mod h1:9/LMvHycG3NFHfR6LwvikHv5iFvmPADQ359cKikGxto= github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7 h1:epCh84lMvA70Z7CTTCmYQn2CKbY8j86K7/FAIr141uY= github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7/go.mod h1:q4W45IWZaF22tdD+VEXcAWRA037jwmWEB5VWYORlTpc= +github.com/tyler-smith/go-bip32 v1.0.0 h1:sDR9juArbUgX+bO/iblgZnMPeWY1KZMUC2AFUJdv5KE= +github.com/tyler-smith/go-bip32 v1.0.0/go.mod h1:onot+eHknzV4BVPwrzqY5OoVpyCvnwD7lMawL5aQupE= +github.com/tyler-smith/go-bip39 v1.1.0 h1:5eUemwrMargf3BSLRRCalXT93Ns6pQJIjYQN2nyfOP8= +github.com/tyler-smith/go-bip39 v1.1.0/go.mod h1:gUYDtqQw1JS3ZJ8UWVcGTGqqr6YIN3CWg+kkNaLt55U= github.com/urfave/cli/v2 v2.3.0/go.mod h1:LJmUH05zAU44vOAcrfzZQKsZbVcdbOG8rtL3/XcUArI= github.com/whyrusleeping/tar-utils v0.0.0-20180509141711-8c6c8ba81d5c/go.mod h1:xxcJeBb7SIUl/Wzkz1eVKJE/CB34YNrqX2TQI6jY9zs= github.com/whyrusleeping/tar-utils v0.0.0-20201201191210-20a61371de5b h1:wA3QeTsaAXybLL2kb2cKhCAQTHgYTMwuI8lBlJSv5V8= @@ -1132,6 +1142,7 @@ go.opencensus.io v0.23.0/go.mod h1:XItmlyltB5F7CS4xOC1DcqMoFqwtC6OG2xF7mCv7P7E= go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo= go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI= go.opentelemetry.io/proto/otlp v0.15.0/go.mod h1:H7XAot3MsfNsj7EXtrA2q5xSNQ10UqI405h3+duxN4U= +golang.org/x/crypto v0.0.0-20170613210332-850760c427c5/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20170930174604-9419663f5a44/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190325154230-a5d413f7728c/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= @@ -1838,6 +1849,7 @@ honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= honnef.co/go/tools v0.1.3/go.mod h1:NgwopIslSNH47DimFoV78dnkksY2EFtX0ajyb3K/las= +launchpad.net/gocheck v0.0.0-20140225173054-000000000087/go.mod h1:hj7XX3B/0A+80Vse0e+BUHsHMTEhd0O4cpUHr/e/BUM= lukechampine.com/blake3 v1.1.6 h1:H3cROdztr7RCfoaTpGZFQsrqvweFLrqS73j7L7cmR5c= lukechampine.com/blake3 v1.1.6/go.mod h1:tkKEOtDkNtklkXtLNEOGNq5tcV90tJiA1vAA12R78LA= lukechampine.com/uint128 v1.1.1/go.mod h1:c4eWIwlEGaxC/+H1VguhU4PHXNWDCDMUlWdIWl2j1gk= diff --git a/grpcserver/did.go b/grpcserver/did.go index 62e3bca2..ca5ab2da 100644 --- a/grpcserver/did.go +++ b/grpcserver/did.go @@ -84,22 +84,7 @@ func (rn *RubixNative) CreateDID(ctx context.Context, req *protos.CreateDIDReq) return nil, status.Errorf(codes.Internal, "failed to create folder") } defer os.RemoveAll(folderName) - if req.DidImage != "" { - err = createFile(folderName+"/"+did.DIDImgFileName, req.DidImage, true) - if err != nil { - rn.log.Error(err.Error()) - return nil, status.Errorf(codes.Internal, err.Error()) - } - dc.ImgFile = folderName + "/" + did.DIDImgFileName - } - if req.PublicShare != "" { - err = createFile(folderName+"/"+did.PubShareFileName, req.PublicShare, true) - if err != nil { - rn.log.Error(err.Error()) - return nil, status.Errorf(codes.Internal, err.Error()) - } - dc.PubImgFile = folderName + "/" + did.PubShareFileName - } + if req.PublicKey != "" { err = createFile(folderName+"/"+did.PubKeyFileName, req.PublicKey, false) if err != nil { diff --git a/rac/rac.go b/rac/rac.go index 51226fb1..44b5b9cb 100644 --- a/rac/rac.go +++ b/rac/rac.go @@ -221,17 +221,14 @@ func (r *RacBlock) GetRacMap() map[string]interface{} { } func (r *RacBlock) UpdateSignature(dc didmodule.DIDCrypto) error { - fmt.Println("updating signature") ha, err := r.GetHash() if err != nil { return err } - fmt.Println("got hash") sig, err := dc.PvtSign([]byte(ha)) if err != nil { return err } - fmt.Println("got pvt sig") r.bm[RacSignKey] = util.HexToStr(sig) return r.blkEncode() } diff --git a/server/did.go b/server/did.go index 8373b257..2bbffaac 100644 --- a/server/did.go +++ b/server/did.go @@ -62,15 +62,7 @@ func (s *Server) APICreateDID(req *ensweb.Request) *ensweb.Result { } for _, fileName := range fileNames { - if strings.Contains(fileName, did.ImgFileName) { - didCreate.ImgFile = fileName - } - if strings.Contains(fileName, did.DIDImgFileName) { - didCreate.DIDImgFileName = fileName - } - if strings.Contains(fileName, did.PubShareFileName) { - didCreate.PubImgFile = fileName - } + if strings.Contains(fileName, did.PubKeyFileName) { didCreate.PubKeyFile = fileName } @@ -199,27 +191,14 @@ func (s *Server) APISetupDID(req *ensweb.Request) *ensweb.Result { } for _, fileName := range fileNames { - if strings.Contains(fileName, did.DIDImgFileName) { - didCreate.DIDImgFileName = fileName - } - if strings.Contains(fileName, did.PubShareFileName) { - didCreate.PubImgFile = fileName - } - if strings.Contains(fileName, did.PvtShareFileName) { - didCreate.PrivImgFile = fileName - } + if strings.Contains(fileName, did.PvtKeyFileName) { didCreate.PrivKeyFile = fileName } if strings.Contains(fileName, did.PubKeyFileName) { didCreate.PubKeyFile = fileName } - if strings.Contains(fileName, did.QuorumPvtKeyFileName) { - didCreate.QuorumPrivKeyFile = fileName - } - if strings.Contains(fileName, did.QuorumPubKeyFileName) { - didCreate.QuorumPubKeyFile = fileName - } + } dir, ok := s.validateAccess(req) if !ok { From 31e07b67248cc11d5da73fc7d82b42eb807c0b77 Mon Sep 17 00:00:00 2001 From: ashi31 Date: Thu, 1 Feb 2024 19:48:50 +0530 Subject: [PATCH 09/62] Adding readme and updated printing format --- README.md | 31 +++++++++++++++++++++++++++++++ command/explorer.go | 5 +++++ 2 files changed, 36 insertions(+) diff --git a/README.md b/README.md index 7817a9d8..a4491eae 100644 --- a/README.md +++ b/README.md @@ -311,4 +311,35 @@ This following options are used for this command Server/Host port (default "20000") -fp Force password to be entered on the terminal +``` +To Add explorer url +: To add explorer url where to send the transaction data. +``` +./rubixgoplatform addexplorer + +This following options are used for this command + -links string + URLs, mutiple URLs will be seprated by comma + -port string + Server/Host port (default "20000") +``` +To remove explorer url +: To remove explorer url where not to send the transaction data. +``` +./rubixgoplatform removeexplorer + +This following options are used for this command + -links string + URLs, mutiple URLs will be seprated by comma + -port string + Server/Host port (default "20000") +``` +To get all explorer urls +: To get explorer urls where the transaction data is being sent. +``` +./rubixgoplatform getallexplorer + +This following options are used for this command + -port string + Server/Host port (default "20000") ``` \ No newline at end of file diff --git a/command/explorer.go b/command/explorer.go index 871d5012..01b1552b 100644 --- a/command/explorer.go +++ b/command/explorer.go @@ -1,5 +1,7 @@ package command +import "fmt" + func (cmd *Command) addExplorer() { if len(cmd.links) == 0 { cmd.log.Error("links required for Explorer") @@ -34,5 +36,8 @@ func (cmd *Command) getAllExplorer() { } else { cmd.log.Info("Get all Explorer command finished, " + msg) cmd.log.Info("Explorer links", "links", links) + for i, q := range links { + fmt.Printf("URL %d: %s\n", i, q) + } } } From 43cc355607f5989f5e760e88c7593a0e5892aac1 Mon Sep 17 00:00:00 2001 From: Maneesha-rubix Date: Fri, 2 Feb 2024 18:05:25 +0530 Subject: [PATCH 10/62] sign version added --- README.md | 2 +- block/block.go | 10 ---------- block/transaction.go | 6 +++++- contract/contract.go | 25 ++++++++----------------- core/core.go | 2 +- core/quorum_initiator.go | 10 +++++++++- did/basic.go | 2 -- did/light.go | 3 ++- 8 files changed, 26 insertions(+), 34 deletions(-) diff --git a/README.md b/README.md index 7817a9d8..b2dc757b 100644 --- a/README.md +++ b/README.md @@ -102,7 +102,7 @@ This following options are used for this command -port string Server/Host port (default "20000") -didType int - DID type (0-Basic Mode, 1-Standard Mode, 2-Wallet Mode) (default 0) + DID type (0-Light Mode, 1-Basic Mode, 2-Standard Mode, 3-Wallet Mode) (default 0) -didSecret string DID secret (default "My DID Secret") -privPWD string diff --git a/block/block.go b/block/block.go index 44e5eaee..89f4c452 100644 --- a/block/block.go +++ b/block/block.go @@ -185,11 +185,6 @@ func (b *Block) blkDecode() error { tcb[TCSignatureKey] = ksb } - //appending 1 to the block hash to signify PKI-sign-version - // sigVersion := make([]byte, 1) - // sigVersion[0] = byte(1) - // new_hb := append(hb, sigVersion...) - tcb[TCBlockHashKey] = util.HexToStr(hb) b.bm = tcb @@ -212,11 +207,6 @@ func (b *Block) blkEncode() error { } hb := util.CalculateHash(bc, "SHA3-256") - //appending 1 to the block hash to signify PKI-sign-version - // sigVersion := make([]byte, 1) - // sigVersion[0] = byte(1) - // new_hb := append(hb, sigVersion...) - b.bm[TCBlockHashKey] = util.HexToStr(hb) m := make(map[string]interface{}) diff --git a/block/transaction.go b/block/transaction.go index a5f98857..4cc6068b 100644 --- a/block/transaction.go +++ b/block/transaction.go @@ -43,6 +43,7 @@ const ( TIDeployerDIDKey string = "8" TIExecutorDIDKey string = "9" TICommitedTokensKey string = "10" + // TISignVersionKey string = "11" ) const ( @@ -78,7 +79,7 @@ type TransInfo struct { Tokens []TransTokens `json:"tokens"` DeployerDID string `json:"deployerDID"` ExecutorDID string `json:"executorDID"` - // SignVersion int `json:"signVersion"` + // SignVersion string `json:"signVersion"` } func newTransToken(b *Block, tt *TransTokens) map[string]interface{} { @@ -142,6 +143,9 @@ func newTransInfo(ctcb map[string]*Block, ti *TransInfo) map[string]interface{} if ti.RefID != "" { ntib[TIRefIDKey] = ti.RefID } + // if ti.SignVersion != "" { + // ntib[TISignVersionKey] = ti.SignVersion + // } nttbs := make(map[string]interface{}) for _, tt := range ti.Tokens { b := ctcb[tt.Token] diff --git a/contract/contract.go b/contract/contract.go index e0ee8dac..7403703b 100644 --- a/contract/contract.go +++ b/contract/contract.go @@ -106,12 +106,7 @@ func (c *Contract) blkDecode() error { return err } - //appending 1 to the block hash to signify PKI-sign-version - sigVersion := make([]byte, 1) - sigVersion[0] = byte(1) - new_hb := append(hb, sigVersion...) - - tcb[SCBlockHashKey] = util.HexToStr(new_hb) + tcb[SCBlockHashKey] = util.HexToStr(hb) if sok { var ksb map[string]interface{} err = cbor.Unmarshal(ssi.([]byte), &ksb) @@ -155,12 +150,7 @@ func (c *Contract) blkEncode() error { } hb := util.CalculateHash(bc, "SHA3-256") - //appending 1 to the block hash to signify PKI-sign-version - sigVersion := make([]byte, 1) - sigVersion[0] = byte(1) - new_hb := append(hb, sigVersion...) - - c.sm[SCBlockHashKey] = util.HexToStr(new_hb) + c.sm[SCBlockHashKey] = util.HexToStr(hb) m := make(map[string]interface{}) m[SCBlockContentKey] = bc if ssok { @@ -441,19 +431,20 @@ func (c *Contract) UpdateSignature(dc did.DIDCrypto) error { return c.blkEncode() } +// This function is used by the quorums to verify sender's signature func (c *Contract) VerifySignature(dc did.DIDCrypto) error { + //fetch sender's did did := dc.GetDID() - hs, ss, ps, err := c.GetHashSig(did) + //fetch sender's signature + hs, ss, ps, err := c.GetHashSig(did) if err != nil { c.log.Error("err", err) return err } - //check if the the last char of the block hash is 1 - // lastCharHs := string(hs[len(hs)-1]) - // fmt.Println("block hash with last char 1:", hs) - + //If the ss i.e., share signature is empty, then its a Pki sign, so call PvtVerify + //Else it is NLSS based sign, so call NlssVerify if ss == "" { ok, err := dc.PvtVerify([]byte(hs), util.StrToHex(ps)) diff --git a/core/core.go b/core/core.go index 8ee62b4f..82863882 100644 --- a/core/core.go +++ b/core/core.go @@ -524,7 +524,7 @@ func (c *Core) SetupForienDID(didStr string) (did.DIDCrypto, error) { if err != nil { return nil, err } - return did.InitDIDBasic(didStr, c.didDir, nil), nil + return did.InitDIDLight(didStr, c.didDir, nil), nil } func (c *Core) SetupForienDIDQuorum(didStr string) (did.DIDCrypto, error) { diff --git a/core/quorum_initiator.go b/core/quorum_initiator.go index f6c05b4a..9ff09b07 100644 --- a/core/quorum_initiator.go +++ b/core/quorum_initiator.go @@ -169,7 +169,7 @@ func (c *Core) SetupQuorum(didStr string, pwd string, pvtKeyPwd string) error { } c.qc[didStr] = dc if pvtKeyPwd != "" { - dc := did.InitDIDBasicWithPassword(didStr, c.didDir, pvtKeyPwd) + dc := did.InitDIDLightWithPassword(didStr, c.didDir, pvtKeyPwd) if dc == nil { c.log.Error("Failed to setup quorum") return fmt.Errorf("failed to setup quorum") @@ -268,6 +268,14 @@ func (c *Core) initiateConsensus(cr *ConensusRequest, sc *contract.Contract, dc tid := util.HexToStr(util.CalculateHash(sc.GetBlock(), "SHA3-256")) lastCharTID := string(tid[len(tid)-1]) + //Fetching sign version + sigVers := dc.GetSignVersion() + + //Appending "1" at the beginning of Transaction ID as a symbol of PKI sign version + if sigVers == did.PkiVersion { + tid = "1" + tid + } + ql := c.qm.GetQuorum(cr.Type, lastCharTID) //passing lastCharTID as a parameter. Made changes in GetQuorum function to take 2 arguments if ql == nil || len(ql) < MinQuorumRequired { c.log.Error("Failed to get required quorums") diff --git a/did/basic.go b/did/basic.go index 39ac4fe2..397b5026 100644 --- a/did/basic.go +++ b/did/basic.go @@ -69,7 +69,6 @@ func (d *DIDBasic) GetSignVersion() int { // Sign will return the singature of the DID func (d *DIDBasic) Sign(hash string) ([]byte, []byte, error) { - // fmt.Println("nlss sign in basic mode") byteImg, err := util.GetPNGImagePixels(d.dir + PvtShareFileName) if err != nil { @@ -165,7 +164,6 @@ func (d *DIDBasic) NlssVerify(hash string, pvtShareSig []byte, pvtKeySIg []byte) } func (d *DIDBasic) PvtSign(hash []byte) ([]byte, error) { - // fmt.Println("pvt signing in basic mode") privKey, err := ioutil.ReadFile(d.dir + PvtKeyFileName) if err != nil { return nil, err diff --git a/did/light.go b/did/light.go index d1e2f2d3..ba61469c 100644 --- a/did/light.go +++ b/did/light.go @@ -63,6 +63,8 @@ func (d *DIDLight) GetDID() string { return d.did } +// When the did creation and signing is done in Light mode, +// this function returns the sign version as PkiVersion = 0 func (d *DIDLight) GetSignVersion() int { return PkiVersion } @@ -72,7 +74,6 @@ func (d *DIDLight) Sign(hash string) ([]byte, []byte, error) { pvtKeySign, err := d.PvtSign([]byte(hash)) bs := []byte{} - // fmt.Println("pki sign in light mode") return bs, pvtKeySign, err } From 7f28f4f65d2cd351bddf7074dc3f2ad9cf7023c8 Mon Sep 17 00:00:00 2001 From: Maneesha-rubix Date: Tue, 6 Feb 2024 13:08:48 +0530 Subject: [PATCH 11/62] comments added back --- block/block.go | 19 +++++++++++++++++++ core/migrate.go | 10 ++++++++++ 2 files changed, 29 insertions(+) diff --git a/block/block.go b/block/block.go index 89f4c452..4c49134c 100644 --- a/block/block.go +++ b/block/block.go @@ -637,6 +637,25 @@ func (b *Block) GetCommitedTokenDetials(t string) ([]string, error) { return nil, nil } +// func (b *Block) GetTokenPledgeMap() map[string]interface{} { +// tokenPledge := b.bm[TCTokensPledgeMapKey] +// tokenPledgeMap, ok := tokenPledge.(map[interface{}]interface{}) +// if !ok { +// return nil +// } + +// result := make(map[string]interface{}) +// for k, v := range tokenPledgeMap { +// kStr, kOk := k.(string) +// if !kOk { +// return nil +// } +// result[kStr] = v +// } + +// return result +// } + func (b *Block) GetSmartContractData() string { return b.getBlkString(TCSmartContractDataKey) } diff --git a/core/migrate.go b/core/migrate.go index 3cb9a0b9..a5ab5bd4 100644 --- a/core/migrate.go +++ b/core/migrate.go @@ -634,6 +634,16 @@ func (c *Core) migrateNode(reqID string, m *MigrateRequest, didDir string) error } } + // if len(migrateTokens) > 0 { + // fp, err := os.Open("migratedtokens.txt") + // if err == nil { + // for i := range migrateTokens { + // fp.WriteString(migrateTokens[i]) + // } + // fp.Close() + // } + // } + creditFiles, err := util.GetAllFiles(rubixDir + "Wallet/WALLET_DATA/Credits/") if err != nil { c.log.Error("Failed to migrate, failed to read credit files", "err", err) From b3e4b4ad2bbc1562b956e05de9e16dbaa0a5001e Mon Sep 17 00:00:00 2001 From: ashi31 Date: Tue, 6 Feb 2024 14:08:30 +0530 Subject: [PATCH 12/62] url prefix check --- core/explorer.go | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/core/explorer.go b/core/explorer.go index c4298837..a17eb8d4 100644 --- a/core/explorer.go +++ b/core/explorer.go @@ -3,6 +3,7 @@ package core import ( "fmt" "net/http" + "strings" "github.com/rubixchain/rubixgoplatform/core/storage" "github.com/rubixchain/rubixgoplatform/wrapper/config" @@ -210,7 +211,11 @@ func (c *Core) AddExplorer(links []string) error { var eurl []ExplorerURL for _, url := range links { - + if strings.HasPrefix(url, "https") { + url = strings.TrimPrefix(url, "https://") + } else if strings.HasPrefix(url, "http") { + url = strings.TrimPrefix(url, "http://") + } eur := ExplorerURL{ URL: url, Port: 0, @@ -227,8 +232,13 @@ func (c *Core) AddExplorer(links []string) error { func (c *Core) RemoveExplorer(links []string) error { - for _, link := range links { - err := c.s.Delete(ExplorerURLTable, &ExplorerURL{}, "url=?", link) + for _, url := range links { + if strings.HasPrefix(url, "https") { + url = strings.TrimPrefix(url, "https://") + } else if strings.HasPrefix(url, "http") { + url = strings.TrimPrefix(url, "http://") + } + err := c.s.Delete(ExplorerURLTable, &ExplorerURL{}, "url=?", url) if err != nil { return err From 0ee0b5bac586c6e8e6bfd40a523b97b5738bf6e3 Mon Sep 17 00:00:00 2001 From: Maneesha-rubix Date: Tue, 6 Feb 2024 14:39:35 +0530 Subject: [PATCH 13/62] removed a file --- crypto/BIP39.go | 120 ------------------------------------------------ 1 file changed, 120 deletions(-) delete mode 100644 crypto/BIP39.go diff --git a/crypto/BIP39.go b/crypto/BIP39.go deleted file mode 100644 index 72fd7454..00000000 --- a/crypto/BIP39.go +++ /dev/null @@ -1,120 +0,0 @@ -package crypto - -import ( - "crypto" - "crypto/ecdsa" - "crypto/rand" - "encoding/pem" - "fmt" - - "github.com/tyler-smith/go-bip32" - "github.com/tyler-smith/go-bip39" -) - -const ( - BIP39 = iota -) - -// Generate child private and public keys for BIP39 masterkey and given path -// The child private key is regenerated on demand from master key hence never stored -// The child public key need to shared with other peers for verification -// Make sure the path of child is also stored along with public key -func BIPGenerateChild(masterKey string, childPath int) ([]byte, []byte, error) { - var privateKeyBytes []byte - var publicKeyBytes []byte - masterKeybip32, err := bip32.B58Deserialize(masterKey) - if err != nil { - return nil, nil, err - } - privateKey, err := masterKeybip32.NewChildKey(uint32(childPath)) - if err != nil { - return nil, nil, err - } - publicKey := privateKey.PublicKey() - privateKeyBytes = privateKey.Key - publicKeyBytes = publicKey.Key - return privateKeyBytes, publicKeyBytes, nil -} - -// Generate BIPMasterKey from Mnemonic and user provided password -// Useful in key recovery / device migration through mnemonics -func BIPGenerateMasterKeyFromMnemonic(mnemonic string, pwd string) ([]byte, error) { - var masterkeySeralise string - seed := bip39.NewSeed(mnemonic, pwd) - masterKey, _ := bip32.NewMasterKey(seed) - masterkeySeralise = masterKey.B58Serialize() - var pemEncPriv []byte - if pwd != "" { - encBlock, err := Seal(pwd, []byte(masterkeySeralise)) - if err != nil { - return nil, err - } - _, err = UnSeal(pwd, encBlock) - if err != nil { - return nil, err - } - pemEncPriv = pem.EncodeToMemory(&pem.Block{Type: "ENCRYPTED PRIVATE KEY", Bytes: encBlock}) - } else { - pemEncPriv = pem.EncodeToMemory(&pem.Block{Type: "PRIVATE KEY", Bytes: []byte(masterkeySeralise)}) - } - return pemEncPriv, nil -} - -// Generate a random BIP mnemonic in rubix -func BIPGenerateMnemonic() string { - entropy, _ := bip39.NewEntropy(256) - mnemonic, _ := bip39.NewMnemonic(entropy) - return mnemonic -} - -// Generate a Bip32 HD wallet MasteKey for the mnemonic and a user provided randomness -// here we are reusing the password used for sealing masterkey as source of randomness also -func BIPGenerateMasterKey(cfg *CryptoConfig) ([]byte, error) { - var pemEncPriv []byte - var err error - if cfg.Alg == 0 { - mnemonic := BIPGenerateMnemonic() - pemEncPriv, err = BIPGenerateMasterKeyFromMnemonic(mnemonic, cfg.Pwd) - if err != nil { - return nil, err - } - } else { - return nil, fmt.Errorf("unsupported algorithm") - } - return pemEncPriv, nil -} - -// Decode the master public key -func BIPDecodeMasterKey(pwd string, privKey []byte) ([]byte, error) { - var cryptoPrivKey []byte - var err error - if privKey != nil { - pemBlock, _ := pem.Decode(privKey) - if pemBlock == nil { - return nil, fmt.Errorf("invalid private key") - } - if pemBlock.Type == "ENCRYPTED PRIVATE KEY" { - if pwd == "" { - return nil, fmt.Errorf("key is encrypted need password to decrypt") - } - cryptoPrivKey, err = UnSeal(pwd, pemBlock.Bytes) - if err != nil { - return nil, fmt.Errorf("key is invalid or password is wrong") - } - } - } - return cryptoPrivKey, nil -} - -func BIPSign(priv PrivateKey, data []byte) ([]byte, error) { - return priv.(crypto.Signer).Sign(rand.Reader, data, crypto.SHA256) -} - -func BIPVerify(pub PublicKey, data []byte, sig []byte) bool { - switch pub.(type) { - case *ecdsa.PublicKey: - return ecdsa.VerifyASN1(pub.(*ecdsa.PublicKey), data, sig) - default: - return false - } -} From 763be72d41021d97d527806e4f6aff3ffb38f310 Mon Sep 17 00:00:00 2001 From: harirubix Date: Fri, 9 Feb 2024 09:56:35 +0530 Subject: [PATCH 14/62] deterministic ecdsa using go 1.19 legacy --- crypto/crypto.go | 9 +++++++++ crypto/crypto_test.go | 1 + go.mod | 1 + go.sum | 5 +++++ 4 files changed, 16 insertions(+) diff --git a/crypto/crypto.go b/crypto/crypto.go index dead956e..5bcb6e12 100644 --- a/crypto/crypto.go +++ b/crypto/crypto.go @@ -6,9 +6,13 @@ import ( "crypto/elliptic" "crypto/rand" "crypto/rsa" + "crypto/sha512" "crypto/x509" "encoding/pem" "fmt" + + "filippo.io/keygen" + "golang.org/x/crypto/hkdf" ) // PublicKey represents a public key using an unspecified algorithm. @@ -23,6 +27,7 @@ type CryptoAlgType int const ( RSA2048 CryptoAlgType = iota ECDSAP256 + ECDSADET ) // CryptoConfig is configuration for the crypto @@ -43,6 +48,10 @@ func GenerateKeyPair(cfg *CryptoConfig) ([]byte, []byte, error) { case ECDSAP256: privKey, err = ecdsa.GenerateKey(elliptic.P256(), rand.Reader) pubKey = &privKey.(*ecdsa.PrivateKey).PublicKey + case ECDSADET: + r := hkdf.New(sha512.New, []byte(cfg.Pwd), nil, nil) + privKey, _ = keygen.ECDSALegacy(elliptic.P256(), r) + pubKey = &privKey.(*ecdsa.PrivateKey).PublicKey default: return nil, nil, fmt.Errorf("unsupported algorithm") } diff --git a/crypto/crypto_test.go b/crypto/crypto_test.go index 968e3e7e..2f3d3170 100644 --- a/crypto/crypto_test.go +++ b/crypto/crypto_test.go @@ -32,5 +32,6 @@ func testKeyGeneration(t *testing.T, alg CryptoAlgType, pwd string) { func TestKeyGeneration(t *testing.T) { testKeyGeneration(t, ECDSAP256, "") + testKeyGeneration(t, ECDSADET, "test") testKeyGeneration(t, ECDSAP256, "TestPassword") } diff --git a/go.mod b/go.mod index c0b1a3ff..c54df7d1 100644 --- a/go.mod +++ b/go.mod @@ -16,6 +16,7 @@ require ( ) require ( + filippo.io/keygen v0.0.0-20230306160926-5201437acf8e // indirect github.com/btcsuite/btcd v0.23.0 // indirect github.com/denisenkom/go-mssqldb v0.12.3 // indirect github.com/dgrijalva/jwt-go v3.2.0+incompatible diff --git a/go.sum b/go.sum index 5ce22340..0e8105f6 100644 --- a/go.sum +++ b/go.sum @@ -592,6 +592,10 @@ cloud.google.com/go/workflows v1.8.0/go.mod h1:ysGhmEajwZxGn1OhGOGKsTXc5PyxOc0vf cloud.google.com/go/workflows v1.9.0/go.mod h1:ZGkj1aFIOd9c8Gerkjjq7OW7I5+l6cSvT3ujaO/WwSA= cloud.google.com/go/workflows v1.10.0/go.mod h1:fZ8LmRmZQWacon9UCX1r/g/DfAXx5VcPALq2CxzdePw= dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= +filippo.io/bigmod v0.0.1 h1:OaEqDr3gEbofpnHbGqZweSL/bLMhy1pb54puiCDeuOA= +filippo.io/bigmod v0.0.1/go.mod h1:KyzqAbH7bRH6MOuOF1TPfUjvLoi0mRF2bIyD2ouRNQI= +filippo.io/keygen v0.0.0-20230306160926-5201437acf8e h1:+xwUCyMiCWKWsI0RowhzB4sngpUdMHgU6lLuWJCX5Dg= +filippo.io/keygen v0.0.0-20230306160926-5201437acf8e/go.mod h1:ZGSiF/b2hd6MRghF/cid0vXw8pXykRTmIu+JSPw/NCQ= gioui.org v0.0.0-20210308172011-57750fc8a0a6/go.mod h1:RSH6KIUZ0p2xy5zHDxgAM4zumjgTw83q2ge/PI+yyw8= git.sr.ht/~sbinet/gg v0.3.1/go.mod h1:KGYtlADtqsqANL9ueOFkWymvzUvLMQllU5Ixo+8v3pc= github.com/Azure/azure-sdk-for-go/sdk/azcore v0.19.0/go.mod h1:h6H6c8enJmmocHUbLiiGY6sx7f9i+X3m1CHdd5c6Rdw= @@ -1167,6 +1171,7 @@ golang.org/x/crypto v0.0.0-20220518034528-6f7dac969898/go.mod h1:IxCIyHEi3zRg3s0 golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/crypto v0.0.0-20221005025214-4161e89ecf1b/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/crypto v0.6.0/go.mod h1:OFC/31mSvZgRz0V1QTNCzfAI1aIRzbiufJtkMIlEp58= +golang.org/x/crypto v0.7.0/go.mod h1:pYwdfH91IfpZVANVyUOhSIPZaFoJGxTFbZhFTx+dXZU= golang.org/x/crypto v0.9.0 h1:LF6fAI+IutBocDJ2OT0Q1g8plpYljMZ4+lty+dsqw3g= golang.org/x/crypto v0.9.0/go.mod h1:yrmDGqONDYtNj3tH8X9dzUun2m2lzPa9ngI6/RUPGR0= golang.org/x/exp v0.0.0-20180321215751-8460e604b9de/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= From 299d7c72947b176541e7a41c0e7d75702d25c5fc Mon Sep 17 00:00:00 2001 From: Maneesha-rubix Date: Tue, 13 Feb 2024 17:56:30 +0530 Subject: [PATCH 15/62] Nlss Backward Compatible --- client/did.go | 38 +++++++++++- core/core.go | 23 ++++++- core/did.go | 19 +++++- core/migrate.go | 19 ++++++ core/quorum_initiator.go | 61 ++++++++++++++++--- did/did.go | 115 ++++++++++++++++++++--------------- did/model.go | 16 ++--- did/quorum.go | 27 +++++++-- did/quorum_light.go | 128 +++++++++++++++++++++++++++++++++++++++ grpcserver/did.go | 19 ++++++ server/did.go | 29 +++++++++ 11 files changed, 422 insertions(+), 72 deletions(-) create mode 100644 did/quorum_light.go diff --git a/client/did.go b/client/did.go index 20e183e8..6715e162 100644 --- a/client/did.go +++ b/client/did.go @@ -130,6 +130,18 @@ func (c *Client) CreateDID(cfg *did.DIDCreate) (string, bool) { fields[setup.DIDConfigField] = string(jd) files := make(map[string]string) + if cfg.Type != did.LightDIDMode { + if cfg.ImgFile != "" { + files["image"] = cfg.ImgFile + } + if cfg.DIDImgFileName != "" { + files["did_image"] = cfg.DIDImgFileName + } + if cfg.PubImgFile != "" { + files["pub_image"] = cfg.PubImgFile + } + } + if cfg.PubKeyFile != "" { files["pub_key"] = cfg.PubKeyFile } @@ -162,13 +174,19 @@ func (c *Client) SetupDID(dc *did.DIDCreate) (string, bool) { if !strings.Contains(dc.PrivImgFile, did.PvtShareFileName) || !strings.Contains(dc.PubImgFile, did.PubShareFileName) || !strings.Contains(dc.DIDImgFileName, did.DIDImgFileName) || + !strings.Contains(dc.PubKeyFile, did.PubKeyFileName) || + !strings.Contains(dc.QuorumPubKeyFile, did.QuorumPubKeyFileName) || + !strings.Contains(dc.QuorumPrivKeyFile, did.QuorumPvtKeyFileName) || !strings.Contains(dc.PrivKeyFile, did.PvtKeyFileName) { return "Required files are missing", false } case did.StandardDIDMode: if !strings.Contains(dc.PubImgFile, did.PubShareFileName) || !strings.Contains(dc.DIDImgFileName, did.DIDImgFileName) || - !strings.Contains(dc.PrivImgFile, did.PvtShareFileName) { + !strings.Contains(dc.PrivImgFile, did.PvtShareFileName) || + !strings.Contains(dc.PubKeyFile, did.PubKeyFileName) || + !strings.Contains(dc.QuorumPubKeyFile, did.QuorumPubKeyFileName) || + !strings.Contains(dc.QuorumPrivKeyFile, did.QuorumPvtKeyFileName) { return "Required files are missing", false } } @@ -181,6 +199,24 @@ func (c *Client) SetupDID(dc *did.DIDCreate) (string, bool) { fields[setup.DIDConfigField] = string(jd) files := make(map[string]string) + if dc.Type != did.LightDIDMode { + if dc.PubImgFile != "" { + files["pub_image"] = dc.PubImgFile + } + if dc.DIDImgFileName != "" { + files["did_image"] = dc.DIDImgFileName + } + if dc.PrivImgFile != "" { + files["priv_image"] = dc.PrivImgFile + } + if dc.QuorumPubKeyFile != "" { + files["quorum_pub_key"] = dc.QuorumPubKeyFile + } + if dc.QuorumPrivKeyFile != "" { + files["quorum_priv_key"] = dc.QuorumPrivKeyFile + } + } + if dc.PubKeyFile != "" { files["pub_key"] = dc.PubKeyFile } diff --git a/core/core.go b/core/core.go index 82863882..da1c9bd7 100644 --- a/core/core.go +++ b/core/core.go @@ -522,9 +522,12 @@ func (c *Core) SetupDID(reqID string, didStr string) (did.DIDCrypto, error) { func (c *Core) SetupForienDID(didStr string) (did.DIDCrypto, error) { err := c.FetchDID(didStr) if err != nil { + c.log.Error("couldn't fetch did") return nil, err } + return did.InitDIDLight(didStr, c.didDir, nil), nil + } func (c *Core) SetupForienDIDQuorum(didStr string) (did.DIDCrypto, error) { @@ -532,7 +535,25 @@ func (c *Core) SetupForienDIDQuorum(didStr string) (did.DIDCrypto, error) { if err != nil { return nil, err } - return did.InitDIDQuorumc(didStr, c.didDir, ""), nil + dt, err := c.w.GetDID(didStr) + if err != nil { + c.log.Error("DID does not exist", "did", didStr) + return nil, fmt.Errorf("DID does not exist") + } + + //To support NLSS backward compatibility, + //If the Quorum's did is created in light mode, + //it will initiate DIDQuorum_Lt, and if it is in basic mode, + //it will initiate DIDQuorumc + switch dt.Type { + case did.LightDIDMode: + return did.InitDIDQuorum_Lt(didStr, c.didDir, ""), nil + case did.BasicDIDMode: + return did.InitDIDQuorumc(didStr, c.didDir, ""), nil + default: + return nil, fmt.Errorf("DID Type is not supported") + } + } func (c *Core) FetchDID(did string) error { diff --git a/core/did.go b/core/did.go index cdca8618..5f4644a5 100644 --- a/core/did.go +++ b/core/did.go @@ -30,7 +30,7 @@ func (c *Core) GetDIDAccess(req *model.GetDIDAccess) *model.DIDAccessResponse { resp.Message = "Password does not match" return resp } - } else { + } else if dt.Type == did.LightDIDMode { _, ok := c.ValidateDIDToken(req.Token, setup.ChanllegeTokenType, req.DID) if !ok { resp.Message = "Invalid token" @@ -47,6 +47,23 @@ func (c *Core) GetDIDAccess(req *model.GetDIDAccess) *model.DIDAccessResponse { resp.Message = "Invalid signature" return resp } + } else { + _, ok := c.ValidateDIDToken(req.Token, setup.ChanllegeTokenType, req.DID) + if !ok { + resp.Message = "Invalid token" + return resp + } + dc := did.InitDIDBasic(req.DID, c.didDir, nil) + ok, err := dc.PvtVerify([]byte(req.Token), req.Signature) + if err != nil { + c.log.Error("Failed to verify DID signature", "err", err) + resp.Message = "Failed to verify DID signature" + return resp + } + if !ok { + resp.Message = "Invalid signature" + return resp + } } expiresAt := time.Now().Add(time.Minute * 10) tkn := c.generateDIDToken(setup.AccessTokenType, req.DID, dt.RootDID == 1, expiresAt) diff --git a/core/migrate.go b/core/migrate.go index a5ab5bd4..6539c2fd 100644 --- a/core/migrate.go +++ b/core/migrate.go @@ -164,6 +164,25 @@ func (c *Core) migrateNode(reqID string, m *MigrateRequest, didDir string) error QuorumPWD: m.QuorumPWD, } + if didCreate.Type != didm.LightDIDMode { + didCreate = didm.DIDCreate{ + DIDImgFileName: rubixDir + "DATA/" + d[0].DID + "/DID.png", + PubImgFile: rubixDir + "DATA/" + d[0].DID + "/PublicShare.png", + PrivImgFile: rubixDir + "DATA/" + d[0].DID + "/PrivateShare.png", + } + + _, err = os.Stat(didCreate.DIDImgFileName) + if err != nil { + c.log.Error("Failed to migrate, missing DID.png file", "err", err) + return fmt.Errorf("failed to migrate, missing DID.png file") + } + _, err = os.Stat(didCreate.PubImgFile) + if err != nil { + c.log.Error("Failed to migrate, missing PublicShare.png file", "err", err) + return fmt.Errorf("failed to migrate, missing PublicShare.png file") + } + } + did, err = c.d.MigrateDID(&didCreate) if err != nil { c.log.Error("Failed to migrate, failed in creation of new DID address", "err", err, "msg", did) diff --git a/core/quorum_initiator.go b/core/quorum_initiator.go index 9ff09b07..0d21585d 100644 --- a/core/quorum_initiator.go +++ b/core/quorum_initiator.go @@ -125,6 +125,7 @@ type CreditSignature struct { PrivSignature string `json:"priv_signature"` DID string `json:"did"` Hash string `json:"hash"` + SignVersion string `json:"sign_version"` //represents sign version (PkiSign == 0 or NlssSign==1) } type TokenArbitrationReq struct { @@ -162,20 +163,52 @@ func (c *Core) SetupQuorum(didStr string, pwd string, pvtKeyPwd string) error { c.log.Error("DID does not exist", "did", didStr) return fmt.Errorf("DID does not exist") } - dc := did.InitDIDQuorumc(didStr, c.didDir, pwd) - if dc == nil { - c.log.Error("Failed to setup quorum") - return fmt.Errorf("failed to setup quorum") + + dt, err := c.w.GetDID(didStr) + if err != nil { + c.log.Error("DID could not fetch", "did", didStr) + return fmt.Errorf("DID does not exist") } - c.qc[didStr] = dc - if pvtKeyPwd != "" { - dc := did.InitDIDLightWithPassword(didStr, c.didDir, pvtKeyPwd) + + //To support NLSS backward compatibility, + //If the Quorum's did is created in light mode, + //it will initiate DIDQuorum_Lt, and if it is in basic mode, + //it will initiate DIDQuorumc + switch dt.Type { + case did.LightDIDMode: + dc := did.InitDIDQuorum_Lt(didStr, c.didDir, pwd) + if dc == nil { + c.log.Error("Failed to setup quorum") + return fmt.Errorf("failed to setup quorum") + } + c.qc[didStr] = dc + if pvtKeyPwd != "" { + dc := did.InitDIDLightWithPassword(didStr, c.didDir, pvtKeyPwd) + if dc == nil { + c.log.Error("Failed to setup quorum as dc is nil") + return fmt.Errorf("failed to setup quorum") + } + c.pqc[didStr] = dc + } + case did.BasicDIDMode: + dc := did.InitDIDQuorumc(didStr, c.didDir, pwd) if dc == nil { c.log.Error("Failed to setup quorum") return fmt.Errorf("failed to setup quorum") } - c.pqc[didStr] = dc + c.qc[didStr] = dc + if pvtKeyPwd != "" { + dc := did.InitDIDBasicWithPassword(didStr, c.didDir, pvtKeyPwd) + if dc == nil { + c.log.Error("Failed to setup quorum") + return fmt.Errorf("failed to setup quorum") + } + c.pqc[didStr] = dc + } + default: + return fmt.Errorf("DID Type is not supported") } + c.up.RunUnpledge() return nil } @@ -551,6 +584,17 @@ func (c *Core) finishConsensus(id string, qt int, p *ipfsport.Peer, status bool, } return } + + var SigVersion string + + //SigVersion = 0 => Pki based sign in light mode + //SigVersion = 0 => Nlss based sign in basic mode + if util.HexToStr(ss) == "" { + SigVersion = "0" + } else { + SigVersion = "1" + } + switch qt { case 0: cs.Result.RunningCount-- @@ -562,6 +606,7 @@ func (c *Core) finishConsensus(id string, qt int, p *ipfsport.Peer, status bool, PrivSignature: util.HexToStr(ps), DID: did, Hash: hash, + SignVersion: SigVersion, } cs.P[did] = p cs.Credit.Credit = append(cs.Credit.Credit, csig) diff --git a/did/did.go b/did/did.go index 262239be..9101fb9b 100644 --- a/did/did.go +++ b/did/did.go @@ -1,7 +1,6 @@ package did import ( - "bytes" "context" "encoding/json" "errors" @@ -213,6 +212,28 @@ func (d *DID) CreateDID(didCreate *DIDCreate) (string, error) { if err != nil { return "", err } + } else if didCreate.Type != LightDIDMode { + if didCreate.QuorumPWD == "" { + if didCreate.PrivPWD != "" { + didCreate.QuorumPWD = didCreate.PrivPWD + } else { + didCreate.QuorumPWD = DefaultPWD + } + } + + pvtKey, pubKey, err := crypto.GenerateKeyPair(&crypto.CryptoConfig{Alg: crypto.ECDSAP256, Pwd: didCreate.QuorumPWD}) + if err != nil { + d.log.Error("failed to create keypair", "err", err) + return "", err + } + err = util.FileWrite(dirName+"/private/"+QuorumPvtKeyFileName, pvtKey) + if err != nil { + return "", err + } + err = util.FileWrite(dirName+"/public/"+QuorumPubKeyFileName, pubKey) + if err != nil { + return "", err + } } //passing the diroctory of public key file to add it to ipfs and exctract the hash @@ -263,6 +284,24 @@ func (d *DID) MigrateDID(didCreate *DIDCreate) (string, error) { return "", err } + if didCreate.Type != LightDIDMode { + _, err = util.Filecopy(didCreate.DIDImgFileName, dirName+"/public/"+DIDImgFileName) + if err != nil { + d.log.Error("failed to copy did image", "err", err) + return "", err + } + _, err = util.Filecopy(didCreate.PubImgFile, dirName+"/public/"+PubShareFileName) + if err != nil { + d.log.Error("failed to copy public share", "err", err) + return "", err + } + _, err = util.Filecopy(didCreate.PrivImgFile, dirName+"/private/"+PvtShareFileName) + if err != nil { + d.log.Error("failed to copy private share key", "err", err) + return "", err + } + } + if didCreate.Type == BasicDIDMode { if didCreate.PrivKeyFile == "" || didCreate.PubKeyFile == "" { if didCreate.PrivPWD == "" { @@ -310,6 +349,33 @@ func (d *DID) MigrateDID(didCreate *DIDCreate) (string, error) { } } + if didCreate.Type != LightDIDMode { + if didCreate.QuorumPrivKeyFile == "" || didCreate.QuorumPubKeyFile == "" { + pvtKey, pubKey, err := crypto.GenerateKeyPair(&crypto.CryptoConfig{Alg: crypto.ECDSAP256, Pwd: didCreate.QuorumPWD}) + if err != nil { + d.log.Error("failed to create keypair", "err", err) + return "", err + } + err = util.FileWrite(dirName+"/private/"+QuorumPvtKeyFileName, pvtKey) + if err != nil { + return "", err + } + err = util.FileWrite(dirName+"/public/"+QuorumPubKeyFileName, pubKey) + if err != nil { + return "", err + } + } else { + _, err = util.Filecopy(didCreate.QuorumPrivKeyFile, dirName+"/private/"+QuorumPvtKeyFileName) + if err != nil { + return "", err + } + _, err = util.Filecopy(didCreate.QuorumPubKeyFile, dirName+"/public/"+QuorumPubKeyFileName) + if err != nil { + return "", err + } + } + } + did, err := d.getDirHash(dirName + "/public/") if err != nil { return "", err @@ -345,53 +411,6 @@ type object struct { Hash string } -// This function takes file content as input, adds it to IPFS, -// without creating a physical file in the file system, and exctracts the hash -func (d *DID) addFileToIPFS(fileData []byte) (string, error) { - fmt.Println("calculating ipfs hash") - // Create a reader for the file data - reader := bytes.NewReader(fileData) - - // Send a request to IPFS to add the file data - resp, err := d.ipfs.Request("add"). - Option("cid-version", 1). - Option("hash", "sha3-256"). - Body(reader). - Send(context.Background()) - if err != nil { - return "", err - } - defer resp.Close() - - // Check for errors in the response - if resp.Error != nil { - return "", resp.Error - } - defer resp.Output.Close() - - // Decode the JSON response and extract the hash - dec := json.NewDecoder(resp.Output) - var final string - for { - var out object - err = dec.Decode(&out) - if err != nil { - if err == io.EOF { - break - } - return "", err - } - final = out.Hash - } - - // Check if the final hash is empty - if final == "" { - return "", errors.New("no results received") - } - - return final, nil -} - // Calculate the hash of a directory using IPFS func (d *DID) getDirHash(dir string) (string, error) { // Get information about the directory diff --git a/did/model.go b/did/model.go index 509d67cc..85688c85 100644 --- a/did/model.go +++ b/did/model.go @@ -14,13 +14,15 @@ const ( ) const ( - ImgFileName string = "image.png" - DIDImgFileName string = "did.png" - MasterDIDFileName string = "master.txt" - PvtShareFileName string = "pvtShare.png" - PubShareFileName string = "pubShare.png" - PvtKeyFileName string = "pvtKey.pem" - PubKeyFileName string = "pubKey.pem" + ImgFileName string = "image.png" + DIDImgFileName string = "did.png" + MasterDIDFileName string = "master.txt" + PvtShareFileName string = "pvtShare.png" + PubShareFileName string = "pubShare.png" + PvtKeyFileName string = "pvtKey.pem" + PubKeyFileName string = "pubKey.pem" + QuorumPvtKeyFileName string = "quorumPrivKey.pem" + QuorumPubKeyFileName string = "quorumPubKey.pem" ) const ( diff --git a/did/quorum.go b/did/quorum.go index 90492739..3cb1975f 100644 --- a/did/quorum.go +++ b/did/quorum.go @@ -23,7 +23,7 @@ type DIDQuorum struct { func InitDIDQuorumc(did string, baseDir string, pwd string) *DIDQuorum { d := &DIDQuorum{did: did, dir: util.SanitizeDirPath(baseDir) + did + "/", pwd: pwd} if d.pwd != "" { - privKey, err := ioutil.ReadFile(d.dir + PvtKeyFileName) + privKey, err := ioutil.ReadFile(d.dir + QuorumPvtKeyFileName) if err != nil { return nil } @@ -33,7 +33,7 @@ func InitDIDQuorumc(did string, baseDir string, pwd string) *DIDQuorum { } } - pubKey, err := ioutil.ReadFile(d.dir + PubKeyFileName) + pubKey, err := ioutil.ReadFile(d.dir + QuorumPubKeyFileName) if err != nil { return nil } @@ -49,7 +49,7 @@ func (d *DIDQuorum) GetDID() string { } func (d *DIDQuorum) GetSignVersion() int { - return PkiVersion + return NlssVersion } // Sign will return the singature of the DID @@ -57,15 +57,30 @@ func (d *DIDQuorum) Sign(hash string) ([]byte, []byte, error) { if d.privKey == nil { return nil, nil, fmt.Errorf("private key is not initialized") } - pvtKeySign, err := d.PvtSign([]byte(hash)) - // byteImg, err := util.GetPNGImagePixels(d.dir + PvtShareFileName) + byteImg, err := util.GetPNGImagePixels(d.dir + PvtShareFileName) if err != nil { fmt.Println(err) return nil, nil, err } - bs := []byte{} + ps := util.ByteArraytoIntArray(byteImg) + + randPosObject := util.RandomPositions("signer", hash, 32, ps) + + finalPos := randPosObject.PosForSign + pvtPos := util.GetPrivatePositions(finalPos, ps) + pvtPosStr := util.IntArraytoStr(pvtPos) + + hashPvtSign := util.HexToStr(util.CalculateHash([]byte(pvtPosStr), "SHA3-256")) + pvtKeySign, err := crypto.Sign(d.privKey, []byte(hashPvtSign)) + if err != nil { + return nil, nil, err + } + bs, err := util.BitstreamToBytes(pvtPosStr) + if err != nil { + return nil, nil, err + } return bs, pvtKeySign, err } diff --git a/did/quorum_light.go b/did/quorum_light.go new file mode 100644 index 00000000..7809e17b --- /dev/null +++ b/did/quorum_light.go @@ -0,0 +1,128 @@ +package did + +import ( + "bytes" + "fmt" + "io/ioutil" + + "github.com/rubixchain/rubixgoplatform/crypto" + "github.com/rubixchain/rubixgoplatform/nlss" + "github.com/rubixchain/rubixgoplatform/util" +) + +// DIDQuorum_Lt will handle light DID +type DIDQuorum_Lt struct { + did string + dir string + pwd string + privKey crypto.PrivateKey + pubKey crypto.PublicKey +} + +// InitDIDQuorum_Lt will return the Quorum did handle in light mode +func InitDIDQuorum_Lt(did string, baseDir string, pwd string) *DIDQuorum_Lt { + d := &DIDQuorum_Lt{did: did, dir: util.SanitizeDirPath(baseDir) + did + "/", pwd: pwd} + if d.pwd != "" { + privKey, err := ioutil.ReadFile(d.dir + PvtKeyFileName) + if err != nil { + return nil + } + d.privKey, _, err = crypto.DecodeKeyPair(d.pwd, privKey, nil) + if err != nil { + return nil + } + } + + pubKey, err := ioutil.ReadFile(d.dir + PubKeyFileName) + if err != nil { + return nil + } + _, d.pubKey, err = crypto.DecodeKeyPair("", nil, pubKey) + if err != nil { + return nil + } + return d +} + +func (d *DIDQuorum_Lt) GetDID() string { + return d.did +} + +func (d *DIDQuorum_Lt) GetSignVersion() int { + return PkiVersion +} + +// Sign will return the singature of the DID +func (d *DIDQuorum_Lt) Sign(hash string) ([]byte, []byte, error) { + if d.privKey == nil { + return nil, nil, fmt.Errorf("private key is not initialized") + } + pvtKeySign, err := d.PvtSign([]byte(hash)) + // byteImg, err := util.GetPNGImagePixels(d.dir + PvtShareFileName) + + if err != nil { + fmt.Println(err) + return nil, nil, err + } + + bs := []byte{} + return bs, pvtKeySign, err +} + +// verify the quorum's nlss based signature +func (d *DIDQuorum_Lt) NlssVerify(hash string, pvtShareSig []byte, pvtKeySIg []byte) (bool, error) { + // read senderDID + didImg, err := util.GetPNGImagePixels(d.dir + DIDImgFileName) + if err != nil { + return false, err + } + pubImg, err := util.GetPNGImagePixels(d.dir + PubShareFileName) + + if err != nil { + return false, err + } + + pSig := util.BytesToBitstream(pvtShareSig) + + ps := util.StringToIntArray(pSig) + + didBin := util.ByteArraytoIntArray(didImg) + pubBin := util.ByteArraytoIntArray(pubImg) + pubPos := util.RandomPositions("verifier", hash, 32, ps) + pubPosInt := util.GetPrivatePositions(pubPos.PosForSign, pubBin) + pubStr := util.IntArraytoStr(pubPosInt) + orgPos := make([]int, len(pubPos.OriginalPos)) + for i := range pubPos.OriginalPos { + orgPos[i] = pubPos.OriginalPos[i] / 8 + } + didPosInt := util.GetPrivatePositions(orgPos, didBin) + didStr := util.IntArraytoStr(didPosInt) + cb := nlss.Combine2Shares(nlss.ConvertBitString(pSig), nlss.ConvertBitString(pubStr)) + + db := nlss.ConvertBitString(didStr) + + if !bytes.Equal(cb, db) { + return false, fmt.Errorf("failed to verify") + } + hashPvtSign := util.HexToStr(util.CalculateHash([]byte(pSig), "SHA3-256")) + if !crypto.Verify(d.pubKey, []byte(hashPvtSign), pvtKeySIg) { + return false, fmt.Errorf("failed to verify private key singature") + } + return true, nil +} +func (d *DIDQuorum_Lt) PvtSign(hash []byte) ([]byte, error) { + if d.privKey == nil { + return nil, fmt.Errorf("private key is not initialized") + } + ps, err := crypto.Sign(d.privKey, hash) + if err != nil { + return nil, err + } + return ps, nil +} +func (d *DIDQuorum_Lt) PvtVerify(hash []byte, sign []byte) (bool, error) { + if !crypto.Verify(d.pubKey, hash, sign) { + return false, fmt.Errorf("failed to verify private key singature") + } + return true, nil +} diff --git a/grpcserver/did.go b/grpcserver/did.go index ca5ab2da..ddbede05 100644 --- a/grpcserver/did.go +++ b/grpcserver/did.go @@ -85,6 +85,25 @@ func (rn *RubixNative) CreateDID(ctx context.Context, req *protos.CreateDIDReq) } defer os.RemoveAll(folderName) + if dc.Type != did.LightDIDMode { + if req.DidImage != "" { + err = createFile(folderName+"/"+did.DIDImgFileName, req.DidImage, true) + if err != nil { + rn.log.Error(err.Error()) + return nil, status.Errorf(codes.Internal, err.Error()) + } + dc.ImgFile = folderName + "/" + did.DIDImgFileName + } + if req.PublicShare != "" { + err = createFile(folderName+"/"+did.PubShareFileName, req.PublicShare, true) + if err != nil { + rn.log.Error(err.Error()) + return nil, status.Errorf(codes.Internal, err.Error()) + } + dc.PubImgFile = folderName + "/" + did.PubShareFileName + } + } + if req.PublicKey != "" { err = createFile(folderName+"/"+did.PubKeyFileName, req.PublicKey, false) if err != nil { diff --git a/server/did.go b/server/did.go index 2bbffaac..b77ba3f4 100644 --- a/server/did.go +++ b/server/did.go @@ -66,6 +66,18 @@ func (s *Server) APICreateDID(req *ensweb.Request) *ensweb.Result { if strings.Contains(fileName, did.PubKeyFileName) { didCreate.PubKeyFile = fileName } + + if didCreate.Type != did.LightDIDMode { + if strings.Contains(fileName, did.ImgFileName) { + didCreate.ImgFile = fileName + } + if strings.Contains(fileName, did.DIDImgFileName) { + didCreate.DIDImgFileName = fileName + } + if strings.Contains(fileName, did.PubShareFileName) { + didCreate.PubImgFile = fileName + } + } } if !s.cfg.EnableAuth { didCreate.Dir = DIDRootDir @@ -199,6 +211,23 @@ func (s *Server) APISetupDID(req *ensweb.Request) *ensweb.Result { didCreate.PubKeyFile = fileName } + if didCreate.Type != did.LightDIDMode { + if strings.Contains(fileName, did.DIDImgFileName) { + didCreate.DIDImgFileName = fileName + } + if strings.Contains(fileName, did.PubShareFileName) { + didCreate.PubImgFile = fileName + } + if strings.Contains(fileName, did.PvtShareFileName) { + didCreate.PrivImgFile = fileName + } + if strings.Contains(fileName, did.QuorumPvtKeyFileName) { + didCreate.QuorumPrivKeyFile = fileName + } + if strings.Contains(fileName, did.QuorumPubKeyFileName) { + didCreate.QuorumPubKeyFile = fileName + } + } } dir, ok := s.validateAccess(req) if !ok { From b74f84d66d4430b42de0eea48552c3b8c09c2455 Mon Sep 17 00:00:00 2001 From: Maneesha-rubix Date: Mon, 19 Feb 2024 15:11:08 +0530 Subject: [PATCH 16/62] updated go.mod --- go.mod | 2 -- go.sum | 4 ---- 2 files changed, 6 deletions(-) diff --git a/go.mod b/go.mod index 703aa0b3..1c8877bd 100644 --- a/go.mod +++ b/go.mod @@ -47,8 +47,6 @@ require ( github.com/stretchr/testify v1.8.3 // indirect github.com/swaggo/files v1.0.0 // indirect github.com/swaggo/http-swagger v1.3.4 - github.com/tyler-smith/go-bip32 v1.0.0 // indirect - github.com/tyler-smith/go-bip39 v1.1.0 // indirect github.com/whyrusleeping/tar-utils v0.0.0-20201201191210-20a61371de5b // indirect golang.org/x/net v0.10.0 golang.org/x/tools v0.9.3 // indirect diff --git a/go.sum b/go.sum index 5ce22340..d25bb6e0 100644 --- a/go.sum +++ b/go.sum @@ -1112,10 +1112,6 @@ github.com/swaggo/swag v1.16.1 h1:fTNRhKstPKxcnoKsytm4sahr8FaYzUcT7i1/3nd/fBg= github.com/swaggo/swag v1.16.1/go.mod h1:9/LMvHycG3NFHfR6LwvikHv5iFvmPADQ359cKikGxto= github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7 h1:epCh84lMvA70Z7CTTCmYQn2CKbY8j86K7/FAIr141uY= github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7/go.mod h1:q4W45IWZaF22tdD+VEXcAWRA037jwmWEB5VWYORlTpc= -github.com/tyler-smith/go-bip32 v1.0.0 h1:sDR9juArbUgX+bO/iblgZnMPeWY1KZMUC2AFUJdv5KE= -github.com/tyler-smith/go-bip32 v1.0.0/go.mod h1:onot+eHknzV4BVPwrzqY5OoVpyCvnwD7lMawL5aQupE= -github.com/tyler-smith/go-bip39 v1.1.0 h1:5eUemwrMargf3BSLRRCalXT93Ns6pQJIjYQN2nyfOP8= -github.com/tyler-smith/go-bip39 v1.1.0/go.mod h1:gUYDtqQw1JS3ZJ8UWVcGTGqqr6YIN3CWg+kkNaLt55U= github.com/urfave/cli/v2 v2.3.0/go.mod h1:LJmUH05zAU44vOAcrfzZQKsZbVcdbOG8rtL3/XcUArI= github.com/whyrusleeping/tar-utils v0.0.0-20180509141711-8c6c8ba81d5c/go.mod h1:xxcJeBb7SIUl/Wzkz1eVKJE/CB34YNrqX2TQI6jY9zs= github.com/whyrusleeping/tar-utils v0.0.0-20201201191210-20a61371de5b h1:wA3QeTsaAXybLL2kb2cKhCAQTHgYTMwuI8lBlJSv5V8= From 98d2f4da5760d2a41d7286e55788213b4ff808ad Mon Sep 17 00:00:00 2001 From: Maneesha-rubix Date: Mon, 19 Feb 2024 16:50:51 +0530 Subject: [PATCH 17/62] comments edited --- README.md | 2 ++ block/transaction.go | 2 -- core/quorum_initiator.go | 12 ++++++------ core/quorum_recv.go | 1 - did/light.go | 1 + did/model.go | 4 ---- 6 files changed, 9 insertions(+), 13 deletions(-) diff --git a/README.md b/README.md index b2dc757b..5796fbb9 100644 --- a/README.md +++ b/README.md @@ -123,6 +123,8 @@ This following options are used for this command DID public key file name (default "pubKey.pem") -fp forcepassword This flag prompts to enter the password in terminal + + _Note: Use Light mode for PKI based authentication with backward compatiblity to PKI+NLSS based sign, and Basic mode for PKI+NLSS based authentication._ ``` Get All DID Command : To get all DID use this command. diff --git a/block/transaction.go b/block/transaction.go index 4cc6068b..0d3a37b5 100644 --- a/block/transaction.go +++ b/block/transaction.go @@ -43,7 +43,6 @@ const ( TIDeployerDIDKey string = "8" TIExecutorDIDKey string = "9" TICommitedTokensKey string = "10" - // TISignVersionKey string = "11" ) const ( @@ -79,7 +78,6 @@ type TransInfo struct { Tokens []TransTokens `json:"tokens"` DeployerDID string `json:"deployerDID"` ExecutorDID string `json:"executorDID"` - // SignVersion string `json:"signVersion"` } func newTransToken(b *Block, tt *TransTokens) map[string]interface{} { diff --git a/core/quorum_initiator.go b/core/quorum_initiator.go index 0d21585d..87e1ece3 100644 --- a/core/quorum_initiator.go +++ b/core/quorum_initiator.go @@ -585,14 +585,14 @@ func (c *Core) finishConsensus(id string, qt int, p *ipfsport.Peer, status bool, return } - var SigVersion string + var signVersion string - //SigVersion = 0 => Pki based sign in light mode - //SigVersion = 0 => Nlss based sign in basic mode + //signVersion = 0 => Pki based sign in light mode + //signVersion = 1 => Nlss based sign in basic mode if util.HexToStr(ss) == "" { - SigVersion = "0" + signVersion = "0" } else { - SigVersion = "1" + signVersion = "1" } switch qt { @@ -606,7 +606,7 @@ func (c *Core) finishConsensus(id string, qt int, p *ipfsport.Peer, status bool, PrivSignature: util.HexToStr(ps), DID: did, Hash: hash, - SignVersion: SigVersion, + SignVersion: signVersion, } cs.P[did] = p cs.Credit.Credit = append(cs.Credit.Credit, csig) diff --git a/core/quorum_recv.go b/core/quorum_recv.go index 00a306d0..9a705f78 100644 --- a/core/quorum_recv.go +++ b/core/quorum_recv.go @@ -485,7 +485,6 @@ func (c *Core) quorumConensus(req *ensweb.Request) *ensweb.Result { switch cr.Mode { case RBTTransferMode: c.log.Debug("RBT consensus started") - // fmt.Println(req, "/n", did, "/n", qdc, "/n", &cr) return c.quorumRBTConsensus(req, did, qdc, &cr) case DTCommitMode: c.log.Debug("Data consensus started") diff --git a/did/light.go b/did/light.go index ba61469c..9cd72091 100644 --- a/did/light.go +++ b/did/light.go @@ -70,6 +70,7 @@ func (d *DIDLight) GetSignVersion() int { } // PKI based sign in light mode +// In light mode, the sign function returns only the private signature, unlike the basic mode func (d *DIDLight) Sign(hash string) ([]byte, []byte, error) { pvtKeySign, err := d.PvtSign([]byte(hash)) bs := []byte{} diff --git a/did/model.go b/did/model.go index 85688c85..a5d0b9d6 100644 --- a/did/model.go +++ b/did/model.go @@ -53,10 +53,6 @@ type DIDSignature struct { Signature []byte } -// type Sign_Version struct { -// Version int `json:"version"` -// } - type SignReqData struct { ID string `json:"id"` Mode int `json:"mode"` From 446824a2ee219c1fd4a44ee5c96311a39d685ce4 Mon Sep 17 00:00:00 2001 From: harirubix Date: Tue, 20 Feb 2024 14:50:11 +0530 Subject: [PATCH 18/62] bip39 integration --- command/command.go | 2 ++ command/did.go | 26 ++++++++++++++++++++++++-- did/light.go | 6 +++--- did/model.go | 1 + did/quorum_light.go | 6 +++--- 5 files changed, 33 insertions(+), 8 deletions(-) diff --git a/command/command.go b/command/command.go index f5ec9efc..73fe18ca 100644 --- a/command/command.go +++ b/command/command.go @@ -240,6 +240,8 @@ type Command struct { executorAddr string latest bool links []string + mnemonicFile string + mnemonic string } func showVersion() { diff --git a/command/did.go b/command/did.go index 11a8bf82..c89ca90d 100644 --- a/command/did.go +++ b/command/did.go @@ -55,11 +55,33 @@ func (cmd *Command) CreateDID() { cmd.log.Error("private key & public key file names required") return } - pvtKey, pubKey, err := crypto.GenerateKeyPair(&crypto.CryptoConfig{Alg: crypto.ECDSAP256, Pwd: cmd.privPWD}) + + mnemonic := cmd.mnemonic + if mnemonic == "" { + mnemonic = crypto.BIPGenerateMnemonic() + } + + masterKey, err := crypto.BIPGenerateMasterKeyFromMnemonic(mnemonic, cmd.privPWD) if err != nil { cmd.log.Error("failed to create keypair", "err", err) + } + + masterKeyDecoded, err := crypto.BIPDecodeMasterKey(cmd.privPWD, masterKey) + if err != nil { + cmd.log.Error("failed to decode masterkey", "err", err) + } + + pvtKey, pubKey, err := crypto.BIPGenerateChild(string(masterKeyDecoded), 0) + if err != nil { + cmd.log.Error("failed to create child", "err", err) + } + + err = util.FileWrite(cmd.mnemonicFile, []byte(mnemonic)) + if err != nil { + cmd.log.Error("failed to write mnemonic file", "err", err) return } + err = util.FileWrite(cmd.privKeyFile, pvtKey) if err != nil { cmd.log.Error("failed to write private key file", "err", err) @@ -279,7 +301,7 @@ func (cmd *Command) SignatureResponse(br *model.BasicResponse, timeout ...time.D return "Failed to decode private key file, " + err.Error(), false } cmd.log.Info("Doing the private key signature") - sig, err := crypto.Sign(key, sr.Hash) + sig, err := crypto.BIPSign(key, sr.Hash) if err != nil { return "Failed to do signature, " + err.Error(), false } diff --git a/did/light.go b/did/light.go index 9cd72091..c6e81505 100644 --- a/did/light.go +++ b/did/light.go @@ -125,7 +125,7 @@ func (d *DIDLight) NlssVerify(hash string, pvtShareSig []byte, pvtKeySIg []byte) return false, err } hashPvtSign := util.HexToStr(util.CalculateHash([]byte(pSig), "SHA3-256")) - if !crypto.Verify(pubKeyByte, []byte(hashPvtSign), pvtKeySIg) { + if !crypto.BIPVerify(pubKeyByte, []byte(hashPvtSign), pvtKeySIg) { return false, fmt.Errorf("failed to verify private key singature") } return true, nil @@ -145,7 +145,7 @@ func (d *DIDLight) PvtSign(hash []byte) ([]byte, error) { if err != nil { return nil, err } - pvtKeySign, err := crypto.Sign(PrivateKey, hash) + pvtKeySign, err := crypto.BIPSign(PrivateKey, hash) if err != nil { return nil, err } @@ -162,7 +162,7 @@ func (d *DIDLight) PvtVerify(hash []byte, sign []byte) (bool, error) { if err != nil { return false, err } - if !crypto.Verify(pubKeyByte, hash, sign) { + if !crypto.BIPVerify(pubKeyByte, hash, sign) { return false, fmt.Errorf("failed to verify private key singature") } return true, nil diff --git a/did/model.go b/did/model.go index a5d0b9d6..7c285c8f 100644 --- a/did/model.go +++ b/did/model.go @@ -23,6 +23,7 @@ const ( PubKeyFileName string = "pubKey.pem" QuorumPvtKeyFileName string = "quorumPrivKey.pem" QuorumPubKeyFileName string = "quorumPubKey.pem" + mnemonicFile string = "mnemonic.txt" ) const ( diff --git a/did/quorum_light.go b/did/quorum_light.go index 7809e17b..2a98e238 100644 --- a/did/quorum_light.go +++ b/did/quorum_light.go @@ -105,7 +105,7 @@ func (d *DIDQuorum_Lt) NlssVerify(hash string, pvtShareSig []byte, pvtKeySIg []b return false, fmt.Errorf("failed to verify") } hashPvtSign := util.HexToStr(util.CalculateHash([]byte(pSig), "SHA3-256")) - if !crypto.Verify(d.pubKey, []byte(hashPvtSign), pvtKeySIg) { + if !crypto.BIPVerify(d.pubKey, []byte(hashPvtSign), pvtKeySIg) { return false, fmt.Errorf("failed to verify private key singature") } return true, nil @@ -114,14 +114,14 @@ func (d *DIDQuorum_Lt) PvtSign(hash []byte) ([]byte, error) { if d.privKey == nil { return nil, fmt.Errorf("private key is not initialized") } - ps, err := crypto.Sign(d.privKey, hash) + ps, err := crypto.BIPSign(d.privKey, hash) if err != nil { return nil, err } return ps, nil } func (d *DIDQuorum_Lt) PvtVerify(hash []byte, sign []byte) (bool, error) { - if !crypto.Verify(d.pubKey, hash, sign) { + if !crypto.BIPVerify(d.pubKey, hash, sign) { return false, fmt.Errorf("failed to verify private key singature") } return true, nil From 9bdce0d28e4bb0fda386c28db2a44e6532bb7fd4 Mon Sep 17 00:00:00 2001 From: Maneesha-rubix Date: Tue, 20 Feb 2024 18:29:02 +0530 Subject: [PATCH 19/62] Mnemonic file added --- command/command.go | 1 + did/did.go | 28 ++++++++++++++++++++++++++-- did/model.go | 4 +++- grpcclient/command.go | 2 ++ 4 files changed, 32 insertions(+), 3 deletions(-) diff --git a/command/command.go b/command/command.go index 73fe18ca..cd2be992 100644 --- a/command/command.go +++ b/command/command.go @@ -391,6 +391,7 @@ func Run(args []string) { flag.StringVar(&cmd.didImgFile, "didImgFile", did.DIDImgFileName, "DID image") flag.StringVar(&cmd.privImgFile, "privImgFile", did.PvtShareFileName, "DID public share image") flag.StringVar(&cmd.pubImgFile, "pubImgFile", did.PubShareFileName, "DID public share image") + flag.StringVar(&cmd.mnemonicFile, "mnemonicKeyFile", did.MnemonicFileName, "Mnemonic key file") flag.StringVar(&cmd.privKeyFile, "privKeyFile", did.PvtKeyFileName, "Private key file") flag.StringVar(&cmd.pubKeyFile, "pubKeyFile", did.PubKeyFileName, "Public key file") flag.StringVar(&cmd.quorumList, "quorumList", "quorumlist.json", "Quorum list") diff --git a/did/did.go b/did/did.go index 9101fb9b..01ad1491 100644 --- a/did/did.go +++ b/did/did.go @@ -77,10 +77,34 @@ func (d *DID) CreateDID(didCreate *DIDCreate) (string, error) { return "", err } - //generating private and public key pair - pvtKey, pubKey, err := crypto.GenerateKeyPair(&crypto.CryptoConfig{Alg: crypto.ECDSAP256, Pwd: didCreate.PrivPWD}) + _mnemonic, err := os.ReadFile(dirName + "/private/" + MnemonicFileName) + if err != nil { + d.log.Error("failed to read mnemonic file", "err", err) + } + mnemonic := string(_mnemonic) + if mnemonic == "" { + mnemonic = crypto.BIPGenerateMnemonic() + } + + masterKey, err := crypto.BIPGenerateMasterKeyFromMnemonic(mnemonic, didCreate.PrivPWD) if err != nil { d.log.Error("failed to create keypair", "err", err) + } + + masterKeyDecoded, err := crypto.BIPDecodeMasterKey(didCreate.PrivPWD, masterKey) + if err != nil { + d.log.Error("failed to decode masterkey", "err", err) + } + + //generating private and public key pair + pvtKey, pubKey, err := crypto.BIPGenerateChild(string(masterKeyDecoded), 0) + if err != nil { + d.log.Error("failed to create child", "err", err) + } + + err = util.FileWrite(dirName+"/private/"+MnemonicFileName, []byte(mnemonic)) + if err != nil { + d.log.Error("failed to write mnemonic file", "err", err) return "", err } diff --git a/did/model.go b/did/model.go index 7c285c8f..acee6280 100644 --- a/did/model.go +++ b/did/model.go @@ -23,7 +23,7 @@ const ( PubKeyFileName string = "pubKey.pem" QuorumPvtKeyFileName string = "quorumPrivKey.pem" QuorumPubKeyFileName string = "quorumPubKey.pem" - mnemonicFile string = "mnemonic.txt" + MnemonicFileName string = "mnemonic.txt" ) const ( @@ -47,6 +47,8 @@ type DIDCreate struct { PrivKeyFile string `json:"priv_key_file"` QuorumPubKeyFile string `json:"quorum_pub_key_file"` QuorumPrivKeyFile string `json:"quorum_priv_key_file"` + MnemonicFile string `json:"mnemonic_file"` + mnemonic string } type DIDSignature struct { diff --git a/grpcclient/command.go b/grpcclient/command.go index b52c1a02..92cc2e2b 100644 --- a/grpcclient/command.go +++ b/grpcclient/command.go @@ -114,6 +114,7 @@ type Command struct { grpcAddr string grpcPort int grpcSecure bool + mnemonicFile string } func showVersion() { @@ -181,6 +182,7 @@ func runCommand() { flag.StringVar(&cmd.didImgFile, "didImgFile", did.DIDImgFileName, "DID image") flag.StringVar(&cmd.privImgFile, "privImgFile", did.PvtShareFileName, "DID public share image") flag.StringVar(&cmd.pubImgFile, "pubImgFile", did.PubShareFileName, "DID public share image") + flag.StringVar(&cmd.mnemonicFile, "mnemonicKeyFile", did.MnemonicFileName, "Mnemonic key file") flag.StringVar(&cmd.privKeyFile, "privKeyFile", did.PvtKeyFileName, "Private key file") flag.StringVar(&cmd.pubKeyFile, "pubKeyFile", did.PubKeyFileName, "Public key file") flag.StringVar(&cmd.quorumList, "quorumList", "quorumlist.json", "Quorum list") From 880319f96844640545bc2b59f08b8bcf1fb0df72 Mon Sep 17 00:00:00 2001 From: harirubix Date: Wed, 21 Feb 2024 12:29:43 +0530 Subject: [PATCH 20/62] bip39 modification and minor fixes --- command/did.go | 13 +++---------- crypto/bip39.go | 38 ++++++++++++++++++-------------------- crypto/bip39_test.go | 14 +++++--------- did/did.go | 11 +++-------- 4 files changed, 29 insertions(+), 47 deletions(-) diff --git a/command/did.go b/command/did.go index c89ca90d..4b5a7f67 100644 --- a/command/did.go +++ b/command/did.go @@ -66,12 +66,7 @@ func (cmd *Command) CreateDID() { cmd.log.Error("failed to create keypair", "err", err) } - masterKeyDecoded, err := crypto.BIPDecodeMasterKey(cmd.privPWD, masterKey) - if err != nil { - cmd.log.Error("failed to decode masterkey", "err", err) - } - - pvtKey, pubKey, err := crypto.BIPGenerateChild(string(masterKeyDecoded), 0) + pvtKey, pubKey, err := crypto.BIPGenerateChild(string(masterKey), 0, cmd.privPWD) if err != nil { cmd.log.Error("failed to create child", "err", err) } @@ -92,8 +87,7 @@ func (cmd *Command) CreateDID() { cmd.log.Error("failed to write public key file", "err", err) return } - } - if cmd.didType == did.WalletDIDMode { + } else if cmd.didType == did.WalletDIDMode { f, err := os.Open(cmd.imgFile) if err != nil { cmd.log.Error("failed to open image", "err", err) @@ -158,8 +152,7 @@ func (cmd *Command) CreateDID() { cmd.log.Error("failed to create image", "err", err) return } - } - if cmd.didType != did.BasicDIDMode { + } else if cmd.didType != did.BasicDIDMode { if cmd.privKeyFile == "" || cmd.pubKeyFile == "" { cmd.log.Error("private key & public key file names required") return diff --git a/crypto/bip39.go b/crypto/bip39.go index 72fd7454..15bd0a09 100644 --- a/crypto/bip39.go +++ b/crypto/bip39.go @@ -19,9 +19,7 @@ const ( // The child private key is regenerated on demand from master key hence never stored // The child public key need to shared with other peers for verification // Make sure the path of child is also stored along with public key -func BIPGenerateChild(masterKey string, childPath int) ([]byte, []byte, error) { - var privateKeyBytes []byte - var publicKeyBytes []byte +func BIPGenerateChild(masterKey string, childPath int, pwd string) ([]byte, []byte, error) { masterKeybip32, err := bip32.B58Deserialize(masterKey) if err != nil { return nil, nil, err @@ -31,33 +29,33 @@ func BIPGenerateChild(masterKey string, childPath int) ([]byte, []byte, error) { return nil, nil, err } publicKey := privateKey.PublicKey() - privateKeyBytes = privateKey.Key - publicKeyBytes = publicKey.Key - return privateKeyBytes, publicKeyBytes, nil -} - -// Generate BIPMasterKey from Mnemonic and user provided password -// Useful in key recovery / device migration through mnemonics -func BIPGenerateMasterKeyFromMnemonic(mnemonic string, pwd string) ([]byte, error) { - var masterkeySeralise string - seed := bip39.NewSeed(mnemonic, pwd) - masterKey, _ := bip32.NewMasterKey(seed) - masterkeySeralise = masterKey.B58Serialize() var pemEncPriv []byte if pwd != "" { - encBlock, err := Seal(pwd, []byte(masterkeySeralise)) + encBlock, err := Seal(pwd, []byte(privateKey.Key)) if err != nil { - return nil, err + return nil, nil, err } _, err = UnSeal(pwd, encBlock) if err != nil { - return nil, err + return nil, nil, err } pemEncPriv = pem.EncodeToMemory(&pem.Block{Type: "ENCRYPTED PRIVATE KEY", Bytes: encBlock}) } else { - pemEncPriv = pem.EncodeToMemory(&pem.Block{Type: "PRIVATE KEY", Bytes: []byte(masterkeySeralise)}) + pemEncPriv = pem.EncodeToMemory(&pem.Block{Type: "PRIVATE KEY", Bytes: []byte(privateKey.Key)}) } - return pemEncPriv, nil + pemEncPub := pem.EncodeToMemory(&pem.Block{Type: "PUBLIC KEY", Bytes: publicKey.Key}) + + return pemEncPriv, pemEncPub, nil +} + +// Generate BIPMasterKey from Mnemonic and user provided password +// Useful in key recovery / device migration through mnemonics +func BIPGenerateMasterKeyFromMnemonic(mnemonic string, pwd string) ([]byte, error) { + var masterkeySeralise string + seed := bip39.NewSeed(mnemonic, pwd) + masterKey, _ := bip32.NewMasterKey(seed) + masterkeySeralise = masterKey.B58Serialize() + return []byte(masterkeySeralise), nil } // Generate a random BIP mnemonic in rubix diff --git a/crypto/bip39_test.go b/crypto/bip39_test.go index fa4ac2e3..1d52a677 100644 --- a/crypto/bip39_test.go +++ b/crypto/bip39_test.go @@ -7,19 +7,14 @@ import ( secp256k1 "github.com/decred/dcrd/dcrec/secp256k1/v4" ) -func BIPtest(t *testing.T, alg CryptoAlgType, pwd string) { +func BIPtest(t *testing.T, mnemonic string, pwd string) { - masterKey, err := BIPGenerateMasterKey(&CryptoConfig{Alg: alg, Pwd: pwd}) + masterKey, err := BIPGenerateMasterKeyFromMnemonic(mnemonic, pwd) if err != nil { t.Fatal("failed to generate key pair", "err", err) } - masterKeyDecoded, err := BIPDecodeMasterKey(pwd, masterKey) - if err != nil { - t.Fatal("failed to decode key pair", "err", err) - } - - priv, _, err := BIPGenerateChild(string(masterKeyDecoded), 0) + priv, _, err := BIPGenerateChild(string(masterKey), 0, pwd) if err != nil { t.Fatal("failed to generate child", "err", err) } @@ -42,5 +37,6 @@ func BIPtest(t *testing.T, alg CryptoAlgType, pwd string) { } } func TestBIPKeyGeneration(t *testing.T) { - BIPtest(t, BIP39, "test") + BIPtest(t, "cup symbol flee find decline market tube border artist clever make plastic unfold chaos float artwork sustain suspect risk process fox decrease west seven", "test") + BIPtest(t, "cup symbol flee find decline market tube border artist clever make plastic unfold chaos float artwork sustain suspect risk process fox decrease west seven", "test") } diff --git a/did/did.go b/did/did.go index 01ad1491..190fe0fc 100644 --- a/did/did.go +++ b/did/did.go @@ -77,9 +77,9 @@ func (d *DID) CreateDID(didCreate *DIDCreate) (string, error) { return "", err } - _mnemonic, err := os.ReadFile(dirName + "/private/" + MnemonicFileName) + _mnemonic, err := os.ReadFile(MnemonicFileName) if err != nil { - d.log.Error("failed to read mnemonic file", "err", err) + d.log.Error("error is here ! failed to read mnemonic file", "err", err) } mnemonic := string(_mnemonic) if mnemonic == "" { @@ -91,13 +91,8 @@ func (d *DID) CreateDID(didCreate *DIDCreate) (string, error) { d.log.Error("failed to create keypair", "err", err) } - masterKeyDecoded, err := crypto.BIPDecodeMasterKey(didCreate.PrivPWD, masterKey) - if err != nil { - d.log.Error("failed to decode masterkey", "err", err) - } - //generating private and public key pair - pvtKey, pubKey, err := crypto.BIPGenerateChild(string(masterKeyDecoded), 0) + pvtKey, pubKey, err := crypto.BIPGenerateChild(string(masterKey), 0, didCreate.PrivPWD) if err != nil { d.log.Error("failed to create child", "err", err) } From 57caa152519c577516473801c95a547c470ec249 Mon Sep 17 00:00:00 2001 From: harirubix Date: Wed, 21 Feb 2024 16:59:57 +0530 Subject: [PATCH 21/62] fixed BIP key gen BIPsign BIPverify --- client/did.go | 3 ++- command/command.go | 1 - command/did.go | 19 +++++++++++-------- crypto/bip39.go | 25 ++++++++----------------- crypto/bip39_test.go | 10 ++++++---- did/did.go | 10 ++++++---- did/light.go | 29 ++++++++++------------------- did/model.go | 1 - did/quorum_light.go | 33 +++++++++++++++++++++++++++------ go.mod | 2 ++ go.sum | 5 +++++ 11 files changed, 77 insertions(+), 61 deletions(-) diff --git a/client/did.go b/client/did.go index 6715e162..1b583b31 100644 --- a/client/did.go +++ b/client/did.go @@ -167,7 +167,8 @@ func (c *Client) SetupDID(dc *did.DIDCreate) (string, bool) { switch dc.Type { case did.LightDIDMode: if !strings.Contains(dc.PubKeyFile, did.PubKeyFileName) || - !strings.Contains(dc.PrivKeyFile, did.PvtKeyFileName) { + !strings.Contains(dc.PrivKeyFile, did.PvtKeyFileName) || + !strings.Contains(dc.MnemonicFile, did.MnemonicFileName) { return "Required files are missing", false } case did.BasicDIDMode: diff --git a/command/command.go b/command/command.go index cd2be992..97c04479 100644 --- a/command/command.go +++ b/command/command.go @@ -241,7 +241,6 @@ type Command struct { latest bool links []string mnemonicFile string - mnemonic string } func showVersion() { diff --git a/command/did.go b/command/did.go index 4b5a7f67..45c425d5 100644 --- a/command/did.go +++ b/command/did.go @@ -8,6 +8,7 @@ import ( "os" "time" + secp256k1 "github.com/decred/dcrd/dcrec/secp256k1/v4" "github.com/rubixchain/rubixgoplatform/core/model" "github.com/rubixchain/rubixgoplatform/crypto" "github.com/rubixchain/rubixgoplatform/did" @@ -56,7 +57,11 @@ func (cmd *Command) CreateDID() { return } - mnemonic := cmd.mnemonic + _mnemonic, err := os.ReadFile(did.MnemonicFileName) + if err != nil { + cmd.log.Error("failed to read mnemonic file", "err", err) + } + mnemonic := string(_mnemonic) if mnemonic == "" { mnemonic = crypto.BIPGenerateMnemonic() } @@ -183,6 +188,7 @@ func (cmd *Command) CreateDID() { DIDImgFileName: cmd.didImgFile, PubImgFile: cmd.pubImgFile, PubKeyFile: cmd.pubKeyFile, + MnemonicFile: cmd.mnemonicFile, } msg, status := cmd.c.CreateDID(&cfg) if !status { @@ -289,14 +295,11 @@ func (cmd *Command) SignatureResponse(br *model.BasicResponse, timeout ...time.D if err != nil { return "Failed to open private key file, " + err.Error(), false } - key, _, err := crypto.DecodeKeyPair(password, privKey, nil) - if err != nil { - return "Failed to decode private key file, " + err.Error(), false - } - cmd.log.Info("Doing the private key signature") - sig, err := crypto.BIPSign(key, sr.Hash) + privkeyback := secp256k1.PrivKeyFromBytes(privKey) + privKeySer := privkeyback.ToECDSA() + sig, err := crypto.BIPSign(privKeySer, sr.Hash) if err != nil { - return "Failed to do signature, " + err.Error(), false + return "Failed to sign, " + err.Error(), false } sresp.Signature.Signature = sig sresp.Password = password diff --git a/crypto/bip39.go b/crypto/bip39.go index 15bd0a09..fc09fed6 100644 --- a/crypto/bip39.go +++ b/crypto/bip39.go @@ -9,6 +9,8 @@ import ( "github.com/tyler-smith/go-bip32" "github.com/tyler-smith/go-bip39" + + secp256k1 "github.com/decred/dcrd/dcrec/secp256k1/v4" ) const ( @@ -28,24 +30,13 @@ func BIPGenerateChild(masterKey string, childPath int, pwd string) ([]byte, []by if err != nil { return nil, nil, err } - publicKey := privateKey.PublicKey() - var pemEncPriv []byte - if pwd != "" { - encBlock, err := Seal(pwd, []byte(privateKey.Key)) - if err != nil { - return nil, nil, err - } - _, err = UnSeal(pwd, encBlock) - if err != nil { - return nil, nil, err - } - pemEncPriv = pem.EncodeToMemory(&pem.Block{Type: "ENCRYPTED PRIVATE KEY", Bytes: encBlock}) - } else { - pemEncPriv = pem.EncodeToMemory(&pem.Block{Type: "PRIVATE KEY", Bytes: []byte(privateKey.Key)}) - } - pemEncPub := pem.EncodeToMemory(&pem.Block{Type: "PUBLIC KEY", Bytes: publicKey.Key}) - return pemEncPriv, pemEncPub, nil + privKey := secp256k1.PrivKeyFromBytes(privateKey.Key) + privkeybyte := privKey.Serialize() + + pubkeybyte := privKey.PubKey().SerializeUncompressed() + return privkeybyte, pubkeybyte, nil + } // Generate BIPMasterKey from Mnemonic and user provided password diff --git a/crypto/bip39_test.go b/crypto/bip39_test.go index 1d52a677..7d154b66 100644 --- a/crypto/bip39_test.go +++ b/crypto/bip39_test.go @@ -14,7 +14,7 @@ func BIPtest(t *testing.T, mnemonic string, pwd string) { t.Fatal("failed to generate key pair", "err", err) } - priv, _, err := BIPGenerateChild(string(masterKey), 0, pwd) + priv, pub, err := BIPGenerateChild(string(masterKey), 0, pwd) if err != nil { t.Fatal("failed to generate child", "err", err) } @@ -24,9 +24,11 @@ func BIPtest(t *testing.T, mnemonic string, pwd string) { t.Fatal("failed to generate random number", "err", err) } - privKey := secp256k1.PrivKeyFromBytes(priv) - privKeySer := privKey.ToECDSA() - pubKeySer := privKey.PubKey().ToECDSA() + privkeyback := secp256k1.PrivKeyFromBytes(priv) + privKeySer := privkeyback.ToECDSA() + pubkeyback, _ := secp256k1.ParsePubKey(pub) + pubKeySer := pubkeyback.ToECDSA() + sig, err := BIPSign(privKeySer, data) if err != nil { t.Fatal("failed to do signature", "err", err) diff --git a/did/did.go b/did/did.go index 190fe0fc..9d44be46 100644 --- a/did/did.go +++ b/did/did.go @@ -77,13 +77,15 @@ func (d *DID) CreateDID(didCreate *DIDCreate) (string, error) { return "", err } - _mnemonic, err := os.ReadFile(MnemonicFileName) + _mnemonic, err := os.ReadFile(didCreate.MnemonicFile) if err != nil { - d.log.Error("error is here ! failed to read mnemonic file", "err", err) + d.log.Debug("failed to read mnemonic file", "err", err) } - mnemonic := string(_mnemonic) - if mnemonic == "" { + var mnemonic string + if _mnemonic == nil { mnemonic = crypto.BIPGenerateMnemonic() + } else { + mnemonic = string(_mnemonic) } masterKey, err := crypto.BIPGenerateMasterKeyFromMnemonic(mnemonic, didCreate.PrivPWD) diff --git a/did/light.go b/did/light.go index c6e81505..8a3fd1ef 100644 --- a/did/light.go +++ b/did/light.go @@ -6,6 +6,7 @@ import ( "io/ioutil" "time" + secp256k1 "github.com/decred/dcrd/dcrec/secp256k1/v4" "github.com/rubixchain/rubixgoplatform/crypto" "github.com/rubixchain/rubixgoplatform/nlss" "github.com/rubixchain/rubixgoplatform/util" @@ -120,12 +121,10 @@ func (d *DIDLight) NlssVerify(hash string, pvtShareSig []byte, pvtKeySIg []byte) if err != nil { return false, err } - _, pubKeyByte, err := crypto.DecodeKeyPair("", nil, pubKey) - if err != nil { - return false, err - } + pubkeyback, _ := secp256k1.ParsePubKey(pubKey) + pubKeySer := pubkeyback.ToECDSA() hashPvtSign := util.HexToStr(util.CalculateHash([]byte(pSig), "SHA3-256")) - if !crypto.BIPVerify(pubKeyByte, []byte(hashPvtSign), pvtKeySIg) { + if !crypto.BIPVerify(pubKeySer, []byte(hashPvtSign), pvtKeySIg) { return false, fmt.Errorf("failed to verify private key singature") } return true, nil @@ -137,15 +136,9 @@ func (d *DIDLight) PvtSign(hash []byte) ([]byte, error) { if err != nil { return nil, err } - pwd, err := d.getPassword() - if err != nil { - return nil, err - } - PrivateKey, _, err := crypto.DecodeKeyPair(pwd, privKey, nil) - if err != nil { - return nil, err - } - pvtKeySign, err := crypto.BIPSign(PrivateKey, hash) + privkeyback := secp256k1.PrivKeyFromBytes(privKey) + privKeySer := privkeyback.ToECDSA() + pvtKeySign, err := crypto.BIPSign(privKeySer, hash) if err != nil { return nil, err } @@ -158,11 +151,9 @@ func (d *DIDLight) PvtVerify(hash []byte, sign []byte) (bool, error) { if err != nil { return false, err } - _, pubKeyByte, err := crypto.DecodeKeyPair("", nil, pubKey) - if err != nil { - return false, err - } - if !crypto.BIPVerify(pubKeyByte, hash, sign) { + pubkeyback, _ := secp256k1.ParsePubKey(pubKey) + pubKeySer := pubkeyback.ToECDSA() + if !crypto.BIPVerify(pubKeySer, hash, sign) { return false, fmt.Errorf("failed to verify private key singature") } return true, nil diff --git a/did/model.go b/did/model.go index acee6280..64f6181e 100644 --- a/did/model.go +++ b/did/model.go @@ -48,7 +48,6 @@ type DIDCreate struct { QuorumPubKeyFile string `json:"quorum_pub_key_file"` QuorumPrivKeyFile string `json:"quorum_priv_key_file"` MnemonicFile string `json:"mnemonic_file"` - mnemonic string } type DIDSignature struct { diff --git a/did/quorum_light.go b/did/quorum_light.go index 2a98e238..e3f082b2 100644 --- a/did/quorum_light.go +++ b/did/quorum_light.go @@ -5,6 +5,7 @@ import ( "fmt" "io/ioutil" + secp256k1 "github.com/decred/dcrd/dcrec/secp256k1/v4" "github.com/rubixchain/rubixgoplatform/crypto" "github.com/rubixchain/rubixgoplatform/nlss" "github.com/rubixchain/rubixgoplatform/util" @@ -104,24 +105,44 @@ func (d *DIDQuorum_Lt) NlssVerify(hash string, pvtShareSig []byte, pvtKeySIg []b if !bytes.Equal(cb, db) { return false, fmt.Errorf("failed to verify") } + hashPvtSign := util.HexToStr(util.CalculateHash([]byte(pSig), "SHA3-256")) - if !crypto.BIPVerify(d.pubKey, []byte(hashPvtSign), pvtKeySIg) { + + pubKey, err := ioutil.ReadFile(d.dir + PubKeyFileName) + if err != nil { + return false, err + } + pubkeyback, _ := secp256k1.ParsePubKey(pubKey) + pubKeySer := pubkeyback.ToECDSA() + + if !crypto.BIPVerify(pubKeySer, []byte(hashPvtSign), pvtKeySIg) { return false, fmt.Errorf("failed to verify private key singature") } return true, nil } func (d *DIDQuorum_Lt) PvtSign(hash []byte) ([]byte, error) { - if d.privKey == nil { - return nil, fmt.Errorf("private key is not initialized") + privKey, err := ioutil.ReadFile(d.dir + PvtKeyFileName) + if err != nil { + return nil, err } - ps, err := crypto.BIPSign(d.privKey, hash) + privkeyback := secp256k1.PrivKeyFromBytes(privKey) + privKeySer := privkeyback.ToECDSA() + pvtKeySign, err := crypto.BIPSign(privKeySer, hash) if err != nil { return nil, err } - return ps, nil + return pvtKeySign, nil } func (d *DIDQuorum_Lt) PvtVerify(hash []byte, sign []byte) (bool, error) { - if !crypto.BIPVerify(d.pubKey, hash, sign) { + + pubKey, err := ioutil.ReadFile(d.dir + PubKeyFileName) + if err != nil { + return false, err + } + pubkeyback, _ := secp256k1.ParsePubKey(pubKey) + pubKeySer := pubkeyback.ToECDSA() + + if !crypto.BIPVerify(pubKeySer, hash, sign) { return false, fmt.Errorf("failed to verify private key singature") } return true, nil diff --git a/go.mod b/go.mod index c54df7d1..7d0ff4ba 100644 --- a/go.mod +++ b/go.mod @@ -18,6 +18,8 @@ require ( require ( filippo.io/keygen v0.0.0-20230306160926-5201437acf8e // indirect github.com/btcsuite/btcd v0.23.0 // indirect + github.com/decred/dcrd/dcrec/secp256k1 v1.0.4 + github.com/decred/dcrd/dcrec/secp256k1/v4 v4.0.1 // indirect github.com/denisenkom/go-mssqldb v0.12.3 // indirect github.com/dgrijalva/jwt-go v3.2.0+incompatible github.com/fatih/color v1.15.0 diff --git a/go.sum b/go.sum index 0e8105f6..37458085 100644 --- a/go.sum +++ b/go.sum @@ -692,8 +692,13 @@ github.com/davecgh/go-spew v0.0.0-20171005155431-ecdeabc65495/go.mod h1:J7Y8YcW2 github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/decred/dcrd/chaincfg/chainhash v1.0.2/go.mod h1:BpbrGgrPTr3YJYRN3Bm+D9NuaFd+zGyNeIKgrhCXK60= github.com/decred/dcrd/crypto/blake256 v1.0.0 h1:/8DMNYp9SGi5f0w7uCm6d6M4OU2rGFK09Y2A4Xv7EE0= github.com/decred/dcrd/crypto/blake256 v1.0.0/go.mod h1:sQl2p6Y26YV+ZOcSTP6thNdn47hh8kt6rqSlvmrXFAc= +github.com/decred/dcrd/dcrec/secp256k1 v1.0.4 h1:0XErmfJBiVbl0NvyclGn4jr+1hIylDf5beFi9W0o7Fc= +github.com/decred/dcrd/dcrec/secp256k1 v1.0.4/go.mod h1:00z7mJdugt+GBAzPN1QrDRGCXxyKUiexEHu6ukxEw3k= +github.com/decred/dcrd/dcrec/secp256k1/v2 v2.0.0 h1:3GIJYXQDAKpLEFriGFN8SbSffak10UXHGdIcFaMPykY= +github.com/decred/dcrd/dcrec/secp256k1/v2 v2.0.0/go.mod h1:3s92l0paYkZoIHuj4X93Teg/HB7eGM9x/zokGw+u4mY= github.com/decred/dcrd/dcrec/secp256k1/v4 v4.0.1 h1:YLtO71vCjJRCBcrPMtQ9nqBsqpA1m5sE92cU+pd5Mcc= github.com/decred/dcrd/dcrec/secp256k1/v4 v4.0.1/go.mod h1:hyedUtir6IdtD/7lIxGeCxkaw7y45JueMRL4DIyJDKs= github.com/decred/dcrd/lru v1.0.0/go.mod h1:mxKOwFd7lFjN2GZYsiz/ecgqR6kkYAl+0pz0tEMk218= From 644dac46da47d2045d651dbb8f77ce58378ee3a8 Mon Sep 17 00:00:00 2001 From: harirubix Date: Wed, 21 Feb 2024 19:16:44 +0530 Subject: [PATCH 22/62] fix light mode directory issue --- client/did.go | 2 +- command/did.go | 36 ------------------------------------ 2 files changed, 1 insertion(+), 37 deletions(-) diff --git a/client/did.go b/client/did.go index 1b583b31..3435286b 100644 --- a/client/did.go +++ b/client/did.go @@ -57,7 +57,7 @@ func (c *Client) CreateDID(cfg *did.DIDCreate) (string, bool) { util.Filecopy(cfg.PubKeyFile, did.PubKeyFileName) cfg.PubKeyFile = did.PubKeyFileName } - + cfg.PubKeyFile = "" case did.BasicDIDMode: if cfg.ImgFile == "" { c.log.Error("Image file requried") diff --git a/command/did.go b/command/did.go index 45c425d5..1d993574 100644 --- a/command/did.go +++ b/command/did.go @@ -56,42 +56,6 @@ func (cmd *Command) CreateDID() { cmd.log.Error("private key & public key file names required") return } - - _mnemonic, err := os.ReadFile(did.MnemonicFileName) - if err != nil { - cmd.log.Error("failed to read mnemonic file", "err", err) - } - mnemonic := string(_mnemonic) - if mnemonic == "" { - mnemonic = crypto.BIPGenerateMnemonic() - } - - masterKey, err := crypto.BIPGenerateMasterKeyFromMnemonic(mnemonic, cmd.privPWD) - if err != nil { - cmd.log.Error("failed to create keypair", "err", err) - } - - pvtKey, pubKey, err := crypto.BIPGenerateChild(string(masterKey), 0, cmd.privPWD) - if err != nil { - cmd.log.Error("failed to create child", "err", err) - } - - err = util.FileWrite(cmd.mnemonicFile, []byte(mnemonic)) - if err != nil { - cmd.log.Error("failed to write mnemonic file", "err", err) - return - } - - err = util.FileWrite(cmd.privKeyFile, pvtKey) - if err != nil { - cmd.log.Error("failed to write private key file", "err", err) - return - } - err = util.FileWrite(cmd.pubKeyFile, pubKey) - if err != nil { - cmd.log.Error("failed to write public key file", "err", err) - return - } } else if cmd.didType == did.WalletDIDMode { f, err := os.Open(cmd.imgFile) if err != nil { From 6060d256003e5a768a5cccf934b35ab72de88054 Mon Sep 17 00:00:00 2001 From: harirubix Date: Thu, 22 Feb 2024 10:50:36 +0530 Subject: [PATCH 23/62] BIP keys encoded and sign check --- command/did.go | 8 ++++++- crypto/bip39.go | 51 +++++++++++++++++++++++++++++++++++++++++++- crypto/bip39_test.go | 9 ++++++-- did/did.go | 37 ++++++++++++++++++++++++++++++++ did/light.go | 24 ++++++++++++++++++--- did/quorum_light.go | 24 ++++++++++++++++++--- 6 files changed, 143 insertions(+), 10 deletions(-) diff --git a/command/did.go b/command/did.go index 1d993574..8da96f0f 100644 --- a/command/did.go +++ b/command/did.go @@ -259,7 +259,13 @@ func (cmd *Command) SignatureResponse(br *model.BasicResponse, timeout ...time.D if err != nil { return "Failed to open private key file, " + err.Error(), false } - privkeyback := secp256k1.PrivKeyFromBytes(privKey) + + Privkey, _, err := crypto.DecodeBIPKeyPair(cmd.privPWD, privKey, nil) + if err != nil { + return "Failed to decode private key " + err.Error(), false + } + + privkeyback := secp256k1.PrivKeyFromBytes(Privkey) privKeySer := privkeyback.ToECDSA() sig, err := crypto.BIPSign(privKeySer, sr.Hash) if err != nil { diff --git a/crypto/bip39.go b/crypto/bip39.go index fc09fed6..2b4af1b3 100644 --- a/crypto/bip39.go +++ b/crypto/bip39.go @@ -35,8 +35,57 @@ func BIPGenerateChild(masterKey string, childPath int, pwd string) ([]byte, []by privkeybyte := privKey.Serialize() pubkeybyte := privKey.PubKey().SerializeUncompressed() - return privkeybyte, pubkeybyte, nil + var pemEncPriv []byte + if pwd != "" { + encBlock, err := Seal(pwd, privkeybyte) + if err != nil { + return nil, nil, err + } + _, err = UnSeal(pwd, encBlock) + if err != nil { + return nil, nil, err + } + pemEncPriv = pem.EncodeToMemory(&pem.Block{Type: "ENCRYPTED PRIVATE KEY", Bytes: encBlock}) + } else { + pemEncPriv = pem.EncodeToMemory(&pem.Block{Type: "PRIVATE KEY", Bytes: privkeybyte}) + } + pemEncPub := pem.EncodeToMemory(&pem.Block{Type: "PUBLIC KEY", Bytes: pubkeybyte}) + + return pemEncPriv, pemEncPub, nil + +} + +// GenerateKeyPair will generate key pair based on the configuration +func DecodeBIPKeyPair(pwd string, privKey []byte, pubKey []byte) ([]byte, []byte, error) { + var cryptoPrivKey []byte + var cryptoPubKey []byte + if privKey != nil { + pemBlock, _ := pem.Decode(privKey) + if pemBlock == nil { + return nil, nil, fmt.Errorf("invalid private key") + } + if pemBlock.Type == "ENCRYPTED PRIVATE KEY" { + if pwd == "" { + return nil, nil, fmt.Errorf("key is encrypted need password to decrypt") + } + decData, err := UnSeal(pwd, pemBlock.Bytes) + if err != nil { + return nil, nil, fmt.Errorf("key is invalid or password is wrong") + } + cryptoPrivKey = decData + } else { + cryptoPrivKey = pemBlock.Bytes + } + } + if pubKey != nil { + pemBlock, _ := pem.Decode(pubKey) + if pemBlock == nil { + return nil, nil, fmt.Errorf("invalid public key") + } + cryptoPubKey = pemBlock.Bytes + } + return cryptoPrivKey, cryptoPubKey, nil } // Generate BIPMasterKey from Mnemonic and user provided password diff --git a/crypto/bip39_test.go b/crypto/bip39_test.go index 7d154b66..407126c3 100644 --- a/crypto/bip39_test.go +++ b/crypto/bip39_test.go @@ -19,14 +19,19 @@ func BIPtest(t *testing.T, mnemonic string, pwd string) { t.Fatal("failed to generate child", "err", err) } + privkey, pubkey, err := DecodeBIPKeyPair(pwd, priv, pub) + if err != nil { + t.Fatal("failed to decode key pair", "err", err) + } + data, err := GetRandBytes(rand.Reader, 20) if err != nil { t.Fatal("failed to generate random number", "err", err) } - privkeyback := secp256k1.PrivKeyFromBytes(priv) + privkeyback := secp256k1.PrivKeyFromBytes(privkey) privKeySer := privkeyback.ToECDSA() - pubkeyback, _ := secp256k1.ParsePubKey(pub) + pubkeyback, _ := secp256k1.ParsePubKey(pubkey) pubKeySer := pubkeyback.ToECDSA() sig, err := BIPSign(privKeySer, data) diff --git a/did/did.go b/did/did.go index 9d44be46..0a2544b6 100644 --- a/did/did.go +++ b/did/did.go @@ -7,10 +7,12 @@ import ( "fmt" "image" "io" + "io/ioutil" "os" "path/filepath" "time" + secp256k1 "github.com/decred/dcrd/dcrec/secp256k1/v4" ipfsnode "github.com/ipfs/go-ipfs-api" files "github.com/ipfs/go-ipfs-files" "github.com/rubixchain/rubixgoplatform/crypto" @@ -114,6 +116,41 @@ func (d *DID) CreateDID(didCreate *DIDCreate) (string, error) { if err != nil { return "", err } + + privKeyTest, err := ioutil.ReadFile(dirName + "/private/" + PvtKeyFileName) + if err != nil { + return "", err + } + + Privkey, _, err := crypto.DecodeBIPKeyPair(didCreate.PrivPWD, privKeyTest, nil) + if err != nil { + return "", err + } + + privkeyback := secp256k1.PrivKeyFromBytes(Privkey) + privKeySer := privkeyback.ToECDSA() + pvtKeySign, err := crypto.BIPSign(privKeySer, []byte("test")) + if err != nil { + return "", err + } + pubKeyTest, err := ioutil.ReadFile(dirName + "/public/" + PubKeyFileName) + if err != nil { + return "", err + } + + _, pubKeyByte, err := crypto.DecodeBIPKeyPair("", nil, pubKeyTest) + if err != nil { + return "", err + } + + pubkeyback, _ := secp256k1.ParsePubKey(pubKeyByte) + pubKeySer := pubkeyback.ToECDSA() + if !crypto.BIPVerify(pubKeySer, []byte("test"), pvtKeySign) { + return "", fmt.Errorf("failed to verify private key singature") + } else { + fmt.Println(" BIP sign tested successfully") + } + if didCreate.QuorumPWD == "" { if didCreate.PrivPWD != "" { didCreate.QuorumPWD = didCreate.PrivPWD diff --git a/did/light.go b/did/light.go index 8a3fd1ef..d43116bd 100644 --- a/did/light.go +++ b/did/light.go @@ -121,7 +121,13 @@ func (d *DIDLight) NlssVerify(hash string, pvtShareSig []byte, pvtKeySIg []byte) if err != nil { return false, err } - pubkeyback, _ := secp256k1.ParsePubKey(pubKey) + + _, pubKeyByte, err := crypto.DecodeBIPKeyPair("", nil, pubKey) + if err != nil { + return false, err + } + + pubkeyback, _ := secp256k1.ParsePubKey(pubKeyByte) pubKeySer := pubkeyback.ToECDSA() hashPvtSign := util.HexToStr(util.CalculateHash([]byte(pSig), "SHA3-256")) if !crypto.BIPVerify(pubKeySer, []byte(hashPvtSign), pvtKeySIg) { @@ -136,7 +142,13 @@ func (d *DIDLight) PvtSign(hash []byte) ([]byte, error) { if err != nil { return nil, err } - privkeyback := secp256k1.PrivKeyFromBytes(privKey) + + Privatekey, _, err := crypto.DecodeBIPKeyPair(d.pwd, privKey, nil) + if err != nil { + return nil, err + } + + privkeyback := secp256k1.PrivKeyFromBytes(Privatekey) privKeySer := privkeyback.ToECDSA() pvtKeySign, err := crypto.BIPSign(privKeySer, hash) if err != nil { @@ -151,7 +163,13 @@ func (d *DIDLight) PvtVerify(hash []byte, sign []byte) (bool, error) { if err != nil { return false, err } - pubkeyback, _ := secp256k1.ParsePubKey(pubKey) + + _, pubKeyByte, err := crypto.DecodeBIPKeyPair("", nil, pubKey) + if err != nil { + return false, err + } + + pubkeyback, _ := secp256k1.ParsePubKey(pubKeyByte) pubKeySer := pubkeyback.ToECDSA() if !crypto.BIPVerify(pubKeySer, hash, sign) { return false, fmt.Errorf("failed to verify private key singature") diff --git a/did/quorum_light.go b/did/quorum_light.go index e3f082b2..ee604ea2 100644 --- a/did/quorum_light.go +++ b/did/quorum_light.go @@ -112,7 +112,13 @@ func (d *DIDQuorum_Lt) NlssVerify(hash string, pvtShareSig []byte, pvtKeySIg []b if err != nil { return false, err } - pubkeyback, _ := secp256k1.ParsePubKey(pubKey) + + _, pubKeyByte, err := crypto.DecodeBIPKeyPair("", nil, pubKey) + if err != nil { + return false, err + } + + pubkeyback, _ := secp256k1.ParsePubKey(pubKeyByte) pubKeySer := pubkeyback.ToECDSA() if !crypto.BIPVerify(pubKeySer, []byte(hashPvtSign), pvtKeySIg) { @@ -125,7 +131,13 @@ func (d *DIDQuorum_Lt) PvtSign(hash []byte) ([]byte, error) { if err != nil { return nil, err } - privkeyback := secp256k1.PrivKeyFromBytes(privKey) + + Privatekey, _, err := crypto.DecodeBIPKeyPair(d.pwd, privKey, nil) + if err != nil { + return nil, err + } + + privkeyback := secp256k1.PrivKeyFromBytes(Privatekey) privKeySer := privkeyback.ToECDSA() pvtKeySign, err := crypto.BIPSign(privKeySer, hash) if err != nil { @@ -139,7 +151,13 @@ func (d *DIDQuorum_Lt) PvtVerify(hash []byte, sign []byte) (bool, error) { if err != nil { return false, err } - pubkeyback, _ := secp256k1.ParsePubKey(pubKey) + + _, pubKeyByte, err := crypto.DecodeBIPKeyPair("", nil, pubKey) + if err != nil { + return false, err + } + + pubkeyback, _ := secp256k1.ParsePubKey(pubKeyByte) pubKeySer := pubkeyback.ToECDSA() if !crypto.BIPVerify(pubKeySer, hash, sign) { From e587be8126296f2a80a0a288d5ce6f8e7c99685e Mon Sep 17 00:00:00 2001 From: harirubix Date: Thu, 22 Feb 2024 12:23:53 +0530 Subject: [PATCH 24/62] paramterise bip child path --- README.md | 4 ++++ command/command.go | 2 ++ command/did.go | 1 + did/did.go | 2 +- did/model.go | 1 + 5 files changed, 9 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 66734d73..2371d67c 100644 --- a/README.md +++ b/README.md @@ -121,6 +121,10 @@ This following options are used for this command DID private key file name (default "pvtKey.pem") -pubKeyFile string DID public key file name (default "pubKey.pem") + -mnemonicKeyFile string + Mnemonic key file (default "mnemonic.txt") + -ChildPath int + BIP Child Path (default 0) -fp forcepassword This flag prompts to enter the password in terminal diff --git a/command/command.go b/command/command.go index 97c04479..20b50828 100644 --- a/command/command.go +++ b/command/command.go @@ -241,6 +241,7 @@ type Command struct { latest bool links []string mnemonicFile string + ChildPath int } func showVersion() { @@ -382,6 +383,7 @@ func Run(args []string) { flag.StringVar(&peers, "peers", "", "Bootstrap peers, mutiple peers will be seprated by comma") flag.BoolVar(&cmd.didRoot, "didRoot", false, "Root DID") flag.IntVar(&cmd.didType, "didType", 0, "DID Creation type") + flag.IntVar(&cmd.ChildPath, "ChildPath", 0, "BIP child Path") flag.StringVar(&cmd.didSecret, "didSecret", "My DID Secret", "DID creation secret") flag.BoolVar(&cmd.forcePWD, "fp", false, "Force password entry") flag.StringVar(&cmd.privPWD, "privPWD", "mypassword", "Private key password") diff --git a/command/did.go b/command/did.go index 8da96f0f..ed41da53 100644 --- a/command/did.go +++ b/command/did.go @@ -153,6 +153,7 @@ func (cmd *Command) CreateDID() { PubImgFile: cmd.pubImgFile, PubKeyFile: cmd.pubKeyFile, MnemonicFile: cmd.mnemonicFile, + ChildPath: cmd.ChildPath, } msg, status := cmd.c.CreateDID(&cfg) if !status { diff --git a/did/did.go b/did/did.go index 0a2544b6..fabaacd6 100644 --- a/did/did.go +++ b/did/did.go @@ -96,7 +96,7 @@ func (d *DID) CreateDID(didCreate *DIDCreate) (string, error) { } //generating private and public key pair - pvtKey, pubKey, err := crypto.BIPGenerateChild(string(masterKey), 0, didCreate.PrivPWD) + pvtKey, pubKey, err := crypto.BIPGenerateChild(string(masterKey), didCreate.ChildPath, didCreate.PrivPWD) if err != nil { d.log.Error("failed to create child", "err", err) } diff --git a/did/model.go b/did/model.go index 64f6181e..c41e6e54 100644 --- a/did/model.go +++ b/did/model.go @@ -48,6 +48,7 @@ type DIDCreate struct { QuorumPubKeyFile string `json:"quorum_pub_key_file"` QuorumPrivKeyFile string `json:"quorum_priv_key_file"` MnemonicFile string `json:"mnemonic_file"` + ChildPath int `json:"childPath"` } type DIDSignature struct { From 1df077912f5a1e85937a92686a7c4d4af0075460 Mon Sep 17 00:00:00 2001 From: Maneesha-rubix Date: Thu, 22 Feb 2024 13:03:33 +0530 Subject: [PATCH 25/62] NLSS verification updated in light mode --- client/did.go | 4 ---- crypto/bip39_test.go | 2 +- did/light.go | 6 ++---- did/quorum_light.go | 7 ++----- 4 files changed, 5 insertions(+), 14 deletions(-) diff --git a/client/did.go b/client/did.go index 3435286b..55a104fa 100644 --- a/client/did.go +++ b/client/did.go @@ -53,10 +53,6 @@ func (c *Client) CreateDID(cfg *did.DIDCreate) (string, bool) { } switch cfg.Type { case did.LightDIDMode: - if !strings.Contains(cfg.PubKeyFile, did.PubKeyFileName) { - util.Filecopy(cfg.PubKeyFile, did.PubKeyFileName) - cfg.PubKeyFile = did.PubKeyFileName - } cfg.PubKeyFile = "" case did.BasicDIDMode: if cfg.ImgFile == "" { diff --git a/crypto/bip39_test.go b/crypto/bip39_test.go index 407126c3..2f2456db 100644 --- a/crypto/bip39_test.go +++ b/crypto/bip39_test.go @@ -45,5 +45,5 @@ func BIPtest(t *testing.T, mnemonic string, pwd string) { } func TestBIPKeyGeneration(t *testing.T) { BIPtest(t, "cup symbol flee find decline market tube border artist clever make plastic unfold chaos float artwork sustain suspect risk process fox decrease west seven", "test") - BIPtest(t, "cup symbol flee find decline market tube border artist clever make plastic unfold chaos float artwork sustain suspect risk process fox decrease west seven", "test") + BIPtest(t, "cub symbol flee find decline market tube border artist clever make plastic unfold chaos float artwork sustain suspect risk process fox decrease west seven", "test") } diff --git a/did/light.go b/did/light.go index d43116bd..57c12265 100644 --- a/did/light.go +++ b/did/light.go @@ -122,15 +122,13 @@ func (d *DIDLight) NlssVerify(hash string, pvtShareSig []byte, pvtKeySIg []byte) return false, err } - _, pubKeyByte, err := crypto.DecodeBIPKeyPair("", nil, pubKey) + _, pubKeyByte, err := crypto.DecodeKeyPair("", nil, pubKey) if err != nil { return false, err } - pubkeyback, _ := secp256k1.ParsePubKey(pubKeyByte) - pubKeySer := pubkeyback.ToECDSA() hashPvtSign := util.HexToStr(util.CalculateHash([]byte(pSig), "SHA3-256")) - if !crypto.BIPVerify(pubKeySer, []byte(hashPvtSign), pvtKeySIg) { + if !crypto.Verify(pubKeyByte, []byte(hashPvtSign), pvtKeySIg) { return false, fmt.Errorf("failed to verify private key singature") } return true, nil diff --git a/did/quorum_light.go b/did/quorum_light.go index ee604ea2..731923f5 100644 --- a/did/quorum_light.go +++ b/did/quorum_light.go @@ -113,15 +113,12 @@ func (d *DIDQuorum_Lt) NlssVerify(hash string, pvtShareSig []byte, pvtKeySIg []b return false, err } - _, pubKeyByte, err := crypto.DecodeBIPKeyPair("", nil, pubKey) + _, pubKeyByte, err := crypto.DecodeKeyPair("", nil, pubKey) if err != nil { return false, err } - pubkeyback, _ := secp256k1.ParsePubKey(pubKeyByte) - pubKeySer := pubkeyback.ToECDSA() - - if !crypto.BIPVerify(pubKeySer, []byte(hashPvtSign), pvtKeySIg) { + if !crypto.Verify(pubKeyByte, []byte(hashPvtSign), pvtKeySIg) { return false, fmt.Errorf("failed to verify private key singature") } return true, nil From 4fe4b009f76582418929afcad8578bd80ec0abbe Mon Sep 17 00:00:00 2001 From: Maneesha-rubix Date: Fri, 5 Apr 2024 16:30:50 +0530 Subject: [PATCH 26/62] bip39 update --- block/block.go | 1 + client/did.go | 2 +- command/did.go | 33 ++++++++++++----------- core/core.go | 56 +++++++++++++++++++++++++++++---------- core/did.go | 6 +++++ core/peer.go | 6 +++-- core/quorum_validation.go | 3 +++ core/wallet/did.go | 16 ++++++++++- did/basic.go | 6 ++++- did/light.go | 9 ++++++- did/model.go | 4 +-- did/quorum.go | 2 +- did/quorum_light.go | 8 ++---- 13 files changed, 107 insertions(+), 45 deletions(-) diff --git a/block/block.go b/block/block.go index 4c49134c..4220f5af 100644 --- a/block/block.go +++ b/block/block.go @@ -369,6 +369,7 @@ func (b *Block) VerifySignature(dc didmodule.DIDCrypto) error { } ok, err := dc.PvtVerify([]byte(h), util.StrToHex(s)) if err != nil || !ok { + fmt.Println("err:", err) return fmt.Errorf("failed to verify did signature") } return nil diff --git a/client/did.go b/client/did.go index 55a104fa..da91053d 100644 --- a/client/did.go +++ b/client/did.go @@ -156,7 +156,7 @@ func (c *Client) CreateDID(cfg *did.DIDCreate) (string, bool) { } func (c *Client) SetupDID(dc *did.DIDCreate) (string, bool) { - if dc.Type < did.LightDIDMode && dc.Type > did.WalletDIDMode { + if dc.Type < did.BasicDIDMode && dc.Type > did.LightDIDMode { return "Invalid DID mode", false } diff --git a/command/did.go b/command/did.go index ed41da53..d820ece9 100644 --- a/command/did.go +++ b/command/did.go @@ -8,7 +8,6 @@ import ( "os" "time" - secp256k1 "github.com/decred/dcrd/dcrec/secp256k1/v4" "github.com/rubixchain/rubixgoplatform/core/model" "github.com/rubixchain/rubixgoplatform/crypto" "github.com/rubixchain/rubixgoplatform/did" @@ -256,23 +255,25 @@ func (cmd *Command) SignatureResponse(br *model.BasicResponse, timeout ...time.D } switch sr.Mode { case did.LightDIDMode: - privKey, err := ioutil.ReadFile(cmd.privKeyFile) - if err != nil { - return "Failed to open private key file, " + err.Error(), false - } + // fmt.Println(cmd.privKeyFile) + // privKey, err := ioutil.ReadFile(cmd.privKeyFile) - Privkey, _, err := crypto.DecodeBIPKeyPair(cmd.privPWD, privKey, nil) - if err != nil { - return "Failed to decode private key " + err.Error(), false - } + // if err != nil { + // return "Failed to open private key file, " + err.Error(), false + // } - privkeyback := secp256k1.PrivKeyFromBytes(Privkey) - privKeySer := privkeyback.ToECDSA() - sig, err := crypto.BIPSign(privKeySer, sr.Hash) - if err != nil { - return "Failed to sign, " + err.Error(), false - } - sresp.Signature.Signature = sig + // Privkey, _, err := crypto.DecodeBIPKeyPair(cmd.privPWD, privKey, nil) + // if err != nil { + // return "Failed to decode private key " + err.Error(), false + // } + + // privkeyback := secp256k1.PrivKeyFromBytes(Privkey) + // privKeySer := privkeyback.ToECDSA() + // sig, err := crypto.BIPSign(privKeySer, sr.Hash) + // if err != nil { + // return "Failed to sign, " + err.Error(), false + // } + // sresp.Signature.Signature = sig sresp.Password = password case did.BasicDIDMode: sresp.Password = password diff --git a/core/core.go b/core/core.go index da1c9bd7..defbeda2 100644 --- a/core/core.go +++ b/core/core.go @@ -519,6 +519,7 @@ func (c *Core) SetupDID(reqID string, didStr string) (did.DIDCrypto, error) { } } +// Initializes the did in it's corresponding did mode (basic/ light) func (c *Core) SetupForienDID(didStr string) (did.DIDCrypto, error) { err := c.FetchDID(didStr) if err != nil { @@ -526,34 +527,45 @@ func (c *Core) SetupForienDID(didStr string) (did.DIDCrypto, error) { return nil, err } - return did.InitDIDLight(didStr, c.didDir, nil), nil - + // Fetching peer's did type from PeerDIDTable using GetPeerDIDType function + // and own did type from DIDTable using GetDID function + didtype, err := c.w.GetPeerDIDType(didStr) + if err != nil { + dt, err1 := c.w.GetDID(didStr) + if err1 != nil { + return nil, fmt.Errorf("couldn't fetch did type") + } + didtype = dt.Type + } + return c.InitialiseDID(didStr, didtype) } +// Initializes the quorum in it's corresponding did mode (basic/ light) func (c *Core) SetupForienDIDQuorum(didStr string) (did.DIDCrypto, error) { err := c.FetchDID(didStr) if err != nil { return nil, err } - dt, err := c.w.GetDID(didStr) + + // Fetching peer's did type from PeerDIDTable using GetPeerDIDType function + // and own did type from DIDTable using GetDID function + didtype, err := c.w.GetPeerDIDType(didStr) if err != nil { - c.log.Error("DID does not exist", "did", didStr) - return nil, fmt.Errorf("DID does not exist") + dt, err1 := c.w.GetDID(didStr) + if err1 != nil { + return nil, fmt.Errorf("couldn't fetch did type") + } + didtype = dt.Type } - //To support NLSS backward compatibility, - //If the Quorum's did is created in light mode, - //it will initiate DIDQuorum_Lt, and if it is in basic mode, - //it will initiate DIDQuorumc - switch dt.Type { - case did.LightDIDMode: - return did.InitDIDQuorum_Lt(didStr, c.didDir, ""), nil + switch didtype { case did.BasicDIDMode: return did.InitDIDQuorumc(didStr, c.didDir, ""), nil + case did.LightDIDMode: + return did.InitDIDQuorum_Lt(didStr, c.didDir, ""), nil default: - return nil, fmt.Errorf("DID Type is not supported") + return nil, fmt.Errorf("invalid did type") } - } func (c *Core) FetchDID(did string) error { @@ -583,3 +595,19 @@ func (c *Core) FetchDID(did string) error { func (c *Core) GetPeerID() string { return c.peerID } + +// Initializes the did in it's corresponding did mode (basic/ light) +func (c *Core) InitialiseDID(didStr string, didType int) (did.DIDCrypto, error) { + err := c.FetchDID(didStr) + if err != nil { + return nil, err + } + switch didType { + case did.LightDIDMode: + return did.InitDIDLight(didStr, c.didDir, nil), nil + case did.BasicDIDMode: + return did.InitDIDBasic(didStr, c.didDir, nil), nil + default: + return nil, fmt.Errorf("invalid did type, couldn't initialise") + } +} diff --git a/core/did.go b/core/did.go index 5f4644a5..95293e3c 100644 --- a/core/did.go +++ b/core/did.go @@ -214,11 +214,17 @@ func (c *Core) registerDID(reqID string, did string) error { if err != nil { return fmt.Errorf("register did, failed to do signature") } + + dt, err := c.w.GetDID(did) + if err != nil { + return fmt.Errorf("DID does not exist") + } pm := &PeerMap{ PeerID: c.peerID, DID: did, Signature: sig, Time: t, + DIDType: dt.Type, } err = c.publishPeerMap(pm) if err != nil { diff --git a/core/peer.go b/core/peer.go index 52456864..80f140da 100644 --- a/core/peer.go +++ b/core/peer.go @@ -18,6 +18,7 @@ const ( type PeerMap struct { PeerID string `json:"peer_id"` DID string `json:"did"` + DIDType int `json:"did_type"` Signature []byte `json:"signature"` Time string `json:"time"` } @@ -48,15 +49,16 @@ func (c *Core) peerCallback(peerID string, topic string, data []byte) { return } h := util.CalculateHashString(m.PeerID+m.DID+m.Time, "SHA3-256") - dc, err := c.SetupForienDID(m.DID) + dc, err := c.InitialiseDID(m.DID, m.DIDType) if err != nil { return } + fmt.Println("dc of peer:", dc) st, err := dc.PvtVerify([]byte(h), m.Signature) if err != nil || !st { return } - c.w.AddDIDPeerMap(m.DID, m.PeerID) + c.w.AddDIDPeerMap(m.DID, m.PeerID, m.DIDType) } func (c *Core) peerStatus(req *ensweb.Request) *ensweb.Result { diff --git a/core/quorum_validation.go b/core/quorum_validation.go index 0e02cb06..b92b8482 100644 --- a/core/quorum_validation.go +++ b/core/quorum_validation.go @@ -30,6 +30,7 @@ func (c *Core) validateSigner(b *block.Block) bool { c.log.Error("failed to get signers", "err", err) return false } + fmt.Println("signers:", signers) for _, signer := range signers { var dc did.DIDCrypto switch b.GetTransType() { @@ -46,6 +47,8 @@ func (c *Core) validateSigner(b *block.Block) bool { return false } } + fmt.Println("dc:", dc) + fmt.Println("signer's did", dc.GetDID()) err := b.VerifySignature(dc) if err != nil { c.log.Error("Failed to verify signature", "err", err) diff --git a/core/wallet/did.go b/core/wallet/did.go index 7c3ae250..b6a97a86 100644 --- a/core/wallet/did.go +++ b/core/wallet/did.go @@ -1,5 +1,7 @@ package wallet +import "fmt" + type DIDType struct { DID string `gorm:"column:did;primaryKey"` Type int `gorm:"column:type"` @@ -10,6 +12,7 @@ type DIDType struct { type DIDPeerMap struct { DID string `gorm:"column:did;primaryKey"` + DIDType int `gorm:"column:did_type"` PeerID string `gorm:"column:peer_id"` DIDLastChar string `gorm:"column:did_last_char"` } @@ -85,7 +88,7 @@ func (w *Wallet) IsDIDExist(did string) bool { return true } -func (w *Wallet) AddDIDPeerMap(did string, peerID string) error { +func (w *Wallet) AddDIDPeerMap(did string, peerID string, didType int) error { lastChar := string(did[len(did)-1]) var dm DIDPeerMap err := w.s.Read(DIDStorage, &dm, "did=?", did) @@ -97,6 +100,7 @@ func (w *Wallet) AddDIDPeerMap(did string, peerID string) error { dm.DID = did dm.PeerID = peerID dm.DIDLastChar = lastChar + dm.DIDType = didType return w.s.Write(DIDPeerStorage, &dm) } if dm.PeerID != peerID { @@ -133,3 +137,13 @@ func (w *Wallet) GetPeerID(did string) string { } return dm.PeerID } + +// Fetches did type of the given did from PeerDIDTable +func (w *Wallet) GetPeerDIDType(did string) (int, error) { + var dm DIDPeerMap + err := w.s.Read(DIDPeerStorage, &dm, "did=?", did) + if err != nil { + return 5, fmt.Errorf("couldn't fetch did type from peer did table") + } + return dm.DIDType, nil +} diff --git a/did/basic.go b/did/basic.go index 397b5026..d33836e4 100644 --- a/did/basic.go +++ b/did/basic.go @@ -158,12 +158,13 @@ func (d *DIDBasic) NlssVerify(hash string, pvtShareSig []byte, pvtKeySIg []byte) } hashPvtSign := util.HexToStr(util.CalculateHash([]byte(pSig), "SHA3-256")) if !crypto.Verify(pubKeyByte, []byte(hashPvtSign), pvtKeySIg) { - return false, fmt.Errorf("failed to verify private key singature") + return false, fmt.Errorf("failed to verify nlss private key singature") } return true, nil } func (d *DIDBasic) PvtSign(hash []byte) ([]byte, error) { + fmt.Println("pvt sign in basic") privKey, err := ioutil.ReadFile(d.dir + PvtKeyFileName) if err != nil { return nil, err @@ -183,12 +184,15 @@ func (d *DIDBasic) PvtSign(hash []byte) ([]byte, error) { return pvtKeySign, nil } func (d *DIDBasic) PvtVerify(hash []byte, sign []byte) (bool, error) { + fmt.Println("pvt verify in basic") pubKey, err := ioutil.ReadFile(d.dir + PubKeyFileName) if err != nil { + fmt.Println("couldn't read pub key") return false, err } _, pubKeyByte, err := crypto.DecodeKeyPair("", nil, pubKey) if err != nil { + fmt.Println("couldn't decode pub key") return false, err } if !crypto.Verify(pubKeyByte, hash, sign) { diff --git a/did/light.go b/did/light.go index 57c12265..88a6f885 100644 --- a/did/light.go +++ b/did/light.go @@ -136,12 +136,18 @@ func (d *DIDLight) NlssVerify(hash string, pvtShareSig []byte, pvtKeySIg []byte) } func (d *DIDLight) PvtSign(hash []byte) ([]byte, error) { + fmt.Println("pvt sign in light") privKey, err := ioutil.ReadFile(d.dir + PvtKeyFileName) if err != nil { return nil, err } - Privatekey, _, err := crypto.DecodeBIPKeyPair(d.pwd, privKey, nil) + pwd, err := d.getPassword() + if err != nil { + return nil, err + } + + Privatekey, _, err := crypto.DecodeBIPKeyPair(pwd, privKey, nil) if err != nil { return nil, err } @@ -157,6 +163,7 @@ func (d *DIDLight) PvtSign(hash []byte) ([]byte, error) { // Verify PKI based signature func (d *DIDLight) PvtVerify(hash []byte, sign []byte) (bool, error) { + fmt.Println("pvt verify in light") pubKey, err := ioutil.ReadFile(d.dir + PubKeyFileName) if err != nil { return false, err diff --git a/did/model.go b/did/model.go index c41e6e54..63722deb 100644 --- a/did/model.go +++ b/did/model.go @@ -1,11 +1,11 @@ package did const ( - LightDIDMode int = iota - BasicDIDMode + BasicDIDMode int = iota StandardDIDMode WalletDIDMode ChildDIDMode + LightDIDMode ) const ( diff --git a/did/quorum.go b/did/quorum.go index 3cb1975f..3b964b68 100644 --- a/did/quorum.go +++ b/did/quorum.go @@ -121,7 +121,7 @@ func (d *DIDQuorum) NlssVerify(hash string, pvtShareSig []byte, pvtKeySIg []byte } hashPvtSign := util.HexToStr(util.CalculateHash([]byte(pSig), "SHA3-256")) if !crypto.Verify(d.pubKey, []byte(hashPvtSign), pvtKeySIg) { - return false, fmt.Errorf("failed to verify private key singature") + return false, fmt.Errorf("failed to verify nlss private key singature") } return true, nil } diff --git a/did/quorum_light.go b/did/quorum_light.go index 731923f5..6771e484 100644 --- a/did/quorum_light.go +++ b/did/quorum_light.go @@ -28,7 +28,7 @@ func InitDIDQuorum_Lt(did string, baseDir string, pwd string) *DIDQuorum_Lt { if err != nil { return nil } - d.privKey, _, err = crypto.DecodeKeyPair(d.pwd, privKey, nil) + d.privKey, _, err = crypto.DecodeBIPKeyPair(d.pwd, privKey, nil) if err != nil { return nil } @@ -38,7 +38,7 @@ func InitDIDQuorum_Lt(did string, baseDir string, pwd string) *DIDQuorum_Lt { if err != nil { return nil } - _, d.pubKey, err = crypto.DecodeKeyPair("", nil, pubKey) + _, d.pubKey, err = crypto.DecodeBIPKeyPair("", nil, pubKey) if err != nil { return nil } @@ -55,9 +55,6 @@ func (d *DIDQuorum_Lt) GetSignVersion() int { // Sign will return the singature of the DID func (d *DIDQuorum_Lt) Sign(hash string) ([]byte, []byte, error) { - if d.privKey == nil { - return nil, nil, fmt.Errorf("private key is not initialized") - } pvtKeySign, err := d.PvtSign([]byte(hash)) // byteImg, err := util.GetPNGImagePixels(d.dir + PvtShareFileName) @@ -143,7 +140,6 @@ func (d *DIDQuorum_Lt) PvtSign(hash []byte) ([]byte, error) { return pvtKeySign, nil } func (d *DIDQuorum_Lt) PvtVerify(hash []byte, sign []byte) (bool, error) { - pubKey, err := ioutil.ReadFile(d.dir + PubKeyFileName) if err != nil { return false, err From ce7cc906acdb68ff23dd97dc6c6a25e76ea3e9db Mon Sep 17 00:00:00 2001 From: Maneesha-rubix Date: Wed, 10 Apr 2024 15:42:37 +0530 Subject: [PATCH 27/62] compatibility with old wallets --- core/quorum_validation.go | 3 --- core/wallet/did.go | 4 ++++ did/basic.go | 2 -- did/light.go | 2 -- 4 files changed, 4 insertions(+), 7 deletions(-) diff --git a/core/quorum_validation.go b/core/quorum_validation.go index b92b8482..0e02cb06 100644 --- a/core/quorum_validation.go +++ b/core/quorum_validation.go @@ -30,7 +30,6 @@ func (c *Core) validateSigner(b *block.Block) bool { c.log.Error("failed to get signers", "err", err) return false } - fmt.Println("signers:", signers) for _, signer := range signers { var dc did.DIDCrypto switch b.GetTransType() { @@ -47,8 +46,6 @@ func (c *Core) validateSigner(b *block.Block) bool { return false } } - fmt.Println("dc:", dc) - fmt.Println("signer's did", dc.GetDID()) err := b.VerifySignature(dc) if err != nil { c.log.Error("Failed to verify signature", "err", err) diff --git a/core/wallet/did.go b/core/wallet/did.go index b6a97a86..a92a2661 100644 --- a/core/wallet/did.go +++ b/core/wallet/did.go @@ -107,6 +107,10 @@ func (w *Wallet) AddDIDPeerMap(did string, peerID string, didType int) error { dm.PeerID = peerID return w.s.Update(DIDPeerStorage, &dm, "did=?", did) } + if dm.DIDType == 0 { + dm.DIDType = didType + return w.s.Update(DIDPeerStorage, &dm, "did=?", did) + } return nil } diff --git a/did/basic.go b/did/basic.go index d33836e4..507a8588 100644 --- a/did/basic.go +++ b/did/basic.go @@ -164,7 +164,6 @@ func (d *DIDBasic) NlssVerify(hash string, pvtShareSig []byte, pvtKeySIg []byte) } func (d *DIDBasic) PvtSign(hash []byte) ([]byte, error) { - fmt.Println("pvt sign in basic") privKey, err := ioutil.ReadFile(d.dir + PvtKeyFileName) if err != nil { return nil, err @@ -184,7 +183,6 @@ func (d *DIDBasic) PvtSign(hash []byte) ([]byte, error) { return pvtKeySign, nil } func (d *DIDBasic) PvtVerify(hash []byte, sign []byte) (bool, error) { - fmt.Println("pvt verify in basic") pubKey, err := ioutil.ReadFile(d.dir + PubKeyFileName) if err != nil { fmt.Println("couldn't read pub key") diff --git a/did/light.go b/did/light.go index 88a6f885..8a3824b8 100644 --- a/did/light.go +++ b/did/light.go @@ -136,7 +136,6 @@ func (d *DIDLight) NlssVerify(hash string, pvtShareSig []byte, pvtKeySIg []byte) } func (d *DIDLight) PvtSign(hash []byte) ([]byte, error) { - fmt.Println("pvt sign in light") privKey, err := ioutil.ReadFile(d.dir + PvtKeyFileName) if err != nil { return nil, err @@ -163,7 +162,6 @@ func (d *DIDLight) PvtSign(hash []byte) ([]byte, error) { // Verify PKI based signature func (d *DIDLight) PvtVerify(hash []byte, sign []byte) (bool, error) { - fmt.Println("pvt verify in light") pubKey, err := ioutil.ReadFile(d.dir + PubKeyFileName) if err != nil { return false, err From aa163179c62115ace2888e5df64dd31fac914723 Mon Sep 17 00:00:00 2001 From: Maneesha-rubix Date: Wed, 10 Apr 2024 17:24:18 +0530 Subject: [PATCH 28/62] BIP sign version updated --- contract/contract.go | 7 ++++--- core/quorum_initiator.go | 2 +- did/light.go | 4 ++-- did/model.go | 2 +- did/quorum_light.go | 2 +- 5 files changed, 9 insertions(+), 8 deletions(-) diff --git a/contract/contract.go b/contract/contract.go index 7403703b..94e00b3a 100644 --- a/contract/contract.go +++ b/contract/contract.go @@ -434,10 +434,10 @@ func (c *Contract) UpdateSignature(dc did.DIDCrypto) error { // This function is used by the quorums to verify sender's signature func (c *Contract) VerifySignature(dc did.DIDCrypto) error { //fetch sender's did - did := dc.GetDID() + didstr := dc.GetDID() //fetch sender's signature - hs, ss, ps, err := c.GetHashSig(did) + hs, ss, ps, err := c.GetHashSig(didstr) if err != nil { c.log.Error("err", err) return err @@ -445,7 +445,8 @@ func (c *Contract) VerifySignature(dc did.DIDCrypto) error { //If the ss i.e., share signature is empty, then its a Pki sign, so call PvtVerify //Else it is NLSS based sign, so call NlssVerify - if ss == "" { + didType := dc.GetSignVersion() + if didType == did.BIPVersion { ok, err := dc.PvtVerify([]byte(hs), util.StrToHex(ps)) if err != nil { diff --git a/core/quorum_initiator.go b/core/quorum_initiator.go index 87e1ece3..93655474 100644 --- a/core/quorum_initiator.go +++ b/core/quorum_initiator.go @@ -305,7 +305,7 @@ func (c *Core) initiateConsensus(cr *ConensusRequest, sc *contract.Contract, dc sigVers := dc.GetSignVersion() //Appending "1" at the beginning of Transaction ID as a symbol of PKI sign version - if sigVers == did.PkiVersion { + if sigVers == did.BIPVersion { tid = "1" + tid } diff --git a/did/light.go b/did/light.go index 8a3824b8..d3f11890 100644 --- a/did/light.go +++ b/did/light.go @@ -65,9 +65,9 @@ func (d *DIDLight) GetDID() string { } // When the did creation and signing is done in Light mode, -// this function returns the sign version as PkiVersion = 0 +// this function returns the sign version as BIPVersion = 0 func (d *DIDLight) GetSignVersion() int { - return PkiVersion + return BIPVersion } // PKI based sign in light mode diff --git a/did/model.go b/did/model.go index 63722deb..2496fda0 100644 --- a/did/model.go +++ b/did/model.go @@ -9,7 +9,7 @@ const ( ) const ( - PkiVersion int = iota + BIPVersion int = iota NlssVersion ) diff --git a/did/quorum_light.go b/did/quorum_light.go index 6771e484..5926cf63 100644 --- a/did/quorum_light.go +++ b/did/quorum_light.go @@ -50,7 +50,7 @@ func (d *DIDQuorum_Lt) GetDID() string { } func (d *DIDQuorum_Lt) GetSignVersion() int { - return PkiVersion + return BIPVersion } // Sign will return the singature of the DID From 061dcdc24390af0bf22b5cfbf4fe31a023f36c1e Mon Sep 17 00:00:00 2001 From: Maneesha-rubix Date: Wed, 10 Apr 2024 17:49:09 +0530 Subject: [PATCH 29/62] not appending sign version to Txn ID --- core/peer.go | 1 - core/quorum_initiator.go | 8 -------- did/basic.go | 2 -- 3 files changed, 11 deletions(-) diff --git a/core/peer.go b/core/peer.go index 80f140da..553cd878 100644 --- a/core/peer.go +++ b/core/peer.go @@ -53,7 +53,6 @@ func (c *Core) peerCallback(peerID string, topic string, data []byte) { if err != nil { return } - fmt.Println("dc of peer:", dc) st, err := dc.PvtVerify([]byte(h), m.Signature) if err != nil || !st { return diff --git a/core/quorum_initiator.go b/core/quorum_initiator.go index 93655474..b2e947f1 100644 --- a/core/quorum_initiator.go +++ b/core/quorum_initiator.go @@ -301,14 +301,6 @@ func (c *Core) initiateConsensus(cr *ConensusRequest, sc *contract.Contract, dc tid := util.HexToStr(util.CalculateHash(sc.GetBlock(), "SHA3-256")) lastCharTID := string(tid[len(tid)-1]) - //Fetching sign version - sigVers := dc.GetSignVersion() - - //Appending "1" at the beginning of Transaction ID as a symbol of PKI sign version - if sigVers == did.BIPVersion { - tid = "1" + tid - } - ql := c.qm.GetQuorum(cr.Type, lastCharTID) //passing lastCharTID as a parameter. Made changes in GetQuorum function to take 2 arguments if ql == nil || len(ql) < MinQuorumRequired { c.log.Error("Failed to get required quorums") diff --git a/did/basic.go b/did/basic.go index 507a8588..1e4730ad 100644 --- a/did/basic.go +++ b/did/basic.go @@ -185,12 +185,10 @@ func (d *DIDBasic) PvtSign(hash []byte) ([]byte, error) { func (d *DIDBasic) PvtVerify(hash []byte, sign []byte) (bool, error) { pubKey, err := ioutil.ReadFile(d.dir + PubKeyFileName) if err != nil { - fmt.Println("couldn't read pub key") return false, err } _, pubKeyByte, err := crypto.DecodeKeyPair("", nil, pubKey) if err != nil { - fmt.Println("couldn't decode pub key") return false, err } if !crypto.Verify(pubKeyByte, hash, sign) { From 757b28534fd7f74c3a48c9fffb6d452265994b21 Mon Sep 17 00:00:00 2001 From: Arnab Ghose Date: Thu, 11 Apr 2024 14:32:55 +0530 Subject: [PATCH 30/62] feat: added API endpoint and CLI command to fetch a node's peer ID --- client/node.go | 9 +++++++++ command/command.go | 7 ++++++- command/node.go | 17 +++++++++++++++++ server/node.go | 9 +++++++++ server/server.go | 1 + setup/setup.go | 1 + 6 files changed, 43 insertions(+), 1 deletion(-) create mode 100644 server/node.go diff --git a/client/node.go b/client/node.go index 02604409..0ef5334d 100644 --- a/client/node.go +++ b/client/node.go @@ -13,3 +13,12 @@ func (c *Client) Shutdown() (string, bool) { } return rm.Message, rm.Status } + +func (c *Client) PeerID() (string, bool) { + var rm model.BasicResponse + err := c.sendJSONRequest("GET", setup.APIPeerID, nil, nil, &rm) + if err != nil { + return "Failed to fetch peer ID of node, error: " + err.Error(), false + } + return rm.Message, rm.Status +} diff --git a/command/command.go b/command/command.go index d806b8ec..e46ad577 100644 --- a/command/command.go +++ b/command/command.go @@ -76,6 +76,7 @@ const ( DumpSmartContractTokenChainCmd string = "dumpsmartcontracttokenchain" GetTokenBlock string = "gettokenblock" GetSmartContractData string = "getsmartcontractdata" + GetPeerID string = "get-peer-id" ) var commands = []string{VersionCmd, @@ -120,6 +121,7 @@ var commands = []string{VersionCmd, DumpSmartContractTokenChainCmd, GetTokenBlock, GetSmartContractData, + GetPeerID, } var commandsHelp = []string{"To get tool version", "To get help", @@ -162,7 +164,8 @@ var commandsHelp = []string{"To get tool version", "This command will subscribe to a smart contract token", "This command will dump the smartcontract token chain", "This command gets token block", - "This command gets the smartcontract data from latest block"} + "This command gets the smartcontract data from latest block", + "This command will fetch the peer ID of the node"} type Command struct { cfg config.Config @@ -567,6 +570,8 @@ func Run(args []string) { cmd.getSmartContractData() case ExecuteSmartcontractCmd: cmd.executeSmartcontract() + case GetPeerID: + cmd.peerIDCmd() default: cmd.log.Error("Invalid command") } diff --git a/command/node.go b/command/node.go index 87975cac..e343eb34 100644 --- a/command/node.go +++ b/command/node.go @@ -1,5 +1,10 @@ package command +import ( + "fmt" + "os" +) + func (cmd *Command) ShutDownCmd() { msg, status := cmd.c.Shutdown() if !status { @@ -8,3 +13,15 @@ func (cmd *Command) ShutDownCmd() { } cmd.log.Info("Shutdown initiated successfully, " + msg) } + +func (cmd *Command) peerIDCmd() { + msg, status := cmd.c.PeerID() + if !status { + cmd.log.Error("Failed to fetch peer ID of the node", "msg", msg) + return + } + _, err := fmt.Fprint(os.Stdout, msg, "\n") + if err != nil { + cmd.log.Error(err.Error()) + } +} diff --git a/server/node.go b/server/node.go new file mode 100644 index 00000000..37ccf3ed --- /dev/null +++ b/server/node.go @@ -0,0 +1,9 @@ +package server + +import ( + "github.com/rubixchain/rubixgoplatform/wrapper/ensweb" +) + +func (s *Server) APIPeerID(req *ensweb.Request) *ensweb.Result { + return s.BasicResponse(req, true, s.c.GetPeerID(), nil) +} diff --git a/server/server.go b/server/server.go index fffb9d7d..32267fc8 100644 --- a/server/server.go +++ b/server/server.go @@ -154,6 +154,7 @@ func (s *Server) RegisterRoutes() { s.AddRoute(setup.APIRegisterCallBackURL, "POST", s.AuthHandle(s.APIRegisterCallbackURL, true, s.AuthError, false)) s.AddRoute(setup.APIGetTxnByNode, "GET", s.AuthHandle(s.APIGetTxnByNode, true, s.AuthError, false)) s.AddRoute(setup.APIRemoveTokenChainBlock, "POST", s.AuthHandle(s.APIRemoveTokenChainBlock, true, s.AuthError, false)) + s.AddRoute(setup.APIPeerID, "GET", s.AuthHandle(s.APIPeerID, false, s.AuthError, false)) } func (s *Server) ExitFunc() error { diff --git a/setup/setup.go b/setup/setup.go index 2763b0d4..81bba0a5 100644 --- a/setup/setup.go +++ b/setup/setup.go @@ -61,6 +61,7 @@ const ( APIRegisterCallBackURL string = "/api/register-callback-url" APIGetTxnByNode string = "/api/get-by-node" APIRemoveTokenChainBlock string = "/api/remove-token-chain-block" + APIPeerID string = "/api/get-peer-id" ) // jwt.RegisteredClaims From 07a3db4d41ccba0a4bc970f4f96e5dedea900305 Mon Sep 17 00:00:00 2001 From: Maneesha-rubix Date: Thu, 18 Apr 2024 11:43:02 +0530 Subject: [PATCH 31/62] fixed occupied port and peer connection issue --- command/did.go | 19 ------------------- core/ipfsport/peer.go | 37 +++++++++++++++++++++++++++++++++++-- core/token_pin_check.go | 18 ++++++++++++++++-- 3 files changed, 51 insertions(+), 23 deletions(-) diff --git a/command/did.go b/command/did.go index d820ece9..f897178a 100644 --- a/command/did.go +++ b/command/did.go @@ -255,25 +255,6 @@ func (cmd *Command) SignatureResponse(br *model.BasicResponse, timeout ...time.D } switch sr.Mode { case did.LightDIDMode: - // fmt.Println(cmd.privKeyFile) - // privKey, err := ioutil.ReadFile(cmd.privKeyFile) - - // if err != nil { - // return "Failed to open private key file, " + err.Error(), false - // } - - // Privkey, _, err := crypto.DecodeBIPKeyPair(cmd.privPWD, privKey, nil) - // if err != nil { - // return "Failed to decode private key " + err.Error(), false - // } - - // privkeyback := secp256k1.PrivKeyFromBytes(Privkey) - // privKeySer := privkeyback.ToECDSA() - // sig, err := crypto.BIPSign(privKeySer, sr.Hash) - // if err != nil { - // return "Failed to sign, " + err.Error(), false - // } - // sresp.Signature.Signature = sig sresp.Password = password case did.BasicDIDMode: sresp.Password = password diff --git a/core/ipfsport/peer.go b/core/ipfsport/peer.go index d5c68fb8..7fd4d2f3 100644 --- a/core/ipfsport/peer.go +++ b/core/ipfsport/peer.go @@ -3,6 +3,7 @@ package ipfsport import ( "context" "fmt" + "net" "net/http" "path" "sync" @@ -66,13 +67,38 @@ func (pm *PeerManager) getPeerPort() uint16 { for i, status := range pm.ps { if !status { pm.ps[i] = true - return pm.startPort + uint16(i) + port := pm.startPort + uint16(i) + availability := isPortAvailable(port) + + if availability { + fmt.Println("available port: ", port, availability) + return pm.startPort + uint16(i) + } else { + fmt.Println("NOT available port: ", port, availability) + } } } return 0 } +func isPortAvailable(port uint16) bool { + // Convert uint16 port to int + portInt := int(port) + + // Attempt to listen on the port + listener, err := net.Listen("tcp", fmt.Sprintf(":%d", portInt)) + if err != nil { + // Port is not available + return false + } + defer listener.Close() + + // Port is available + return true +} + func (pm *PeerManager) releasePeerPort(port uint16) bool { + fmt.Println("trying to release peer port ", port) pm.lock.Lock() defer pm.lock.Unlock() offset := uint16(port) - pm.startPort @@ -148,8 +174,11 @@ func (pm *PeerManager) OpenPeerConn(peerID string, did string, appname string) ( did: did, } proto := "/x/" + appname + "/1.0" + // fmt.Println("proto:", proto) addr := "/ip4/127.0.0.1/tcp/" + fmt.Sprintf("%d", portNum) + // fmt.Println("addr:", addr) peer := "/p2p/" + peerID + // fmt.Println("peer:", peer) resp, err := pm.ipfs.Request("p2p/forward", proto, addr, peer).Send(context.Background()) if err != nil { pm.log.Error("failed make forward request") @@ -157,13 +186,17 @@ func (pm *PeerManager) OpenPeerConn(peerID string, did string, appname string) ( return nil, err } defer resp.Close() + var result bool if resp.Error != nil { + pm.log.Error("error in forward request") - pm.releasePeerPort(portNum) + result = pm.releasePeerPort(portNum) + fmt.Println("result of release peer port ", result) return nil, resp.Error } p.Client, err = ensweb.NewClient(scfg, p.log) if err != nil { + fmt.Println("peer in OpenPeerConn ln 199 ", p) pm.log.Error("failed to create ensweb clent", "err", err) pm.releasePeerPort(portNum) return nil, err diff --git a/core/token_pin_check.go b/core/token_pin_check.go index ce7c9a04..56c55901 100644 --- a/core/token_pin_check.go +++ b/core/token_pin_check.go @@ -1,6 +1,7 @@ package core import ( + "fmt" "sync" "github.com/rubixchain/rubixgoplatform/core/wallet" @@ -88,13 +89,26 @@ func (c *Core) pinCheck(token string, index int, senderPeerId string, receiverPe } else { peerIdRolemap := make(map[string]int) for _, peerId := range t { + fmt.Println("try1 for peer id ", peerId) p, err := c.connectPeer(peerId) - if err != nil { - c.log.Error("Error connecting to peer ", "peerId", peerId, "err", err) + if err != nil || p == nil { + + c.log.Error("Error connecting to peer try 1", "peerId", peerId, "err", err) + result.Status = true + result.Owners = nil + result.Error = err + results[index] = result + } + fmt.Println("try2 for peer id ", peerId) + p, err = c.connectPeer(peerId) + if err != nil || p == nil { + + c.log.Error("Error connecting to peer try 2", "peerId", peerId, "err", err) result.Status = true result.Owners = nil result.Error = err results[index] = result + continue } req := PinStatusReq{ Token: token, From f0018662fd239b6aae16e64a1f76481f9bc74b8b Mon Sep 17 00:00:00 2001 From: Maneesha-rubix Date: Mon, 22 Apr 2024 14:24:41 +0530 Subject: [PATCH 32/62] removing changes on port unavailability issue --- block/block.go | 1 - core/ipfsport/peer.go | 36 +----------------------------------- core/token_pin_check.go | 18 ++---------------- 3 files changed, 3 insertions(+), 52 deletions(-) diff --git a/block/block.go b/block/block.go index 4220f5af..4c49134c 100644 --- a/block/block.go +++ b/block/block.go @@ -369,7 +369,6 @@ func (b *Block) VerifySignature(dc didmodule.DIDCrypto) error { } ok, err := dc.PvtVerify([]byte(h), util.StrToHex(s)) if err != nil || !ok { - fmt.Println("err:", err) return fmt.Errorf("failed to verify did signature") } return nil diff --git a/core/ipfsport/peer.go b/core/ipfsport/peer.go index 7fd4d2f3..2dc9d51e 100644 --- a/core/ipfsport/peer.go +++ b/core/ipfsport/peer.go @@ -3,7 +3,6 @@ package ipfsport import ( "context" "fmt" - "net" "net/http" "path" "sync" @@ -67,38 +66,13 @@ func (pm *PeerManager) getPeerPort() uint16 { for i, status := range pm.ps { if !status { pm.ps[i] = true - port := pm.startPort + uint16(i) - availability := isPortAvailable(port) - - if availability { - fmt.Println("available port: ", port, availability) - return pm.startPort + uint16(i) - } else { - fmt.Println("NOT available port: ", port, availability) - } + return pm.startPort + uint16(i) } } return 0 } -func isPortAvailable(port uint16) bool { - // Convert uint16 port to int - portInt := int(port) - - // Attempt to listen on the port - listener, err := net.Listen("tcp", fmt.Sprintf(":%d", portInt)) - if err != nil { - // Port is not available - return false - } - defer listener.Close() - - // Port is available - return true -} - func (pm *PeerManager) releasePeerPort(port uint16) bool { - fmt.Println("trying to release peer port ", port) pm.lock.Lock() defer pm.lock.Unlock() offset := uint16(port) - pm.startPort @@ -174,11 +148,8 @@ func (pm *PeerManager) OpenPeerConn(peerID string, did string, appname string) ( did: did, } proto := "/x/" + appname + "/1.0" - // fmt.Println("proto:", proto) addr := "/ip4/127.0.0.1/tcp/" + fmt.Sprintf("%d", portNum) - // fmt.Println("addr:", addr) peer := "/p2p/" + peerID - // fmt.Println("peer:", peer) resp, err := pm.ipfs.Request("p2p/forward", proto, addr, peer).Send(context.Background()) if err != nil { pm.log.Error("failed make forward request") @@ -186,17 +157,12 @@ func (pm *PeerManager) OpenPeerConn(peerID string, did string, appname string) ( return nil, err } defer resp.Close() - var result bool if resp.Error != nil { - pm.log.Error("error in forward request") - result = pm.releasePeerPort(portNum) - fmt.Println("result of release peer port ", result) return nil, resp.Error } p.Client, err = ensweb.NewClient(scfg, p.log) if err != nil { - fmt.Println("peer in OpenPeerConn ln 199 ", p) pm.log.Error("failed to create ensweb clent", "err", err) pm.releasePeerPort(portNum) return nil, err diff --git a/core/token_pin_check.go b/core/token_pin_check.go index 56c55901..ce7c9a04 100644 --- a/core/token_pin_check.go +++ b/core/token_pin_check.go @@ -1,7 +1,6 @@ package core import ( - "fmt" "sync" "github.com/rubixchain/rubixgoplatform/core/wallet" @@ -89,26 +88,13 @@ func (c *Core) pinCheck(token string, index int, senderPeerId string, receiverPe } else { peerIdRolemap := make(map[string]int) for _, peerId := range t { - fmt.Println("try1 for peer id ", peerId) p, err := c.connectPeer(peerId) - if err != nil || p == nil { - - c.log.Error("Error connecting to peer try 1", "peerId", peerId, "err", err) - result.Status = true - result.Owners = nil - result.Error = err - results[index] = result - } - fmt.Println("try2 for peer id ", peerId) - p, err = c.connectPeer(peerId) - if err != nil || p == nil { - - c.log.Error("Error connecting to peer try 2", "peerId", peerId, "err", err) + if err != nil { + c.log.Error("Error connecting to peer ", "peerId", peerId, "err", err) result.Status = true result.Owners = nil result.Error = err results[index] = result - continue } req := PinStatusReq{ Token: token, From 59913ce5f07922da1f57c2feb65eb8bfe10f8c31 Mon Sep 17 00:00:00 2001 From: Ashita Gupta Date: Tue, 23 Apr 2024 17:18:47 +0530 Subject: [PATCH 33/62] 7 quorums fix --- core/quorum_initiator.go | 46 +++++++++++++++++++++++++++++++--------- 1 file changed, 36 insertions(+), 10 deletions(-) diff --git a/core/quorum_initiator.go b/core/quorum_initiator.go index 4df6f291..b088a91c 100644 --- a/core/quorum_initiator.go +++ b/core/quorum_initiator.go @@ -62,6 +62,7 @@ type ConsensusResult struct { RunningCount int SuccessCount int FailedCount int + RunsTotal int } type ConsensusStatus struct { @@ -236,6 +237,7 @@ func (c *Core) initiateConsensus(cr *ConensusRequest, sc *contract.Contract, dc RunningCount: 0, SuccessCount: 0, FailedCount: 0, + RunsTotal: 0, }, } reqPledgeTokens := float64(0) @@ -381,7 +383,7 @@ func (c *Core) initiateConsensus(cr *ConensusRequest, sc *contract.Contract, dc c.log.Debug("String: token is ", token, " issuetype is ", issueType) issueTypeInt, err1 := strconv.Atoi(issueType) if err1 != nil { - errMsg := fmt.Sprintf("Consensus failed due to token chain sync issue, issueType string conversion, err %v", err1) + errMsg := fmt.Sprintf("Consensus failed due to token chain sync issue, issueType string conversion, err %v", err1) c.log.Error(errMsg) return nil, nil, fmt.Errorf(errMsg) } @@ -397,7 +399,7 @@ func (c *Core) initiateConsensus(cr *ConensusRequest, sc *contract.Contract, dc syncIssueTokenDetails.TokenStatus = wallet.TokenChainSyncIssue c.log.Debug("sync issue token details status updated", syncIssueTokenDetails) c.w.UpdateToken(syncIssueTokenDetails) - return nil, nil, errors.New(br.Message) + return nil, nil, errors.New(br.Message) } } if !br.Status { @@ -656,29 +658,53 @@ func (c *Core) finishConsensus(id string, qt int, p *ipfsport.Peer, status bool, defer c.qlock.Unlock() cs, ok := c.quorumRequest[id] if !ok { + fmt.Println("failed to get quorum consensus") if p != nil { p.Close() } return } + pd, ok := c.pd[id] //getting details of quorums who pledged + if !ok { + fmt.Println("failed to get pledged token details") + if p != nil { + p.Close() + } + return + } + keys := make([]string, 0, len(pd.PledgedTokens)) + for k := range pd.PledgedTokens { + keys = append(keys, k) + } + key := keys[0] + switch qt { case 0: cs.Result.RunningCount-- if status { did := p.GetPeerDID() - if cs.Result.SuccessCount < MinConsensusRequired { - csig := CreditSignature{ - Signature: util.HexToStr(ss), - PrivSignature: util.HexToStr(ps), - DID: did, - Hash: hash, - } + csig := CreditSignature{ + Signature: util.HexToStr(ss), + PrivSignature: util.HexToStr(ps), + DID: did, + Hash: hash, + } + if cs.Result.SuccessCount < MinConsensusRequired-1 { + cs.P[did] = p + cs.Credit.Credit = append(cs.Credit.Credit, csig) + cs.Result.SuccessCount++ + } else if did == key && cs.Result.SuccessCount == MinConsensusRequired-1 { + cs.P[did] = p + cs.Credit.Credit = append(cs.Credit.Credit, csig) + cs.Result.SuccessCount++ + } else if cs.Result.RunsTotal == 6 && cs.Result.SuccessCount == MinConsensusRequired-1 { cs.P[did] = p cs.Credit.Credit = append(cs.Credit.Credit, csig) + cs.Result.SuccessCount++ } else { p.Close() } - cs.Result.SuccessCount++ + cs.Result.RunsTotal++ } else { cs.Result.FailedCount++ if p != nil { From 92f859cd2117386e96da7f2616957afbe73d4595 Mon Sep 17 00:00:00 2001 From: Maneesha-rubix Date: Fri, 26 Apr 2024 03:11:13 +0530 Subject: [PATCH 34/62] fixed port unavailability --- block/block.go | 4 ---- block/transaction.go | 3 --- core/ipfsport/peer.go | 29 +++++++++++++++++++++++++++-- 3 files changed, 27 insertions(+), 9 deletions(-) diff --git a/block/block.go b/block/block.go index 4f1032e2..19227f7e 100644 --- a/block/block.go +++ b/block/block.go @@ -42,10 +42,6 @@ const ( TCChildTokensKey string = "11" ) -// const ( -// PkiSignVersion int = iota -// ) - const ( TokenMintedType string = "01" TokenTransferredType string = "02" diff --git a/block/transaction.go b/block/transaction.go index 0d3a37b5..589179da 100644 --- a/block/transaction.go +++ b/block/transaction.go @@ -141,9 +141,6 @@ func newTransInfo(ctcb map[string]*Block, ti *TransInfo) map[string]interface{} if ti.RefID != "" { ntib[TIRefIDKey] = ti.RefID } - // if ti.SignVersion != "" { - // ntib[TISignVersionKey] = ti.SignVersion - // } nttbs := make(map[string]interface{}) for _, tt := range ti.Tokens { b := ctcb[tt.Token] diff --git a/core/ipfsport/peer.go b/core/ipfsport/peer.go index 2dc9d51e..b5837baa 100644 --- a/core/ipfsport/peer.go +++ b/core/ipfsport/peer.go @@ -3,6 +3,7 @@ package ipfsport import ( "context" "fmt" + "net" "net/http" "path" "sync" @@ -65,13 +66,37 @@ func (pm *PeerManager) getPeerPort() uint16 { defer pm.lock.Unlock() for i, status := range pm.ps { if !status { - pm.ps[i] = true - return pm.startPort + uint16(i) + port := pm.startPort + uint16(i) + availability := isPortAvailable(port) + + if availability { + fmt.Println("available port: ", port, availability) + pm.ps[i] = true + return pm.startPort + uint16(i) + } else { + fmt.Println("NOT available port: ", port, availability) + } } } return 0 } +func isPortAvailable(port uint16) bool { + // Convert uint16 port to int + portInt := int(port) + + // Attempt to listen on the port + listener, err := net.Listen("tcp", fmt.Sprintf(":%d", portInt)) + if err != nil { + // Port is not available + return false + } + defer listener.Close() + + // Port is available + return true +} + func (pm *PeerManager) releasePeerPort(port uint16) bool { pm.lock.Lock() defer pm.lock.Unlock() From f4db465defc88aca5d07c7a8ca1361a98ffe89d2 Mon Sep 17 00:00:00 2001 From: Ashita Gupta Date: Thu, 2 May 2024 16:57:49 +0530 Subject: [PATCH 35/62] fix for unpledging of tokens and 7 quorums --- core/core.go | 1 + core/quorum_initiator.go | 63 ++++++++++++++++++++++++++++++++++------ core/quorum_recv.go | 31 ++++++++++++++++++++ core/wallet/token.go | 18 ++++++++++++ 4 files changed, 104 insertions(+), 9 deletions(-) diff --git a/core/core.go b/core/core.go index aca89d1d..d3f31936 100644 --- a/core/core.go +++ b/core/core.go @@ -46,6 +46,7 @@ const ( APIGetTokenNumber string = "/api/get-token-number" APIGetMigratedTokenStatus string = "/api/get-Migrated-token-status" APISyncDIDArbitration string = "/api/sync-did-arbitration" + APIUnlockTokens string = "/api/unlock-tokens" ) const ( diff --git a/core/quorum_initiator.go b/core/quorum_initiator.go index b088a91c..06d15eab 100644 --- a/core/quorum_initiator.go +++ b/core/quorum_initiator.go @@ -62,7 +62,6 @@ type ConsensusResult struct { RunningCount int SuccessCount int FailedCount int - RunsTotal int } type ConsensusStatus struct { @@ -141,6 +140,11 @@ type ArbitaryStatus struct { status bool } +type TokenList struct { + Tokens []string + DID string +} + // PingSetup will setup the ping route func (c *Core) QuroumSetup() { c.l.AddRoute(APICreditStatus, "GET", c.creditStatus) @@ -150,6 +154,7 @@ func (c *Core) QuroumSetup() { c.l.AddRoute(APIUpdatePledgeToken, "POST", c.updatePledgeToken) c.l.AddRoute(APISignatureRequest, "POST", c.signatureRequest) c.l.AddRoute(APISendReceiverToken, "POST", c.updateReceiverToken) + c.l.AddRoute(APIUnlockTokens, "POST", c.unlockTokens) if c.arbitaryMode { c.l.AddRoute(APIMapDIDArbitration, "POST", c.mapDIDArbitration) c.l.AddRoute(APICheckDIDArbitration, "GET", c.chekDIDArbitration) @@ -237,7 +242,6 @@ func (c *Core) initiateConsensus(cr *ConensusRequest, sc *contract.Contract, dc RunningCount: 0, SuccessCount: 0, FailedCount: 0, - RunsTotal: 0, }, } reqPledgeTokens := float64(0) @@ -322,6 +326,10 @@ func (c *Core) initiateConsensus(cr *ConensusRequest, sc *contract.Contract, dc } } if err != nil { + unlockErr := c.checkLokedTokens(cr, ql) + if unlockErr != nil { + c.log.Error(unlockErr.Error() + "Locked tokens could not be unlocked") + } return nil, nil, err } @@ -408,7 +416,7 @@ func (c *Core) initiateConsensus(cr *ConensusRequest, sc *contract.Contract, dc } //trigger pledge finality to the quorum - pledgeFinalityError := c.quorumPledgeFinality(cr, nb) + pledgeFinalityError := c.quorumPledgeFinality(cr, nb) /////////hereeeeeeeeeee if pledgeFinalityError != nil { c.log.Error("Pledge finlaity not achieved", "err", err) return nil, nil, pledgeFinalityError @@ -672,11 +680,14 @@ func (c *Core) finishConsensus(id string, qt int, p *ipfsport.Peer, status bool, } return } - keys := make([]string, 0, len(pd.PledgedTokens)) + pledgingQuorumDID := make([]string, 0, len(pd.PledgedTokens)) for k := range pd.PledgedTokens { - keys = append(keys, k) + pledgingQuorumDID = append(pledgingQuorumDID, k) + } + var pledgingDID string + if len(pledgingQuorumDID) > 0 { + pledgingDID = pledgingQuorumDID[0] } - key := keys[0] switch qt { case 0: @@ -693,18 +704,17 @@ func (c *Core) finishConsensus(id string, qt int, p *ipfsport.Peer, status bool, cs.P[did] = p cs.Credit.Credit = append(cs.Credit.Credit, csig) cs.Result.SuccessCount++ - } else if did == key && cs.Result.SuccessCount == MinConsensusRequired-1 { + } else if did == pledgingDID && cs.Result.SuccessCount == MinConsensusRequired-1 { cs.P[did] = p cs.Credit.Credit = append(cs.Credit.Credit, csig) cs.Result.SuccessCount++ - } else if cs.Result.RunsTotal == 6 && cs.Result.SuccessCount == MinConsensusRequired-1 { + } else if cs.Result.RunningCount == 0 && cs.Result.SuccessCount == MinConsensusRequired-1 { cs.P[did] = p cs.Credit.Credit = append(cs.Credit.Credit, csig) cs.Result.SuccessCount++ } else { p.Close() } - cs.Result.RunsTotal++ } else { cs.Result.FailedCount++ if p != nil { @@ -1269,3 +1279,38 @@ func (c *Core) createCommitedTokensBlock(newBlock *block.Block, smartContractTok } return nil } + +func (c *Core) checkLokedTokens(cr *ConensusRequest, quorumList []string) error { + // var err error + pd := c.pd[cr.ReqID] + + pledgingQuorumDID := make([]string, 0, len(pd.PledgedTokens)) + for k := range pd.PledgedTokens { + pledgingQuorumDID = append(pledgingQuorumDID, k) + } + var pledgingDID string + if len(pledgingQuorumDID) > 0 { + pledgingDID = pledgingQuorumDID[0] + } + var br model.BasicResponse + for _, addr := range quorumList { + peerID, did, _ := util.ParseAddress(addr) + if did == pledgingDID { + p, err := c.pm.OpenPeerConn(peerID, did, c.getCoreAppName(peerID)) + if err != nil { + c.log.Error("Failed to get peer connection", "err", err) + return err + } + tokenList := TokenList{ + Tokens: pd.PledgedTokens[pledgingDID], + DID: pledgingDID, + } + err = p.SendJSONRequest("POST", APIUnlockTokens, nil, &tokenList, &br, true) + if err != nil { + c.log.Error("Invalid response for pledge request", "err", err) + return err + } + } + } + return nil +} diff --git a/core/quorum_recv.go b/core/quorum_recv.go index b7493fcc..a8667f24 100644 --- a/core/quorum_recv.go +++ b/core/quorum_recv.go @@ -568,6 +568,14 @@ func (c *Core) reqPledgeToken(req *ensweb.Request) *ensweb.Result { crep.Message = "Failed to parse json request" return c.l.RenderJSON(req, &crep, http.StatusOK) } + + _, ok := c.qc[did] + if !ok { + c.log.Error("Quorum is not setup") + crep.Message = "Quorum is not setup" + return c.l.RenderJSON(req, &crep, http.StatusOK) + } + if (pr.TokensRequired) < MinTrnxAmt { c.log.Error("Pledge amount is less than ", MinTrnxAmt) crep.Message = "Pledge amount is less than minimum transcation amount" @@ -1314,3 +1322,26 @@ func (c *Core) getProofverificationDetails(tokenID string, senderAddr string) (s } return receiverDID, txnId, nil } + +func (c *Core) unlockTokens(req *ensweb.Request) *ensweb.Result { + var tokenList TokenList + err := c.l.ParseJSON(req, &tokenList) + crep := model.BasicResponse{ + Status: false, + } + if err != nil { + c.log.Error("Failed to parse json request", "err", err) + crep.Message = "Failed to parse json request" + return c.l.RenderJSON(req, &crep, http.StatusOK) + } + err = c.w.UnlockLockedTokens(tokenList.DID, tokenList.Tokens) + if err != nil { + c.log.Error("Failed to update token status", "err", err) + return c.l.RenderJSON(req, &crep, http.StatusOK) + } + crep.Status = true + crep.Message = "Tokens Unlocked Successfully." + c.log.Info("Tokens Unclocked") + return c.l.RenderJSON(req, &crep, http.StatusOK) + +} diff --git a/core/wallet/token.go b/core/wallet/token.go index c32dac55..f75efbb5 100644 --- a/core/wallet/token.go +++ b/core/wallet/token.go @@ -573,3 +573,21 @@ func (w *Wallet) ReleaseAllLockedTokens() error { } return nil } + +func (w *Wallet) UnlockLockedTokens(did string, tokenList []string) error { + for _, tid := range tokenList { + var t Token + err := w.s.Read(TokenStorage, &t, "did=? AND token_id=?", did, tid) + if err != nil { + w.log.Error("Failed to update token status", "err", err) + return err + } + t.TokenStatus = TokenIsFree + err = w.s.Update(TokenStorage, &t, "did=? AND token_id=?", did, tid) + if err != nil { + w.log.Error("Failed to update token status", "err", err) + return err + } + } + return nil +} From 1539d2b6172bd0052d444eefe27d64447a2dba5a Mon Sep 17 00:00:00 2001 From: Ashita Gupta <38140293+ashi31@users.noreply.github.com> Date: Thu, 2 May 2024 17:10:56 +0530 Subject: [PATCH 36/62] removed comments --- core/quorum_initiator.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/quorum_initiator.go b/core/quorum_initiator.go index 06d15eab..cf31db96 100644 --- a/core/quorum_initiator.go +++ b/core/quorum_initiator.go @@ -416,7 +416,7 @@ func (c *Core) initiateConsensus(cr *ConensusRequest, sc *contract.Contract, dc } //trigger pledge finality to the quorum - pledgeFinalityError := c.quorumPledgeFinality(cr, nb) /////////hereeeeeeeeeee + pledgeFinalityError := c.quorumPledgeFinality(cr, nb) if pledgeFinalityError != nil { c.log.Error("Pledge finlaity not achieved", "err", err) return nil, nil, pledgeFinalityError From 8eadd963cfd8149ceb9b152d95fa63737ac4edec Mon Sep 17 00:00:00 2001 From: Maneesha-rubix Date: Mon, 6 May 2024 15:40:58 +0530 Subject: [PATCH 37/62] updated Readme --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 2371d67c..f457f546 100644 --- a/README.md +++ b/README.md @@ -102,7 +102,7 @@ This following options are used for this command -port string Server/Host port (default "20000") -didType int - DID type (0-Light Mode, 1-Basic Mode, 2-Standard Mode, 3-Wallet Mode) (default 0) + DID type (0-Basic Mode, 1-Standard Mode, 2-Wallet Mode, 3-Child Mode, 4-Light Mode) (default 0) -didSecret string DID secret (default "My DID Secret") -privPWD string From f98fa984e0c48244d45d26255474e44e70a6fabf Mon Sep 17 00:00:00 2001 From: Maneesha-rubix Date: Mon, 6 May 2024 16:28:25 +0530 Subject: [PATCH 38/62] changing variable and function names --- client/did.go | 12 ++++----- command/did.go | 4 +-- contract/contract.go | 2 +- core/core.go | 16 ++++++------ core/did.go | 4 +-- core/migrate.go | 2 +- core/part_token.go | 8 +++--- core/quorum_initiator.go | 8 +++--- core/token_pin_check.go | 2 +- did/basic.go | 2 +- did/child.go | 2 +- did/did.go | 12 ++++----- did/{light.go => lite.go} | 34 ++++++++++++------------- did/model.go | 2 +- did/quorum.go | 2 +- did/{quorum_light.go => quorum_lite.go} | 6 ++--- did/standard.go | 2 +- did/wallet.go | 2 +- grpcclient/token.go | 2 +- grpcserver/did.go | 2 +- server/did.go | 4 +-- 21 files changed, 65 insertions(+), 65 deletions(-) rename did/{light.go => lite.go} (78%) rename did/{quorum_light.go => quorum_lite.go} (96%) diff --git a/client/did.go b/client/did.go index da91053d..de362662 100644 --- a/client/did.go +++ b/client/did.go @@ -48,11 +48,11 @@ func (c *Client) GetAllDIDs() (*model.GetAccountInfo, error) { } func (c *Client) CreateDID(cfg *did.DIDCreate) (string, bool) { - if cfg.Type < did.LightDIDMode && cfg.Type > did.WalletDIDMode { + if cfg.Type < did.LiteDIDMode && cfg.Type > did.WalletDIDMode { return "Invalid DID mode", false } switch cfg.Type { - case did.LightDIDMode: + case did.LiteDIDMode: cfg.PubKeyFile = "" case did.BasicDIDMode: if cfg.ImgFile == "" { @@ -126,7 +126,7 @@ func (c *Client) CreateDID(cfg *did.DIDCreate) (string, bool) { fields[setup.DIDConfigField] = string(jd) files := make(map[string]string) - if cfg.Type != did.LightDIDMode { + if cfg.Type != did.LiteDIDMode { if cfg.ImgFile != "" { files["image"] = cfg.ImgFile } @@ -156,12 +156,12 @@ func (c *Client) CreateDID(cfg *did.DIDCreate) (string, bool) { } func (c *Client) SetupDID(dc *did.DIDCreate) (string, bool) { - if dc.Type < did.BasicDIDMode && dc.Type > did.LightDIDMode { + if dc.Type < did.BasicDIDMode && dc.Type > did.LiteDIDMode { return "Invalid DID mode", false } switch dc.Type { - case did.LightDIDMode: + case did.LiteDIDMode: if !strings.Contains(dc.PubKeyFile, did.PubKeyFileName) || !strings.Contains(dc.PrivKeyFile, did.PvtKeyFileName) || !strings.Contains(dc.MnemonicFile, did.MnemonicFileName) { @@ -196,7 +196,7 @@ func (c *Client) SetupDID(dc *did.DIDCreate) (string, bool) { fields[setup.DIDConfigField] = string(jd) files := make(map[string]string) - if dc.Type != did.LightDIDMode { + if dc.Type != did.LiteDIDMode { if dc.PubImgFile != "" { files["pub_image"] = dc.PubImgFile } diff --git a/command/did.go b/command/did.go index 637d20fd..42d6fef0 100644 --- a/command/did.go +++ b/command/did.go @@ -50,7 +50,7 @@ func (cmd *Command) CreateDID() { } cmd.quorumPWD = pwd } - if cmd.didType == did.LightDIDMode { + if cmd.didType == did.LiteDIDMode { if cmd.privKeyFile == "" || cmd.pubKeyFile == "" { cmd.log.Error("private key & public key file names required") return @@ -254,7 +254,7 @@ func (cmd *Command) SignatureResponse(br *model.BasicResponse, timeout ...time.D Mode: sr.Mode, } switch sr.Mode { - case did.LightDIDMode: + case did.LiteDIDMode: sresp.Password = password case did.BasicDIDMode: sresp.Password = password diff --git a/contract/contract.go b/contract/contract.go index 2cd19d0c..d19334e3 100644 --- a/contract/contract.go +++ b/contract/contract.go @@ -446,7 +446,7 @@ func (c *Contract) VerifySignature(dc did.DIDCrypto) error { //If the ss i.e., share signature is empty, then its a Pki sign, so call PvtVerify //Else it is NLSS based sign, so call NlssVerify - didType := dc.GetSignVersion() + didType := dc.GetSignType() if didType == did.BIPVersion { ok, err := dc.PvtVerify([]byte(hs), util.StrToHex(ps)) diff --git a/core/core.go b/core/core.go index 8ceeff82..c337586f 100644 --- a/core/core.go +++ b/core/core.go @@ -508,8 +508,8 @@ func (c *Core) SetupDID(reqID string, didStr string) (did.DIDCrypto, error) { return nil, fmt.Errorf("faield to get did channel") } switch dt.Type { - case did.LightDIDMode: - return did.InitDIDLight(didStr, c.didDir, dc), nil + case did.LiteDIDMode: + return did.InitDIDLite(didStr, c.didDir, dc), nil case did.BasicDIDMode: return did.InitDIDBasic(didStr, c.didDir, dc), nil case did.StandardDIDMode: @@ -523,7 +523,7 @@ func (c *Core) SetupDID(reqID string, didStr string) (did.DIDCrypto, error) { } } -// Initializes the did in it's corresponding did mode (basic/ light) +// Initializes the did in it's corresponding did mode (basic/ lite) func (c *Core) SetupForienDID(didStr string) (did.DIDCrypto, error) { err := c.FetchDID(didStr) if err != nil { @@ -544,7 +544,7 @@ func (c *Core) SetupForienDID(didStr string) (did.DIDCrypto, error) { return c.InitialiseDID(didStr, didtype) } -// Initializes the quorum in it's corresponding did mode (basic/ light) +// Initializes the quorum in it's corresponding did mode (basic/ lite) func (c *Core) SetupForienDIDQuorum(didStr string) (did.DIDCrypto, error) { err := c.FetchDID(didStr) if err != nil { @@ -565,7 +565,7 @@ func (c *Core) SetupForienDIDQuorum(didStr string) (did.DIDCrypto, error) { switch didtype { case did.BasicDIDMode: return did.InitDIDQuorumc(didStr, c.didDir, ""), nil - case did.LightDIDMode: + case did.LiteDIDMode: return did.InitDIDQuorum_Lt(didStr, c.didDir, ""), nil default: return nil, fmt.Errorf("invalid did type") @@ -600,15 +600,15 @@ func (c *Core) GetPeerID() string { return c.peerID } -// Initializes the did in it's corresponding did mode (basic/ light) +// Initializes the did in it's corresponding did mode (basic/ lite) func (c *Core) InitialiseDID(didStr string, didType int) (did.DIDCrypto, error) { err := c.FetchDID(didStr) if err != nil { return nil, err } switch didType { - case did.LightDIDMode: - return did.InitDIDLight(didStr, c.didDir, nil), nil + case did.LiteDIDMode: + return did.InitDIDLite(didStr, c.didDir, nil), nil case did.BasicDIDMode: return did.InitDIDBasic(didStr, c.didDir, nil), nil default: diff --git a/core/did.go b/core/did.go index 95293e3c..5818135c 100644 --- a/core/did.go +++ b/core/did.go @@ -30,13 +30,13 @@ func (c *Core) GetDIDAccess(req *model.GetDIDAccess) *model.DIDAccessResponse { resp.Message = "Password does not match" return resp } - } else if dt.Type == did.LightDIDMode { + } else if dt.Type == did.LiteDIDMode { _, ok := c.ValidateDIDToken(req.Token, setup.ChanllegeTokenType, req.DID) if !ok { resp.Message = "Invalid token" return resp } - dc := did.InitDIDLight(req.DID, c.didDir, nil) + dc := did.InitDIDLite(req.DID, c.didDir, nil) ok, err := dc.PvtVerify([]byte(req.Token), req.Signature) if err != nil { c.log.Error("Failed to verify DID signature", "err", err) diff --git a/core/migrate.go b/core/migrate.go index 314125ba..cd55f0b0 100644 --- a/core/migrate.go +++ b/core/migrate.go @@ -164,7 +164,7 @@ func (c *Core) migrateNode(reqID string, m *MigrateRequest, didDir string) error QuorumPWD: m.QuorumPWD, } - if didCreate.Type != didm.LightDIDMode { + if didCreate.Type != didm.LiteDIDMode { didCreate = didm.DIDCreate{ DIDImgFileName: rubixDir + "DATA/" + d[0].DID + "/DID.png", PubImgFile: rubixDir + "DATA/" + d[0].DID + "/PublicShare.png", diff --git a/core/part_token.go b/core/part_token.go index 1e7aca3f..5e906911 100644 --- a/core/part_token.go +++ b/core/part_token.go @@ -96,7 +96,7 @@ func (c *Core) GetTokens(dc did.DIDCrypto, did string, value float64) ([]wallet. } idx := make([]int, 0) rpt := make([]wallet.Token, 0) - for i, _ := range pt { + for i := range pt { if pt[i].TokenValue <= rem { wt = append(wt, pt[i]) rem = floatPrecision(rem-pt[i].TokenValue, 10) @@ -169,7 +169,7 @@ func (c *Core) createPartToken(dc did.DIDCrypto, did string, tkn string, parts [ // check part split not crossing RBT amount := float64(0) - for i, _ := range parts { + for i := range parts { amount = amount + parts[i] amount = floatPrecision(amount, MaxDecimalPlaces) if amount > t.TokenValue { @@ -193,7 +193,7 @@ func (c *Core) createPartToken(dc did.DIDCrypto, did string, tkn string, parts [ c.log.Error("failed to get parent detials", "err", err) return nil, err } - for i, _ := range parts { + for i := range parts { rt := &rac.RacType{ Type: c.RACPartTokenType(), DID: did, @@ -303,7 +303,7 @@ func (c *Core) createPartToken(dc did.DIDCrypto, did string, tkn string, parts [ return nil, err } npt := make([]wallet.Token, 0) - for i, _ := range parts { + for i := range parts { ptkn := &wallet.Token{ TokenID: pts[i], ParentTokenID: tkn, diff --git a/core/quorum_initiator.go b/core/quorum_initiator.go index 6bea3817..da5cef74 100644 --- a/core/quorum_initiator.go +++ b/core/quorum_initiator.go @@ -174,11 +174,11 @@ func (c *Core) SetupQuorum(didStr string, pwd string, pvtKeyPwd string) error { } //To support NLSS backward compatibility, - //If the Quorum's did is created in light mode, + //If the Quorum's did is created in lite mode, //it will initiate DIDQuorum_Lt, and if it is in basic mode, //it will initiate DIDQuorumc switch dt.Type { - case did.LightDIDMode: + case did.LiteDIDMode: dc := did.InitDIDQuorum_Lt(didStr, c.didDir, pwd) if dc == nil { c.log.Error("Failed to setup quorum") @@ -186,7 +186,7 @@ func (c *Core) SetupQuorum(didStr string, pwd string, pvtKeyPwd string) error { } c.qc[didStr] = dc if pvtKeyPwd != "" { - dc := did.InitDIDLightWithPassword(didStr, c.didDir, pvtKeyPwd) + dc := did.InitDIDLiteWithPassword(didStr, c.didDir, pvtKeyPwd) if dc == nil { c.log.Error("Failed to setup quorum as dc is nil") return fmt.Errorf("failed to setup quorum") @@ -714,7 +714,7 @@ func (c *Core) finishConsensus(id string, qt int, p *ipfsport.Peer, status bool, var signVersion string - //signVersion = 0 => Pki based sign in light mode + //signVersion = 0 => Pki based sign in lite mode //signVersion = 1 => Nlss based sign in basic mode if util.HexToStr(ss) == "" { signVersion = "0" diff --git a/core/token_pin_check.go b/core/token_pin_check.go index c6d50984..e1306369 100644 --- a/core/token_pin_check.go +++ b/core/token_pin_check.go @@ -114,7 +114,7 @@ func (c *Core) pinCheck(token string, index int, senderPeerId string, receiverPe } } - for peerId := range peerIdRolemap { + for peerId, _ := range peerIdRolemap { if peerIdRolemap[peerId] == wallet.OwnerRole { c.log.Error("Token has multiple Pins") result.Status = true diff --git a/did/basic.go b/did/basic.go index 1e4730ad..51aa080a 100644 --- a/did/basic.go +++ b/did/basic.go @@ -63,7 +63,7 @@ func (d *DIDBasic) GetDID() string { return d.did } -func (d *DIDBasic) GetSignVersion() int { +func (d *DIDBasic) GetSignType() int { return NlssVersion } diff --git a/did/child.go b/did/child.go index 47fc7d15..e97da41d 100644 --- a/did/child.go +++ b/did/child.go @@ -64,7 +64,7 @@ func (d *DIDChild) GetDID() string { return d.did } -func (d *DIDChild) GetSignVersion() int { +func (d *DIDChild) GetSignType() int { return NlssVersion } diff --git a/did/did.go b/did/did.go index fabaacd6..7edf5ba7 100644 --- a/did/did.go +++ b/did/did.go @@ -40,7 +40,7 @@ type DID struct { type DIDCrypto interface { GetDID() string - GetSignVersion() int + GetSignType() int Sign(hash string) ([]byte, []byte, error) NlssVerify(hash string, didSig []byte, pvtSig []byte) (bool, error) PvtSign(hash []byte) ([]byte, error) @@ -72,8 +72,8 @@ func (d *DID) CreateDID(didCreate *DIDCreate) (string, error) { return "", err } - //In light mode, did is simply the SHA-256 hash of the public key - if didCreate.Type == LightDIDMode { + //In lite mode, did is simply the SHA-256 hash of the public key + if didCreate.Type == LiteDIDMode { if didCreate.PrivPWD == "" { d.log.Error("password required for creating", "err", err) return "", err @@ -270,7 +270,7 @@ func (d *DID) CreateDID(didCreate *DIDCreate) (string, error) { if err != nil { return "", err } - } else if didCreate.Type != LightDIDMode { + } else if didCreate.Type != LiteDIDMode { if didCreate.QuorumPWD == "" { if didCreate.PrivPWD != "" { didCreate.QuorumPWD = didCreate.PrivPWD @@ -342,7 +342,7 @@ func (d *DID) MigrateDID(didCreate *DIDCreate) (string, error) { return "", err } - if didCreate.Type != LightDIDMode { + if didCreate.Type != LiteDIDMode { _, err = util.Filecopy(didCreate.DIDImgFileName, dirName+"/public/"+DIDImgFileName) if err != nil { d.log.Error("failed to copy did image", "err", err) @@ -407,7 +407,7 @@ func (d *DID) MigrateDID(didCreate *DIDCreate) (string, error) { } } - if didCreate.Type != LightDIDMode { + if didCreate.Type != LiteDIDMode { if didCreate.QuorumPrivKeyFile == "" || didCreate.QuorumPubKeyFile == "" { pvtKey, pubKey, err := crypto.GenerateKeyPair(&crypto.CryptoConfig{Alg: crypto.ECDSAP256, Pwd: didCreate.QuorumPWD}) if err != nil { diff --git a/did/light.go b/did/lite.go similarity index 78% rename from did/light.go rename to did/lite.go index d3f11890..beccd88a 100644 --- a/did/light.go +++ b/did/lite.go @@ -12,24 +12,24 @@ import ( "github.com/rubixchain/rubixgoplatform/util" ) -// DIDLight will handle Light DID -type DIDLight struct { +// DIDLite will handle Light DID +type DIDLite struct { did string dir string ch *DIDChan pwd string } -// InitDIDLight will return the Light did handle -func InitDIDLight(did string, baseDir string, ch *DIDChan) *DIDLight { - return &DIDLight{did: did, dir: util.SanitizeDirPath(baseDir) + did + "/", ch: ch} +// InitDIDLite will return the Light did handle +func InitDIDLite(did string, baseDir string, ch *DIDChan) *DIDLite { + return &DIDLite{did: did, dir: util.SanitizeDirPath(baseDir) + did + "/", ch: ch} } -func InitDIDLightWithPassword(did string, baseDir string, pwd string) *DIDLight { - return &DIDLight{did: did, dir: util.SanitizeDirPath(baseDir) + did + "/", pwd: pwd} +func InitDIDLiteWithPassword(did string, baseDir string, pwd string) *DIDLite { + return &DIDLite{did: did, dir: util.SanitizeDirPath(baseDir) + did + "/", pwd: pwd} } -func (d *DIDLight) getPassword() (string, error) { +func (d *DIDLite) getPassword() (string, error) { if d.pwd != "" { return d.pwd, nil } @@ -41,7 +41,7 @@ func (d *DIDLight) getPassword() (string, error) { Message: "Password needed", Result: SignReqData{ ID: d.ch.ID, - Mode: LightDIDMode, + Mode: LiteDIDMode, }, } d.ch.OutChan <- sr @@ -60,19 +60,19 @@ func (d *DIDLight) getPassword() (string, error) { return d.pwd, nil } -func (d *DIDLight) GetDID() string { +func (d *DIDLite) GetDID() string { return d.did } // When the did creation and signing is done in Light mode, // this function returns the sign version as BIPVersion = 0 -func (d *DIDLight) GetSignVersion() int { +func (d *DIDLite) GetSignType() int { return BIPVersion } -// PKI based sign in light mode -// In light mode, the sign function returns only the private signature, unlike the basic mode -func (d *DIDLight) Sign(hash string) ([]byte, []byte, error) { +// PKI based sign in lite mode +// In lite mode, the sign function returns only the private signature, unlike the basic mode +func (d *DIDLite) Sign(hash string) ([]byte, []byte, error) { pvtKeySign, err := d.PvtSign([]byte(hash)) bs := []byte{} @@ -80,7 +80,7 @@ func (d *DIDLight) Sign(hash string) ([]byte, []byte, error) { } // verify nlss based signatures -func (d *DIDLight) NlssVerify(hash string, pvtShareSig []byte, pvtKeySIg []byte) (bool, error) { +func (d *DIDLite) NlssVerify(hash string, pvtShareSig []byte, pvtKeySIg []byte) (bool, error) { //read senderDID didImg, err := util.GetPNGImagePixels(d.dir + DIDImgFileName) if err != nil { @@ -135,7 +135,7 @@ func (d *DIDLight) NlssVerify(hash string, pvtShareSig []byte, pvtKeySIg []byte) } -func (d *DIDLight) PvtSign(hash []byte) ([]byte, error) { +func (d *DIDLite) PvtSign(hash []byte) ([]byte, error) { privKey, err := ioutil.ReadFile(d.dir + PvtKeyFileName) if err != nil { return nil, err @@ -161,7 +161,7 @@ func (d *DIDLight) PvtSign(hash []byte) ([]byte, error) { } // Verify PKI based signature -func (d *DIDLight) PvtVerify(hash []byte, sign []byte) (bool, error) { +func (d *DIDLite) PvtVerify(hash []byte, sign []byte) (bool, error) { pubKey, err := ioutil.ReadFile(d.dir + PubKeyFileName) if err != nil { return false, err diff --git a/did/model.go b/did/model.go index 2496fda0..bf18b21f 100644 --- a/did/model.go +++ b/did/model.go @@ -5,7 +5,7 @@ const ( StandardDIDMode WalletDIDMode ChildDIDMode - LightDIDMode + LiteDIDMode ) const ( diff --git a/did/quorum.go b/did/quorum.go index 3b964b68..d1955d8c 100644 --- a/did/quorum.go +++ b/did/quorum.go @@ -48,7 +48,7 @@ func (d *DIDQuorum) GetDID() string { return d.did } -func (d *DIDQuorum) GetSignVersion() int { +func (d *DIDQuorum) GetSignType() int { return NlssVersion } diff --git a/did/quorum_light.go b/did/quorum_lite.go similarity index 96% rename from did/quorum_light.go rename to did/quorum_lite.go index 5926cf63..a56f7172 100644 --- a/did/quorum_light.go +++ b/did/quorum_lite.go @@ -11,7 +11,7 @@ import ( "github.com/rubixchain/rubixgoplatform/util" ) -// DIDQuorum_Lt will handle light DID +// DIDQuorum_Lt will handle lite DID type DIDQuorum_Lt struct { did string dir string @@ -20,7 +20,7 @@ type DIDQuorum_Lt struct { pubKey crypto.PublicKey } -// InitDIDQuorum_Lt will return the Quorum did handle in light mode +// InitDIDQuorum_Lt will return the Quorum did handle in lite mode func InitDIDQuorum_Lt(did string, baseDir string, pwd string) *DIDQuorum_Lt { d := &DIDQuorum_Lt{did: did, dir: util.SanitizeDirPath(baseDir) + did + "/", pwd: pwd} if d.pwd != "" { @@ -49,7 +49,7 @@ func (d *DIDQuorum_Lt) GetDID() string { return d.did } -func (d *DIDQuorum_Lt) GetSignVersion() int { +func (d *DIDQuorum_Lt) GetSignType() int { return BIPVersion } diff --git a/did/standard.go b/did/standard.go index 561a168e..d4dbe999 100644 --- a/did/standard.go +++ b/did/standard.go @@ -55,7 +55,7 @@ func (d *DIDStandard) GetDID() string { return d.did } -func (d *DIDStandard) GetSignVersion() int { +func (d *DIDStandard) GetSignType() int { return NlssVersion } diff --git a/did/wallet.go b/did/wallet.go index 85941bdf..77fc3a77 100644 --- a/did/wallet.go +++ b/did/wallet.go @@ -56,7 +56,7 @@ func (d *DIDWallet) GetDID() string { return d.did } -func (d *DIDWallet) GetSignVersion() int { +func (d *DIDWallet) GetSignType() int { return NlssVersion } diff --git a/grpcclient/token.go b/grpcclient/token.go index 19dfbcee..77370d25 100644 --- a/grpcclient/token.go +++ b/grpcclient/token.go @@ -34,7 +34,7 @@ func (cmd *Command) GenerateRBT() { Mode: br.SignRequest.Mode, } switch int(br.SignRequest.Mode) { - case did.LightDIDMode: + case did.LiteDIDMode: resp.Password = cmd.privPWD case did.BasicDIDMode: resp.Password = cmd.privPWD diff --git a/grpcserver/did.go b/grpcserver/did.go index ddbede05..21606ed0 100644 --- a/grpcserver/did.go +++ b/grpcserver/did.go @@ -85,7 +85,7 @@ func (rn *RubixNative) CreateDID(ctx context.Context, req *protos.CreateDIDReq) } defer os.RemoveAll(folderName) - if dc.Type != did.LightDIDMode { + if dc.Type != did.LiteDIDMode { if req.DidImage != "" { err = createFile(folderName+"/"+did.DIDImgFileName, req.DidImage, true) if err != nil { diff --git a/server/did.go b/server/did.go index b77ba3f4..777a2835 100644 --- a/server/did.go +++ b/server/did.go @@ -67,7 +67,7 @@ func (s *Server) APICreateDID(req *ensweb.Request) *ensweb.Result { didCreate.PubKeyFile = fileName } - if didCreate.Type != did.LightDIDMode { + if didCreate.Type != did.LiteDIDMode { if strings.Contains(fileName, did.ImgFileName) { didCreate.ImgFile = fileName } @@ -211,7 +211,7 @@ func (s *Server) APISetupDID(req *ensweb.Request) *ensweb.Result { didCreate.PubKeyFile = fileName } - if didCreate.Type != did.LightDIDMode { + if didCreate.Type != did.LiteDIDMode { if strings.Contains(fileName, did.DIDImgFileName) { didCreate.DIDImgFileName = fileName } From a18ecd07188c60a9c14ea7f6d577cf83bfbadbb9 Mon Sep 17 00:00:00 2001 From: Ashita Gupta Date: Tue, 7 May 2024 16:23:35 +0530 Subject: [PATCH 39/62] fixed bugs for to reduce waiting time --- core/quorum_initiator.go | 24 +++++++++++++----------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/core/quorum_initiator.go b/core/quorum_initiator.go index 203c943a..2f764987 100644 --- a/core/quorum_initiator.go +++ b/core/quorum_initiator.go @@ -60,9 +60,10 @@ type ConensusReply struct { } type ConsensusResult struct { - RunningCount int - SuccessCount int - FailedCount int + RunningCount int + SuccessCount int + FailedCount int + PledgingDIDSignStatus bool } type ConsensusStatus struct { @@ -240,9 +241,10 @@ func (c *Core) initiateConsensus(cr *ConensusRequest, sc *contract.Contract, dc }, P: make(map[string]*ipfsport.Peer), Result: ConsensusResult{ - RunningCount: 0, - SuccessCount: 0, - FailedCount: 0, + RunningCount: 0, + SuccessCount: 0, + FailedCount: 0, + PledgingDIDSignStatus: false, }, } reqPledgeTokens := float64(0) @@ -721,11 +723,11 @@ func (c *Core) finishConsensus(id string, qt int, p *ipfsport.Peer, status bool, cs.P[did] = p cs.Credit.Credit = append(cs.Credit.Credit, csig) cs.Result.SuccessCount++ - } else if did == pledgingDID && cs.Result.SuccessCount == MinConsensusRequired-1 { - cs.P[did] = p - cs.Credit.Credit = append(cs.Credit.Credit, csig) - cs.Result.SuccessCount++ - } else if cs.Result.RunningCount == 0 && cs.Result.SuccessCount == MinConsensusRequired-1 { + if did == pledgingDID { + cs.Result.PledgingDIDSignStatus = true + } + + } else if (did == pledgingDID || cs.Result.PledgingDIDSignStatus) && cs.Result.SuccessCount == MinConsensusRequired-1 { cs.P[did] = p cs.Credit.Credit = append(cs.Credit.Credit, csig) cs.Result.SuccessCount++ From c0e07e5f4249a71ae37dfea173f1006cb7bca35a Mon Sep 17 00:00:00 2001 From: Arnab Ghose Date: Tue, 7 May 2024 18:50:04 +0530 Subject: [PATCH 40/62] feat: added python tests for RBT transfer --- tests/README.md | 57 +++++++++++ tests/fixtures/didimage.png.file | Bin 0 -> 5276 bytes tests/fixtures/testswarm.key | 3 + tests/helper/__init__.py | 0 tests/helper/utils.py | 16 +++ tests/node/__init__.py | 0 tests/node/actions.py | 111 ++++++++++++++++++++ tests/node/commands.py | 142 ++++++++++++++++++++++++++ tests/node/quorum.py | 67 ++++++++++++ tests/node/utils.py | 16 +++ tests/node/vars.py | 2 + tests/run.py | 169 +++++++++++++++++++++++++++++++ tests/scenarios/__init__.py | 0 tests/scenarios/rbt_transfer.py | 84 +++++++++++++++ tests/shutdown.py | 16 +++ 15 files changed, 683 insertions(+) create mode 100644 tests/README.md create mode 100644 tests/fixtures/didimage.png.file create mode 100644 tests/fixtures/testswarm.key create mode 100644 tests/helper/__init__.py create mode 100644 tests/helper/utils.py create mode 100644 tests/node/__init__.py create mode 100644 tests/node/actions.py create mode 100644 tests/node/commands.py create mode 100644 tests/node/quorum.py create mode 100644 tests/node/utils.py create mode 100644 tests/node/vars.py create mode 100644 tests/run.py create mode 100644 tests/scenarios/__init__.py create mode 100644 tests/scenarios/rbt_transfer.py create mode 100644 tests/shutdown.py diff --git a/tests/README.md b/tests/README.md new file mode 100644 index 00000000..496afa0c --- /dev/null +++ b/tests/README.md @@ -0,0 +1,57 @@ +# Test Scripts + +The test script does the complete setup by building the rubix node based on the Operatng System, downloads IPFS binary for a specific version (refer `IPFS_KUBO_VERSION` variable in `run.py`) and sets up quorum and non-quorum nodes before proceeding with running all the test cases. + +The test script covers the following RBT Transfer scenarios: + +1. Shuttle Transfer (Success Case)
+ 1.1 Generate 2 whole RBT for A
+ 1.2 Transfer 0.5 from A to B
+ 1.3 Transfer 1.499 from A to B
+ 1.4 (Transfer 0.25 from B to A) * 4
+ 1.5 Transfer 1 RBT from A to B
+ 1.6 Generate 2 whole RBT for A
+ 1.7 Transfer 2 RBT from A to B
+ 1.8 Transfer 0.001 from A to B
+ +2. Insufficient Balance Transfer (Failure Case)
+ 2.1 Transferring 100 RBT from A which has zero balance
+ 2.2 Transferring 100 RBT from B which has insufficient balance
+ +3. Transferring 0.00000009 RBT from B which is more than allowed decimal places (Failure Case) + +## Prerequisites + +- Python 3.10+ ([Install Ref](https://www.python.org/downloads/)) +- `pip` package manger ([Install Ref](https://pip.pypa.io/en/stable/installation/)) +- `requests` package. After installing Python and pip, run `pip install requests` to install this package + +## Running the tests + +To start the test. Please NOTE that it must be run from the `tests` directory only. + +``` +python3 run.py +``` + +### Flags + +The test script is equipped with CLI Parser. Following are the flags and their description + +``` +usage: run.py [-h] [--skip_prerequisite | --no-skip_prerequisite] [--run_nodes_only | --no-run_nodes_only] [--skip_adding_quorums | --no-skip_adding_quorums] + [--run_tests_only | --no-run_tests_only] + +CLI to run tests for Rubix + +options: + -h, --help show this help message and exit + --skip_prerequisite, --no-skip_prerequisite + skip prerequisite steps such as installing IPFS and building Rubix + --run_nodes_only, --no-run_nodes_only + only run the rubix nodes and skip the setup + --skip_adding_quorums, --no-skip_adding_quorums + skips adding quorums + --run_tests_only, --no-run_tests_only + only proceed with running tests +``` \ No newline at end of file diff --git a/tests/fixtures/didimage.png.file b/tests/fixtures/didimage.png.file new file mode 100644 index 0000000000000000000000000000000000000000..09bf52e0a3e9f0188c6c68b274457a90856352f8 GIT binary patch literal 5276 zcmX9?c_7s96MlCc+mc(k$(1AWQ$)FoT)9)I*r*7(Z(>ndB|2QW>Wg)h(1n~ULWEpd zv@DWqWpl3k_ip{Q`No%fx2k9j8E(%g`ZMUVvmz-DZuZw&wf{zZU&%<$*3U(pQ! zcwLP3_0ET6Es*qZq`|<}KV|K_@4ua9J#gc{d&X9Jtctvrx(I=S{~Ac>>AmDStpn%7<_-efYDyaz8nm#Tj?#9!oBFpZ5J1@4lUWVDF|( zeXG9Q?Y0}Xyt}tPy0^12-t=!l_Bb4`JDLc*WE>5TMLh{a zNT3xF4NQsjPZnTZeVb5*T_&8K_^@J*&~2_|j6hQ?>K#idz=oC<AOYD-L!OyF_QTLm;P&>!w7m9hk!&(2-=3ki5DOP3b#)&G^6 z&CntFLgIfRzwaEOE2|H@{Hsjj{0rHxQld+Lbp#r}0Ec=x(&$p7s2_iQ@A%o$edmwo z(jmq&p>&%k7kcT#HpfZPO>ts%Y4mBU@;tz)J zzqhvbQ1ysiR28~J#vzSXE~d^H!D`32oAujz(m*)7-Gh3N%7e-4;JZSof75ZL-mTRO z`HIkRYxhH+H@51X7|nxxmBQoWG(1)HhkI=&1X)EIctDSI8NxeYHO4;(RmHN+nksFi zZI0BD=#uf155^W^yK6$;xM^W;6HbzY2?xl!!&62mb7TWbThDv<#3_wZDcHBQj0igoDitcZav{O3UD|m@JnG+D)zfJW&kZseZV3XM0Hk98=$w~tS zjLsvJjZ!|aZ5-OEe4k9>cxy=Bq8RI3JNJ9@+?bh-gaVndsB9!5))CnSS7>vjXm+{> zoBCJgmi8@lty)^;`j@)lgK*q)b#DBI}_E#mr_!GH~A+jgfyP=5Rthu6nD4;}f$ zn9n_>~G!KUvI`w$8yLNnpda&dk{CMb_MFx;j{Pvbc$m6#r&5=wMY= z7?+kE*yYg>o*Gai1V3Bo^AX5=Iz3cKxOr;3zu|ctH`#-HlRVkadUIT)J!ENtyMAnY zJ|K%lLnSS_q3aAN%3`iJslzd|5(Q{k8WXP6=MS@)y$T$gh1q6`I>wr9KvC}I0)#(W zUL$iUbo`-+;T|iRzv??0#bbd07`708R^}W(u_hvWwCljyi|MltcosX;_(5fJFEbrJxu`35 z02mgf4A0ZFd#czqWAfD66PVSFH|BF0LHV&mpJYCXQ{KNATxfhsd~KAYh4=wumRM!7 zF)zUc%I}doiurmz`9|avY2dVmDMRzkZrdk(;Vv+MF}M`VmD3i^>@?yrV5ihQ^+lE3 z+5cdM01Ba3crt>FW|sROxQ%P3`h`;w^<}y>ck#PDAI+g_W-J?}s(igkoRuiFXfzR6 z8}nRO#U!w|JN#*I7AJ)F1MsE-r6Wm79r4{>#2b2Vvh9PBH(&>tBz8mEPooc7Az+U~ z!N7a-E}UyFJXPWng*HmLcVq2%O3Tz-0;8u#bLvM`B-D0J7i&!^B|!A-x9?Ru*x z5?4ATrph`LfhT4!R$|-d%70s5YPPKUyhWL>!5K~+1ccmW$!4PHHsgGM@YVHS^P!>_ z1mDc2!NZj10zi23iZa;|=FzUXYhOT5aa7z2DzPR0`%1?#IIJpsybH4y^cLT3=c(>6 zUxWFbf|s85CwKG3)MvYi&3QDj`2)qXX@PLGZ~$JNjCvf#rI_`pi(=u-HTDj5$h@x% zm)uYavwnf)vPB*4U?j8V=u-FD^eHj?tlEo5P?roiZ-rCs9_Xx}sCV5kyt#QG1#Y7% z(OL`C8;`PeyrWU9Dp}l9%_Z5!?giCdq^5c#oIrZGm!11jUJ+n#yYHgv=Wmp&b)O+* z59{b8Fe!IGy)7z!mgH1xZGzo;jkG9q)Mw4BK&_8Qm0V0Ncy0-+k*fP7^+}R)h4s!p zxHgrYYc}!HgdOet+k;y8!DyY&>*|Y{b~0M+SH<)Y7&WRiNhjGRqsFe!yRZPSZtIS= z{1|tOgPprf^6lL2*}4q|c`cxu<&G+V_hUNv zi2C9;rw=RVR3t0IYcgCcQ&D!3B>jD|?kz(K;BX-1lrKj-H8&9=8tV+~2v{;xU$Bwo zSZ=H5GpX(z%iWK0eL(Q0?o{0x>tE?eKoUaYuuhX(l-o`Ly-H`~5iK?GB7Q?gb&r~% zIvJ_^&VyJ~WIdbj)WQpfLxYzu#zT2}7+6rmbWc2ocA_wICz-HcD2)YwLh1u6kGO9h z&_!VUw%#o0bzk)9G)Y=Ncv=hlh16pHX=?LJQGt^lFDUS5&`?aDTziob$z+B8U#33+ zzKOYKAoMH(6O@K^wN}byfL})NimLI!3HF>)ZlMI`e` zRce^Hjb&dMMjlZe$XgSn(B2m-#x;qwc*b)bkT&o04<_11riCG%q#||Ky||`ZhSacz z@ILRgLVtU0;E8Rso(MeWEJ8b?f_!b%4yt*^m%6Oh!1MolTn((jOxFm(Z_eP{O)iZN zPJF1Gh!vP=ks}ZFKS=KpSBUNDG-9%Xb25A*bT7Ej(a3O=DF;5KvvEj*=fUW)Cu5%2 zcLexwKiaSX>7&RKA~SAtcfUq^?aAE<1AR66Io^@PYS9JDxw~xwj;40 zQ`G##Qoz$oEnQn_y^4D*H0=zYN7C29(;+em%(_B_#Ti z%UQq@@Oz_cnB1Hu0z>>+S&_juO8PhQL!MYQ^ou@+ z7QsC3bR@y840Flp*r)&*4_7!_jH14nBy!o|D;IV+X)3D{*Zf$(hzKDgGTcT7&T)ibLMz=Y)nwKc@CyIE;mk8axiue!H z(R*k8nMg-YG7ulA?ywg)w(+ZB6+(Yw!FA#|y_Zr9D6S9OWy#hJVjZ{@;m?v1P|qTXH~$j?j2R;SyKs z08SDna;x0XPOHJ*3sbrDepQvquiUjyGcmi8(-0PLT&2Gqo7}g;&7#VG`A__qT4$zS zn=|-PNPC-~417e#t}OeSHJmug;2l_*^|2Z$Y+8piGkn9r+-*O8IfWDCFm~Y`^<$^` z$5uQhua|VKl~xB)bm#7Rh6&e@KeUZ2eMDg;X$}1ox2rXjgERPf!e61{YBhsy0}bA_ zb8~lB6sJKsPIX6fFw{xezOU?yR!I`)IJr|#frsiRd|U0rL`l(;LxaFlb!V**#@4p4 zY@U5LyL0fN&shvplt0r0d9)uJ@OC+Kr0%8pa_78R80&~=g3o``0^6%@_vPq?u`AXU zp7%z3g`MYx^Y3*mlZQjeaE<-ER@^@ig2V|Wd`WoJ@&?AaHPZud*-T`Im@MM=;?>!Pi^~wSv1!5S;<9$?Xf>B z#mtyf3n;i;ip*IZTJd;$uagT`t`)*Q((_0D!IMLNfS9z$)h`EOURR&#-Z8`}jc;^it!3594ByWJi1I(Fo7v&qqLQ;E8I}~&U@LUHqp3B z0bPs2PTI9k+rKYxdg{^4fBg4GGh&8daD8>k0HR))$ zL$X(vg-NjT7!KhQlAR#2P|e|0+Gt=*Rs|8b#mVObE2K8Km2)Io(*L+p)h?F5&XbuM3StO!#?*D_-3Xx^Ko!!4p4wU=ANkfXMP ziJ`mp?!A|c$>QLAab{YFgrOXMcJQYQh1+^Dk+Vh^n`1&}xjymlWnM-C&F9qlO5Y6l zSRYRFDUT!dGLgrEX?0CBF*y{K?R&yb^*rCGsxZ4#Q`Dp)J~-a@SgFN8eooPqb=>c( zJB6iQPnaW;LC$OI8+~QQsyAwvEu@BeE}I~ku-Pf2aDOG5@z-aEiQkCw_xmj zDYwhlki>$ckoi{>&8pR?z1d>UkFuc~oHc9sopl(-`?A@2I3~a9PPGl2(L?G!-%^xTs^AXl8}ahywe$)D?Ln$SH4lpXlq<4TE4;NE(C_lZ_uen(FdY;%Mdn!(}>2qhp+4P=8(iP8|z*dW$t*LaxOs80% z0R?qYU}QzmX1DqWl3)l$L$;pngYvMfl?I+5DsEsqY`L|9C4x^#MZU8oXd@He zCiN{6V>)<8T)?jrspzcFk%a5-O z)UaZRG3H$X)rWq;C{ynSwr#EI`xT^W=qp?y>uIn(YRcr_IMNj%WTpT=# zRO6!eFF?|6nPRZYl&c^k( z)59Tg=7wD%N64zL1Bsifu#SiAto*)z3aN*5zIO~fj+Fj~*nFxvRc3>REhos>=!y+L zxKfDtnpBhAU@nbqi>QL^KN*1w=zx`fA#6^GtV2r^@Yw4PYym*U*Td)kDvs6p{8P-{ z`G+`nIN%?`k@j~eBMtlf?Z9@R-_ik7V*@yc?1TOxdfxs+c+%Mg^zl}D>n{Q)2N{nI s^CA2Z28D8<^{tp2o!dA0RRAK>z>% literal 0 HcmV?d00001 diff --git a/tests/fixtures/testswarm.key b/tests/fixtures/testswarm.key new file mode 100644 index 00000000..8985c5d0 --- /dev/null +++ b/tests/fixtures/testswarm.key @@ -0,0 +1,3 @@ +/key/swarm/psk/1.0.0/ +/base16/ +278b9a199c43fa84178920bd9f5cbcd69e933ddf02a8f69e47a3ea5a1705512f \ No newline at end of file diff --git a/tests/helper/__init__.py b/tests/helper/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/tests/helper/utils.py b/tests/helper/utils.py new file mode 100644 index 00000000..8011a780 --- /dev/null +++ b/tests/helper/utils.py @@ -0,0 +1,16 @@ +def expect_success(func): + def wrapper(*args, **kwargs): + try: + func(*args, **kwargs) + except: + raise Exception("The action was expected to pass, but it failed") + return wrapper + +def expect_failure(func): + def wrapper(*args, **kwargs): + try: + func(*args, **kwargs) + raise Exception("The action was expected to fail, but it passed") + except: + return 0 + return wrapper \ No newline at end of file diff --git a/tests/node/__init__.py b/tests/node/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/tests/node/actions.py b/tests/node/actions.py new file mode 100644 index 00000000..7251f265 --- /dev/null +++ b/tests/node/actions.py @@ -0,0 +1,111 @@ +from .commands import cmd_run_rubix_servers, cmd_get_peer_id, cmd_create_did, cmd_register_did, \ + cmd_generate_rbt, cmd_add_quorum_dids, cmd_setup_quorum_dids, cmd_rbt_transfer +from .utils import get_node_name_from_idx, save_to_json + +def add_quorums(node_config: dict): + for config in node_config.values(): + cmd_add_quorum_dids( + config["server"], + config["grpcPort"] + ) + +def setup_quorums(node_config: dict): + for config in node_config.values(): + cmd_setup_quorum_dids( + config["did"], + config["server"], + config["grpcPort"] + ) + +def quorum_config(node_config: dict, skip_adding_quorums: bool = False, create_quorum_list: bool = False): + # Prepare quorumlist.json + quorum_list = [] + if create_quorum_list: + for config in node_config.values(): + quorum_info = { + "type": 2, + "address": config["peerId"] + "." + config["did"] + } + + quorum_list_file_path = "../linux/quorumlist.json" # TODO: make it Dynamic + quorum_list.append(quorum_info) + + save_to_json(quorum_list_file_path, quorum_list) + + # # add quorums + if not skip_adding_quorums: + add_quorums(node_config) + + setup_quorums(node_config) + + +def get_base_ports(): + base_ens_server = 20000 + base_grpc_port = 10500 + + return base_ens_server, base_grpc_port + +def setup_rubix_nodes(node_count: int = 0, node_prefix_str: str = "node"): + base_ens_server, base_grpc_port = get_base_ports() + + node_config = {} + + # Start rubix servers + loop_start_idx, loop_end_idx = 0, node_count + + for i in range(loop_start_idx, loop_end_idx): + k = i if node_prefix_str == "node" else (10+i) + + ens_server = base_ens_server + k + print(f"Running server at port: {ens_server}") + grpc_port = base_grpc_port + k + + node_name = get_node_name_from_idx(k, node_prefix_str) + + cmd_run_rubix_servers(node_name, k, grpc_port) + + node_config[node_name] = { + "did": "", + "server": ens_server, + "grpcPort": grpc_port, + "peerId": "" + } + + return node_config + + +def fetch_peer_ids(node_config: dict): + print("Fetching Node IDs........") + for config in node_config.values(): + peer_id = cmd_get_peer_id(config["server"], config["grpcPort"]) + config["peerId"] = peer_id + print("Fetched all Node IDs") + + +def create_and_register_did(node_config: dict, register_did: bool = True): + for config in node_config.values(): + did_id = cmd_create_did(config["server"], config["grpcPort"]) + print("Created DID : ", did_id) + + if register_did: + print(f"Registering DID: {did_id}") + cmd_register_did(did_id, config["server"], config["grpcPort"]) + print("DID is registered successfully\n") + + config["did"] = did_id + +def fund_dids_with_rbt(node_config: dict, rbt_amount: int = 30): + for config in node_config.values(): + cmd_generate_rbt(config["did"], rbt_amount, config["server"], config["grpcPort"]) + print("DID ", config["did"], f" is funded with {rbt_amount} RBT") + +def fund_did_with_rbt(config: dict, rbt_amount: int = 30): + output = cmd_generate_rbt(config["did"], rbt_amount, config["server"], config["grpcPort"]) + print(output) + return output + +def rbt_transfer(config_sender: dict, config_receiver: dict, transfer_rbt_amount: int): + sender_address = config_sender["peerId"] + "." + config_sender["did"] + receiver_address = config_receiver["peerId"] + "." + config_receiver["did"] + + cmd_rbt_transfer(sender_address, receiver_address, transfer_rbt_amount, config_sender["server"], config_sender["grpcPort"]) \ No newline at end of file diff --git a/tests/node/commands.py b/tests/node/commands.py new file mode 100644 index 00000000..42c76f24 --- /dev/null +++ b/tests/node/commands.py @@ -0,0 +1,142 @@ +import subprocess +import os +import re + +def run_command(cmd_string, is_output_from_stderr=False): + assert isinstance(cmd_string, str), "command must be of string type" + cmd_result = subprocess.run(cmd_string, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True) + code = cmd_result.returncode + + if int(code) != 0: + err_output = cmd_result.stderr.decode('utf-8')[:-1] + print(err_output) + return err_output, int(code) + + output = "" + if not is_output_from_stderr: + output = cmd_result.stdout.decode('utf-8')[:-1] + print(output) + if output.find('[ERROR]') > 0 or output.find('parse error') > 0: + return output, 1 + else: + return output, code + else: + output = cmd_result.stderr.decode('utf-8')[:-1] + if output.find('[ERROR]') > 0 or output.find('parse error') > 0: + return output, 1 + else: + return output, code + +def cmd_run_rubix_servers(node_name, server_port_idx, grpc_port): + os.chdir("../linux") + cmd_string = f"screen -S {node_name} -d -m ./rubixgoplatform run -p {node_name} -n {server_port_idx} -s -testNet -grpcPort {grpc_port}" + _, code = run_command(cmd_string) + if code != 0: + raise Exception("Error occurred while run the command: " + cmd_string) + os.chdir("../tests") + +def cmd_create_did(server_port, grpc_port): + os.chdir("../linux") + cmd_string = f"./rubixgoplatform createdid -port {server_port} -grpcPort {grpc_port}" + output, code = run_command(cmd_string, True) + + if code != 0: + raise Exception("Error occurred while run the command: " + cmd_string) + + did_id = "" + if "successfully" in output: + pattern = r'bafybmi\w+' + matches = re.findall(pattern, output) + if matches: + did_id = matches[0] + else: + raise Exception("unable to extract DID ID") + + os.chdir("../tests") + return did_id + +def cmd_register_did(did_id, server_port, grpc_port): + os.chdir("../linux") + cmd_string = f"./rubixgoplatform registerdid -did {did_id} -port {server_port} -grpcPort {grpc_port}" + output, code = run_command(cmd_string) + print(output) + + if code != 0: + raise Exception("Error occurred while run the command: " + cmd_string) + + os.chdir("../tests") + return output + +def cmd_generate_rbt(did_id, numTokens, server_port, grpc_port): + os.chdir("../linux") + cmd_string = f"./rubixgoplatform generatetestrbt -did {did_id} -numTokens {numTokens} -port {server_port} -grpcPort {grpc_port}" + output, code = run_command(cmd_string, True) + + if code != 0: + raise Exception("Error occurred while run the command: " + cmd_string) + + os.chdir("../tests") + return output + +def cmd_add_quorum_dids(server_port, grpc_port): + os.chdir("../linux") + cmd_string = f"./rubixgoplatform addquorum -port {server_port} -grpcPort {grpc_port}" + output, code = run_command(cmd_string, True) + print(output) + if code != 0: + raise Exception("Error occurred while run the command: " + cmd_string) + + os.chdir("../tests") + return output + +def cmd_shutdown_node(server_port, grpc_port): + os.chdir("../linux") + cmd_string = f"./rubixgoplatform shutdown -port {server_port} -grpcPort {grpc_port}" + output, _ = run_command(cmd_string, True) + print(output) + + os.chdir("../tests") + return output + +def cmd_setup_quorum_dids(did, server_port, grpc_port): + os.chdir("../linux") + cmd_string = f"./rubixgoplatform setupquorum -did {did} -port {server_port} -grpcPort {grpc_port}" + output, code = run_command(cmd_string, True) + print(output) + if code != 0: + raise Exception("Error occurred while run the command: " + cmd_string) + + os.chdir("../tests") + return output + +def cmd_get_peer_id(server_port, grpc_port): + os.chdir("../linux") + cmd_string = f"./rubixgoplatform get-peer-id -port {server_port} -grpcPort {grpc_port}" + output, code = run_command(cmd_string) + + if code != 0: + raise Exception("Error occurred while run the command: " + cmd_string) + os.chdir("../tests") + return output + +def check_account_info(did, server_port, grpc_port): + os.chdir("../linux") + cmd_string = f"./rubixgoplatform getaccountinfo -did {did} -port {server_port} -grpcPort {grpc_port}" + output, code = run_command(cmd_string) + + if code != 0: + raise Exception("Error occurred while run the command: " + cmd_string) + os.chdir("../tests") + return output + +# Note: address != did, address = peerId.didId +def cmd_rbt_transfer(sender_address, receiver_address, rbt_amount, server_port, grpc_port): + os.chdir("../linux") + cmd_string = f"./rubixgoplatform transferrbt -senderAddr {sender_address} -receiverAddr {receiver_address} -rbtAmount {rbt_amount} -port {server_port} -grpcPort {grpc_port}" + output, code = run_command(cmd_string, True) + print(output) + if code != 0: + raise Exception("Error occurred while run the command: " + cmd_string) + + os.chdir("../tests") + return output \ No newline at end of file diff --git a/tests/node/quorum.py b/tests/node/quorum.py new file mode 100644 index 00000000..b8ca59d7 --- /dev/null +++ b/tests/node/quorum.py @@ -0,0 +1,67 @@ +import pprint +import time + +from .actions import setup_rubix_nodes, fetch_peer_ids, create_and_register_did, \ + fund_dids_with_rbt, quorum_config +from .utils import save_to_json + +def run_quorum_nodes(node_config_path, only_run_nodes, skip_adding_quorums): + node_config_path = "./quorum_config.json" + + print("Running Rubix nodes......") + node_config = setup_rubix_nodes(5) + print("Rubix nodes are now running") + + if not only_run_nodes: + print("Waiting 20 seconds before fetching all node peer IDs............") + time.sleep(20) + + fetch_peer_ids(node_config) + + print("Creation and registeration of quorum DIDs have started") + create_and_register_did(node_config) + print("All quorum DIDs have been registered") + + print("Initiating funding of these quorum DIDs") + fund_dids_with_rbt(node_config) + print("All Quorum DIDs have been funded") + + save_to_json(node_config_path, node_config) + + print("Setting up quorums and saving information about them to quorumlist.json") + quorum_config(node_config, skip_adding_quorums=skip_adding_quorums, create_quorum_list=True) + + pprint.pp(node_config) + print("Quorums have been configured. You can proceed with running Test scenarios") + else: + quorum_config(node_config, skip_adding_quorums=True, create_quorum_list=False) + + return node_config + +def run_non_quorum_nodes(node_config_path, only_run_nodes, skip_adding_quorums): + node_config_path = "./non_quorum_config.json" + + print("Running non-quorum nodes...") + node_config = setup_rubix_nodes(2, "nodeNq") + print("Non-quorum nodes are running successfully") + + if not only_run_nodes: + print("Waiting 20 seconds before fetching all node peer IDs............") + time.sleep(20) + fetch_peer_ids(node_config) + + print("Creation of Non Quorum DIDs have started") + create_and_register_did(node_config, False) + print("Non Quorum DIDs have been created") + + save_to_json(node_config_path, node_config) + + print("Adding and setting up quorum config") + quorum_config(node_config, skip_adding_quorums=skip_adding_quorums, create_quorum_list=False) + + pprint.pp(node_config) + print("Non Quorum nodes have been configured") + else: + quorum_config(node_config, skip_adding_quorums=True, create_quorum_list=False) + + return node_config \ No newline at end of file diff --git a/tests/node/utils.py b/tests/node/utils.py new file mode 100644 index 00000000..61bcdbe7 --- /dev/null +++ b/tests/node/utils.py @@ -0,0 +1,16 @@ +import json +import sys +import os +sys.path.insert(1, os.getcwd()) +from .vars import QUORUM_NODES + +def get_node_name_from_idx(idx, prefix_string: str = "node"): + return prefix_string + str(idx) + +def save_to_json(filepath, obj): + # Check if file exists. If yes, then remove it + if os.path.exists(filepath): + os.remove(filepath) + + with open(filepath, 'w') as f: + json.dump(obj, f, indent=4) diff --git a/tests/node/vars.py b/tests/node/vars.py new file mode 100644 index 00000000..7b683fcb --- /dev/null +++ b/tests/node/vars.py @@ -0,0 +1,2 @@ +QUORUM_NODES = 5 + diff --git a/tests/run.py b/tests/run.py new file mode 100644 index 00000000..7e8c091b --- /dev/null +++ b/tests/run.py @@ -0,0 +1,169 @@ +import platform +import os +import shutil +import requests +import argparse +from node.commands import run_command +from node.quorum import run_quorum_nodes, run_non_quorum_nodes +from scenarios.rbt_transfer import * + +IPFS_KUBO_VERSION = "v0.21.0" +QUORUM_CONFIG_FILE = "./quorum_config.json" +NON_QUORUM_CONFIG_FILE = "./non_quorum_config.json" + +def get_os_info(): + os_name = platform.system() + build_folder = "" + + if os_name == "Linux": + build_folder = "linux" + elif os_name == "Windows": + build_folder = "windows" + elif os_name == "Darwin": + build_folder = "mac" + else: + print("Unsupported operating system to build Rubix") + return None, None + + return os_name, build_folder + +def download_ipfs_binary(os_name, version, build_dir): + download_url = "" + + if os_name == "Linux": + download_url = f"https://dist.ipfs.tech/kubo/{version}/kubo_{version}_linux-amd64.tar.gz" + elif os_name == "Windows": + download_url = f"https://dist.ipfs.tech/kubo/{version}/kubo_{version}_windows-amd64.zip" + elif os_name == "Darwin": # MacOS + download_url = f"https://dist.ipfs.tech/kubo/{version}/kubo_{version}_darwin-amd64.tar.gz" + else: + raise ValueError("Unsupported operating system") + + # Download the IPFS binary archive + download_path = f"kubo_{version}_{os_name.lower()}-amd64.tar.gz" if os_name != "Windows" else f"kubo_{version}_{os_name.lower()}-amd64.zip" + print("Downloading IPFS binary...") + response = requests.get(download_url) + with open(download_path, "wb") as f: + f.write(response.content) + print("Download completed.") + + # Extract the archive + print("Extracting IPFS binary...") + if os_name == "Windows": + # For Windows, we need to use the 'zipfile' module to extract + import zipfile + with zipfile.ZipFile(download_path, "r") as zip_ref: + zip_ref.extractall("kubo") + else: + # For Linux and MacOS, we use tar + import tarfile + with tarfile.open(download_path, "r:gz" if os_name != "Darwin" else "r") as tar_ref: + tar_ref.extractall("kubo") + print("Extraction completed.") + + # Check the contents of the kubo directory + print("Contents of kubo directory:") + for item in os.listdir("kubo"): + print(item) + + # Move IPFS binary to the appropriate folder + print("Moving IPFS binary...") + src_file = os.path.join("kubo", "kubo", "ipfs") + dest_dir = os.path.join(build_dir, "ipfs") + if os.path.exists(src_file): + shutil.move(src_file, dest_dir) + print("IPFS binary moved to", dest_dir) + + # Check if the file is present at the destination + dest_file = os.path.join(dest_dir) + if not os.path.exists(dest_file): + raise FileNotFoundError("IPFS binary not found at the destination after move operation.") + else: + raise FileNotFoundError("Installed IPFS binary file does not exist.") + + # Clean up + os.remove(download_path) + shutil.rmtree("kubo") + print("\nIPFS has been installed succesfully.") + +def copy_fixtures_to_build_dir(build_directory): + fixtures_directory = os.path.join("tests", "fixtures") + + # Copy didimage.png.file + image_file_src = os.path.join(fixtures_directory, "didimage.png.file") + image_file_dest = os.path.join(build_directory, "image.png") + shutil.copyfile(image_file_src, image_file_dest) + + if not os.path.exists(image_file_dest): + raise FileNotFoundError(f"Copy operation for didimage.png.file failed. Destination file not found: {image_file_dest}") + + # Copy testswarm.key + swarmkey_src = os.path.join(fixtures_directory, "testswarm.key") + swarmkey_dest = os.path.join(build_directory, "testswarm.key") + shutil.copyfile(swarmkey_src, swarmkey_dest) + + if not os.path.exists(swarmkey_dest): + raise FileNotFoundError(f"Copy operation for testswarm.key failed. Destination file not found: {swarmkey_dest}") + + print("\nimage.png and swarm key have been added to build directory successfully") + +def cli(): + parser = argparse.ArgumentParser(description="CLI to run tests for Rubix") + parser.add_argument("--skip_prerequisite", action=argparse.BooleanOptionalAction, help="skip prerequisite steps such as installing IPFS and building Rubix") + parser.add_argument("--run_nodes_only", action=argparse.BooleanOptionalAction, help="only run the rubix nodes and skip the setup") + parser.add_argument("--skip_adding_quorums", action=argparse.BooleanOptionalAction, help="skips adding quorums") + parser.add_argument("--run_tests_only", action=argparse.BooleanOptionalAction, help="only proceed with running tests") + return parser.parse_args() + + +if __name__=='__main__': + os.chdir("../") + + args = cli() + skip_prerequisite = args.skip_prerequisite + run_nodes_only = args.run_nodes_only + skip_adding_quorums = args.skip_adding_quorums + run_tests_only = args.run_tests_only + + non_quorum_node_config = {} + + if not run_tests_only: + os_name, build_folder = get_os_info() + if os_name is None: + exit(1) + + if not skip_prerequisite: + print(f"Building Rubix binary for {os_name}\n") + build_command = "" + if os_name == "Linux": + build_command = "make compile-linux" + elif os_name == "Windows": + build_command = "make compile-windows" + elif os_name == "Darwin": + build_command = "make compile-mac" + + output, code = run_command(build_command) + if code != 0: + print("build failed with error:", output) + exit(1) + else: + print("\nBuild successful\n") + + + download_ipfs_binary(os_name, IPFS_KUBO_VERSION, build_folder) + copy_fixtures_to_build_dir(build_folder) + os.chdir("./tests") + + run_quorum_nodes(QUORUM_CONFIG_FILE, run_nodes_only, skip_adding_quorums=skip_adding_quorums) + + non_quorum_node_config = run_non_quorum_nodes(NON_QUORUM_CONFIG_FILE, run_nodes_only, skip_adding_quorums=skip_adding_quorums) + + # Run RBT Transfer related tests + rbt_transfer_test_list = [ + shuttle_transfer, + insufficient_balance_transfer, + max_decimal_place_transfer + ] + for testFn in rbt_transfer_test_list: + testFn(non_quorum_node_config) + diff --git a/tests/scenarios/__init__.py b/tests/scenarios/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/tests/scenarios/rbt_transfer.py b/tests/scenarios/rbt_transfer.py new file mode 100644 index 00000000..78454198 --- /dev/null +++ b/tests/scenarios/rbt_transfer.py @@ -0,0 +1,84 @@ +from node.actions import rbt_transfer, fund_did_with_rbt +from helper.utils import expect_failure, expect_success + +def max_decimal_place_transfer(config): + node_A_info = config["nodeNq10"] + node_B_info = config["nodeNq11"] + + print("------ Test Case (FAIL) : Transferring 0.00000009 RBT from B which is more than allowed decimal places ------") + + print("\nTransferring 0.00000009 RBT from B to A....") + expect_failure(rbt_transfer)(node_B_info, node_A_info, 0.00000009) + + print("\n------ Test Case (FAIL) : Transferring 0.00000009 RBT from B which is more than allowed decimal places completed ------\n") + +def insufficient_balance_transfer(config): + node_A_info = config["nodeNq10"] + node_B_info = config["nodeNq11"] + + print("\n------ Test Case (FAIL) : Transferring 100 RBT from A which has zero balance ------") + + print("\nTransferring 100 RBT from A to B....") + expect_failure(rbt_transfer)(node_A_info, node_B_info, 100) + + print("\n------ Test Case (FAIL) : Transferring 100 RBT from A which has zero balance completed ------\n") + + + print("\n------ Test Case (FAIL) : Transferring 100 RBT from B which has insufficient balance ------") + + print("\nTransferring 100 RBT from B to A....") + expect_failure(rbt_transfer)(node_B_info, node_A_info, 100) + + print("\n------ Test Case (FAIL) : Transferring 100 RBT from B which has insufficient balance completed ------\n") + +def shuttle_transfer(config): + node_A_info = config["nodeNq10"] + node_B_info = config["nodeNq11"] + + print("------ Test Case (PASS): Shuttle transfer started ------\n") + + print("\n1. Generating 2 whole RBT for A") + expect_success(fund_did_with_rbt)(node_A_info, 2) + print("Funded node A with 2 RBT") + + print("\n2. Transferring 0.5 RBT from A to B....") + expect_success(rbt_transfer)(node_A_info, node_B_info, 0.5) + print("Transferred 0.5 RBT from A to B") + + print("\n3. Transferring 1.499 RBT from A to B....") + expect_success(rbt_transfer)(node_A_info, node_B_info, 1.499) + print("Transferred 1.499 RBT from A to B") + + print("\n4. Transferring 0.25 RBT from B to A....") + expect_success(rbt_transfer)(node_B_info, node_A_info, 0.25) + print("Transferred 0.25 RBT from B to A") + + print("\n5. Transferring 0.25 RBT from B to A....") + expect_success(rbt_transfer)(node_B_info, node_A_info, 0.25) + print("Transferred 0.25 RBT from B to A") + + print("\n6. Transferring 0.25 RBT from B to A....") + expect_success(rbt_transfer)(node_B_info, node_A_info, 0.25) + print("Transferred 0.25 RBT from B to A") + + print("\n7. Transferring 0.25 RBT from B to A....") + expect_success(rbt_transfer)(node_B_info, node_A_info, 0.25) + print("Transferred 0.25 RBT from B to A") + + print("\n8. Transferring 1 RBT from A to B....") + expect_success(rbt_transfer)(node_A_info, node_B_info, 1) + print("Transferred 1 RBT from A to B") + + print("\n9. Generating 2 whole RBT for A") + expect_success(fund_did_with_rbt)(node_A_info, 2) + print("Funded node A with 2 RBT") + + print("\n10. Transferring 2 RBT from A to B....") + expect_success(rbt_transfer)(node_A_info, node_B_info, 2) + print("Transferred 2 RBT from A to B") + + print("\n11. Transferring 0.001 RBT from A to B....") + expect_success(rbt_transfer)(node_A_info, node_B_info, 0.001) + print("Transferred 0.001 RBT from A to B") + + print("\n------ Test Case (PASS): Shuttle transfer completed ------\n") diff --git a/tests/shutdown.py b/tests/shutdown.py new file mode 100644 index 00000000..05c6a090 --- /dev/null +++ b/tests/shutdown.py @@ -0,0 +1,16 @@ +from node.commands import cmd_shutdown_node +from node.actions import get_base_ports + +quorum_base_server, quorum_grpc_server = get_base_ports() + +for i in range(0, 5): + server_port = quorum_base_server + i + grpc_port = quorum_grpc_server + i + + cmd_shutdown_node(server_port, grpc_port) + +for i in range(0, 2): + server_port = quorum_base_server + 10 + i + grpc_port = quorum_grpc_server + 10 + i + + cmd_shutdown_node(server_port, grpc_port) From 90d50f5ba206d0dbf3606ee6da8acb2c29a36043 Mon Sep 17 00:00:00 2001 From: Arnab Ghose Date: Wed, 8 May 2024 11:48:06 +0530 Subject: [PATCH 41/62] added func to get the build dir based on the target OS --- tests/README.md | 1 + tests/node/commands.py | 35 ++++++++++++++++++++++++----------- 2 files changed, 25 insertions(+), 11 deletions(-) diff --git a/tests/README.md b/tests/README.md index 496afa0c..2d6f8ff0 100644 --- a/tests/README.md +++ b/tests/README.md @@ -23,6 +23,7 @@ The test script covers the following RBT Transfer scenarios: ## Prerequisites - Python 3.10+ ([Install Ref](https://www.python.org/downloads/)) +- tmux for MacOs and Ubuntu based systems ([Install Ref](https://github.com/tmux/tmux/wiki/Installing#binary-packages)) - `pip` package manger ([Install Ref](https://pip.pypa.io/en/stable/installation/)) - `requests` package. After installing Python and pip, run `pip install requests` to install this package diff --git a/tests/node/commands.py b/tests/node/commands.py index 42c76f24..542a56df 100644 --- a/tests/node/commands.py +++ b/tests/node/commands.py @@ -1,6 +1,19 @@ import subprocess import os import re +import platform + +def get_build_dir(): + os_name = platform.system() + build_folder = "" + if os_name == "Linux": + build_folder = "linux" + elif os_name == "Windows": + build_folder = "windows" + elif os_name == "Darwin": + build_folder = "mac" + + return build_folder def run_command(cmd_string, is_output_from_stderr=False): assert isinstance(cmd_string, str), "command must be of string type" @@ -28,15 +41,15 @@ def run_command(cmd_string, is_output_from_stderr=False): return output, code def cmd_run_rubix_servers(node_name, server_port_idx, grpc_port): - os.chdir("../linux") - cmd_string = f"screen -S {node_name} -d -m ./rubixgoplatform run -p {node_name} -n {server_port_idx} -s -testNet -grpcPort {grpc_port}" + os.chdir("../" + get_build_dir()) + cmd_string = f"tmux new -s {node_name} -d ./rubixgoplatform run -p {node_name} -n {server_port_idx} -s -testNet -grpcPort {grpc_port}" _, code = run_command(cmd_string) if code != 0: raise Exception("Error occurred while run the command: " + cmd_string) os.chdir("../tests") def cmd_create_did(server_port, grpc_port): - os.chdir("../linux") + os.chdir("../" + get_build_dir()) cmd_string = f"./rubixgoplatform createdid -port {server_port} -grpcPort {grpc_port}" output, code = run_command(cmd_string, True) @@ -56,7 +69,7 @@ def cmd_create_did(server_port, grpc_port): return did_id def cmd_register_did(did_id, server_port, grpc_port): - os.chdir("../linux") + os.chdir("../" + get_build_dir()) cmd_string = f"./rubixgoplatform registerdid -did {did_id} -port {server_port} -grpcPort {grpc_port}" output, code = run_command(cmd_string) print(output) @@ -68,7 +81,7 @@ def cmd_register_did(did_id, server_port, grpc_port): return output def cmd_generate_rbt(did_id, numTokens, server_port, grpc_port): - os.chdir("../linux") + os.chdir("../" + get_build_dir()) cmd_string = f"./rubixgoplatform generatetestrbt -did {did_id} -numTokens {numTokens} -port {server_port} -grpcPort {grpc_port}" output, code = run_command(cmd_string, True) @@ -79,7 +92,7 @@ def cmd_generate_rbt(did_id, numTokens, server_port, grpc_port): return output def cmd_add_quorum_dids(server_port, grpc_port): - os.chdir("../linux") + os.chdir("../" + get_build_dir()) cmd_string = f"./rubixgoplatform addquorum -port {server_port} -grpcPort {grpc_port}" output, code = run_command(cmd_string, True) print(output) @@ -90,7 +103,7 @@ def cmd_add_quorum_dids(server_port, grpc_port): return output def cmd_shutdown_node(server_port, grpc_port): - os.chdir("../linux") + os.chdir("../" + get_build_dir()) cmd_string = f"./rubixgoplatform shutdown -port {server_port} -grpcPort {grpc_port}" output, _ = run_command(cmd_string, True) print(output) @@ -99,7 +112,7 @@ def cmd_shutdown_node(server_port, grpc_port): return output def cmd_setup_quorum_dids(did, server_port, grpc_port): - os.chdir("../linux") + os.chdir("../" + get_build_dir()) cmd_string = f"./rubixgoplatform setupquorum -did {did} -port {server_port} -grpcPort {grpc_port}" output, code = run_command(cmd_string, True) print(output) @@ -110,7 +123,7 @@ def cmd_setup_quorum_dids(did, server_port, grpc_port): return output def cmd_get_peer_id(server_port, grpc_port): - os.chdir("../linux") + os.chdir("../" + get_build_dir()) cmd_string = f"./rubixgoplatform get-peer-id -port {server_port} -grpcPort {grpc_port}" output, code = run_command(cmd_string) @@ -120,7 +133,7 @@ def cmd_get_peer_id(server_port, grpc_port): return output def check_account_info(did, server_port, grpc_port): - os.chdir("../linux") + os.chdir("../" + get_build_dir()) cmd_string = f"./rubixgoplatform getaccountinfo -did {did} -port {server_port} -grpcPort {grpc_port}" output, code = run_command(cmd_string) @@ -131,7 +144,7 @@ def check_account_info(did, server_port, grpc_port): # Note: address != did, address = peerId.didId def cmd_rbt_transfer(sender_address, receiver_address, rbt_amount, server_port, grpc_port): - os.chdir("../linux") + os.chdir("../" + get_build_dir()) cmd_string = f"./rubixgoplatform transferrbt -senderAddr {sender_address} -receiverAddr {receiver_address} -rbtAmount {rbt_amount} -port {server_port} -grpcPort {grpc_port}" output, code = run_command(cmd_string, True) print(output) From d8b8aef025fa1160e99b96f52779080403072b93 Mon Sep 17 00:00:00 2001 From: Maneesha-rubix Date: Wed, 8 May 2024 14:18:09 +0530 Subject: [PATCH 42/62] ping peer to get peer did type --- core/core.go | 27 ++++++++++++++++++++---- core/model/basic.go | 6 ++++++ core/ping.go | 50 +++++++++++++++++++++++++++++++++++++++++++++ core/wallet/did.go | 37 +++++++++++++++++++++++++-------- 4 files changed, 108 insertions(+), 12 deletions(-) diff --git a/core/core.go b/core/core.go index c337586f..537de591 100644 --- a/core/core.go +++ b/core/core.go @@ -47,6 +47,7 @@ const ( APIGetMigratedTokenStatus string = "/api/get-Migrated-token-status" APISyncDIDArbitration string = "/api/sync-did-arbitration" APICheckQuorumStatusPath string = "/api/check-quorum-status" + APIGetPeerDIDTypePath string = "/api/get-peer-didType" ) const ( @@ -320,6 +321,7 @@ func (c *Core) SetupCore() error { c.w.SetupWallet(c.ipfs) c.PingSetup() c.CheckQuorumStatusSetup() + c.GetPeerdidTypeSetup() c.peerSetup() c.w.AddDIDLastChar() c.SetupToken() @@ -554,12 +556,29 @@ func (c *Core) SetupForienDIDQuorum(didStr string) (did.DIDCrypto, error) { // Fetching peer's did type from PeerDIDTable using GetPeerDIDType function // and own did type from DIDTable using GetDID function didtype, err := c.w.GetPeerDIDType(didStr) - if err != nil { + if err != nil || didtype == -1 { dt, err1 := c.w.GetDID(didStr) - if err1 != nil { - return nil, fmt.Errorf("couldn't fetch did type") + + if err1 != nil || dt.Type == -1 { + peerId := c.w.GetPeerID(didStr) + + if peerId == "" { + return nil, err + } + didtype_, msg, err2 := c.GetPeerdidType_fromPeer(peerId, didStr) + if err2 != nil { + c.log.Error(msg) + return nil, err2 + } + didtype = didtype_ + peerUpdateResult, err3 := c.w.UpdatePeerDIDType(didStr, didtype) + if !peerUpdateResult { + c.log.Error("couldn't update did type in peer did table", err3) + } + } else { + didtype = dt.Type } - didtype = dt.Type + } switch didtype { diff --git a/core/model/basic.go b/core/model/basic.go index 65493651..eb70deaa 100644 --- a/core/model/basic.go +++ b/core/model/basic.go @@ -20,3 +20,9 @@ type MigratedTokenStatus struct { Message string `json:"message"` MigratedStatus []int `json:"migratedstatus"` } + +// GetDIDTypeResponse is the model for response of peer while fetching did type +type GetDIDTypeResponse struct { + DidType int + BasicResponse +} diff --git a/core/ping.go b/core/ping.go index 35b0e729..4d0731f0 100644 --- a/core/ping.go +++ b/core/ping.go @@ -29,6 +29,11 @@ func (c *Core) CheckQuorumStatusSetup() { c.l.AddRoute(APICheckQuorumStatusPath, "GET", c.CheckQuorumStatusResponse) } +// GetPeerdidTypeSetup will setup the ping route +func (c *Core) GetPeerdidTypeSetup() { + c.l.AddRoute(APIGetPeerDIDTypePath, "GET", c.GetPeerdidTypeResponse) +} + // PingRecevied is the handler for ping request func (c *Core) PingRecevied(req *ensweb.Request) *ensweb.Result { c.log.Info("Ping Received") @@ -98,3 +103,48 @@ func (c *Core) CheckQuorumStatus(peerID string, did string) (string, bool, error } return checkQuorumStatusResponse.Message, checkQuorumStatusResponse.Status, nil } + +// CheckQuorumStatusResponse is the handler for CheckQuorumStatus request +func (c *Core) GetPeerdidTypeResponse(req *ensweb.Request) *ensweb.Result { //PingRecevied + did := c.l.GetQuerry(req, "did") + c.log.Info("Fetching peer did type from peer") + resp := &model.GetDIDTypeResponse{ + BasicResponse: model.BasicResponse{ + Status: false, + }, + } + + dt, err := c.w.GetDID(did) + if err != nil { + c.log.Error("Couldn't fetch did type from DID Table", "error", err) + resp.Message = "Couldn't fetch did type for did: " + did + resp.Status = false + resp.DidType = -1 + return c.l.RenderJSON(req, &resp, http.StatusOK) + } else { + resp.DidType = dt.Type + resp.Status = true + resp.Message = "successfully fetched did type" + return c.l.RenderJSON(req, &resp, http.StatusOK) + } + +} + +// GetPeerdidType will ping the peer & get the did type +func (c *Core) GetPeerdidType_fromPeer(peerID string, did string) (int, string, error) { + q := make(map[string]string) + p, err := c.pm.OpenPeerConn(peerID, did, c.getCoreAppName(peerID)) + if err != nil { + return -1, "Quorum Connection Error", fmt.Errorf("quorum connection error") + } + + // Close the p2p before exit + defer p.Close() + q["did"] = did + var getPeerdidTypeResponse model.GetDIDTypeResponse + err = p.SendJSONRequest("GET", APIGetPeerDIDTypePath, q, nil, &getPeerdidTypeResponse, false, 2*time.Minute) + if err != nil { + return -1, "Send Json Request error ", err + } + return getPeerdidTypeResponse.DidType, getPeerdidTypeResponse.Message, nil +} diff --git a/core/wallet/did.go b/core/wallet/did.go index daadf251..798bd84a 100644 --- a/core/wallet/did.go +++ b/core/wallet/did.go @@ -1,7 +1,5 @@ package wallet -import "fmt" - type DIDType struct { DID string `gorm:"column:did;primaryKey"` Type int `gorm:"column:type"` @@ -12,7 +10,7 @@ type DIDType struct { type DIDPeerMap struct { DID string `gorm:"column:did;primaryKey"` - DIDType int `gorm:"column:did_type"` + DIDType *int `gorm:"column:did_type"` PeerID string `gorm:"column:peer_id"` DIDLastChar string `gorm:"column:did_last_char"` } @@ -97,15 +95,15 @@ func (w *Wallet) AddDIDPeerMap(did string, peerID string, didType int) error { dm.DID = did dm.PeerID = peerID dm.DIDLastChar = lastChar - dm.DIDType = didType + dm.DIDType = &didType return w.s.Write(DIDPeerStorage, &dm) } if dm.PeerID != peerID { dm.PeerID = peerID return w.s.Update(DIDPeerStorage, &dm, "did=?", did) } - if dm.DIDType == 0 { - dm.DIDType = didType + if dm.DIDType == nil { + dm.DIDType = &didType return w.s.Update(DIDPeerStorage, &dm, "did=?", did) } return nil @@ -144,7 +142,30 @@ func (w *Wallet) GetPeerDIDType(did string) (int, error) { var dm DIDPeerMap err := w.s.Read(DIDPeerStorage, &dm, "did=?", did) if err != nil { - return 5, fmt.Errorf("couldn't fetch did type from peer did table") + w.log.Error("couldn't fetch did type from peer did table") + return -1, err + } + if dm.DIDType == nil { + return -1, nil + } + return *dm.DIDType, nil +} + +// Updates did type of the given did in PeerDIDTable +func (w *Wallet) UpdatePeerDIDType(did string, didtype int) (bool, error) { + var dm DIDPeerMap + err := w.s.Read(DIDPeerStorage, &dm, "did=?", did) + if err != nil { + w.log.Error("couldn't read from peer did table") + return false, err + } + + dm.DIDType = &didtype + + err1 := w.s.Update(DIDPeerStorage, &dm, "did=?", did) + if err1 != nil { + w.log.Error("couldn't update did type in peer did table") + return false, err1 } - return dm.DIDType, nil + return true, nil } From 9ee397dbc2debef67f6c4e4a2bf67835d38960ed Mon Sep 17 00:00:00 2001 From: Arnab Ghose Date: Thu, 9 May 2024 10:02:13 +0530 Subject: [PATCH 43/62] added checks and instructions to support execution in windows os --- tests/fixtures/testswarm.key | 4 +- tests/helper/utils.py | 30 +-- tests/node/actions.py | 221 ++++++++++---------- tests/node/commands.py | 339 +++++++++++++++++-------------- tests/node/quorum.py | 132 ++++++------ tests/node/utils.py | 32 +-- tests/node/vars.py | 4 +- tests/run.py | 343 ++++++++++++++++---------------- tests/scenarios/rbt_transfer.py | 168 ++++++++-------- tests/shutdown.py | 32 +-- 10 files changed, 671 insertions(+), 634 deletions(-) diff --git a/tests/fixtures/testswarm.key b/tests/fixtures/testswarm.key index 8985c5d0..6f0cf118 100644 --- a/tests/fixtures/testswarm.key +++ b/tests/fixtures/testswarm.key @@ -1,3 +1,3 @@ -/key/swarm/psk/1.0.0/ -/base16/ +/key/swarm/psk/1.0.0/ +/base16/ 278b9a199c43fa84178920bd9f5cbcd69e933ddf02a8f69e47a3ea5a1705512f \ No newline at end of file diff --git a/tests/helper/utils.py b/tests/helper/utils.py index 8011a780..68d8649f 100644 --- a/tests/helper/utils.py +++ b/tests/helper/utils.py @@ -1,16 +1,16 @@ -def expect_success(func): - def wrapper(*args, **kwargs): - try: - func(*args, **kwargs) - except: - raise Exception("The action was expected to pass, but it failed") - return wrapper - -def expect_failure(func): - def wrapper(*args, **kwargs): - try: - func(*args, **kwargs) - raise Exception("The action was expected to fail, but it passed") - except: - return 0 +def expect_success(func): + def wrapper(*args, **kwargs): + try: + func(*args, **kwargs) + except: + raise Exception("The action was expected to pass, but it failed") + return wrapper + +def expect_failure(func): + def wrapper(*args, **kwargs): + try: + func(*args, **kwargs) + raise Exception("The action was expected to fail, but it passed") + except: + return 0 return wrapper \ No newline at end of file diff --git a/tests/node/actions.py b/tests/node/actions.py index 7251f265..9cc014e4 100644 --- a/tests/node/actions.py +++ b/tests/node/actions.py @@ -1,111 +1,112 @@ -from .commands import cmd_run_rubix_servers, cmd_get_peer_id, cmd_create_did, cmd_register_did, \ - cmd_generate_rbt, cmd_add_quorum_dids, cmd_setup_quorum_dids, cmd_rbt_transfer -from .utils import get_node_name_from_idx, save_to_json - -def add_quorums(node_config: dict): - for config in node_config.values(): - cmd_add_quorum_dids( - config["server"], - config["grpcPort"] - ) - -def setup_quorums(node_config: dict): - for config in node_config.values(): - cmd_setup_quorum_dids( - config["did"], - config["server"], - config["grpcPort"] - ) - -def quorum_config(node_config: dict, skip_adding_quorums: bool = False, create_quorum_list: bool = False): - # Prepare quorumlist.json - quorum_list = [] - if create_quorum_list: - for config in node_config.values(): - quorum_info = { - "type": 2, - "address": config["peerId"] + "." + config["did"] - } - - quorum_list_file_path = "../linux/quorumlist.json" # TODO: make it Dynamic - quorum_list.append(quorum_info) - - save_to_json(quorum_list_file_path, quorum_list) - - # # add quorums - if not skip_adding_quorums: - add_quorums(node_config) - - setup_quorums(node_config) - - -def get_base_ports(): - base_ens_server = 20000 - base_grpc_port = 10500 - - return base_ens_server, base_grpc_port - -def setup_rubix_nodes(node_count: int = 0, node_prefix_str: str = "node"): - base_ens_server, base_grpc_port = get_base_ports() - - node_config = {} - - # Start rubix servers - loop_start_idx, loop_end_idx = 0, node_count - - for i in range(loop_start_idx, loop_end_idx): - k = i if node_prefix_str == "node" else (10+i) - - ens_server = base_ens_server + k - print(f"Running server at port: {ens_server}") - grpc_port = base_grpc_port + k - - node_name = get_node_name_from_idx(k, node_prefix_str) - - cmd_run_rubix_servers(node_name, k, grpc_port) - - node_config[node_name] = { - "did": "", - "server": ens_server, - "grpcPort": grpc_port, - "peerId": "" - } - - return node_config - - -def fetch_peer_ids(node_config: dict): - print("Fetching Node IDs........") - for config in node_config.values(): - peer_id = cmd_get_peer_id(config["server"], config["grpcPort"]) - config["peerId"] = peer_id - print("Fetched all Node IDs") - - -def create_and_register_did(node_config: dict, register_did: bool = True): - for config in node_config.values(): - did_id = cmd_create_did(config["server"], config["grpcPort"]) - print("Created DID : ", did_id) - - if register_did: - print(f"Registering DID: {did_id}") - cmd_register_did(did_id, config["server"], config["grpcPort"]) - print("DID is registered successfully\n") - - config["did"] = did_id - -def fund_dids_with_rbt(node_config: dict, rbt_amount: int = 30): - for config in node_config.values(): - cmd_generate_rbt(config["did"], rbt_amount, config["server"], config["grpcPort"]) - print("DID ", config["did"], f" is funded with {rbt_amount} RBT") - -def fund_did_with_rbt(config: dict, rbt_amount: int = 30): - output = cmd_generate_rbt(config["did"], rbt_amount, config["server"], config["grpcPort"]) - print(output) - return output - -def rbt_transfer(config_sender: dict, config_receiver: dict, transfer_rbt_amount: int): - sender_address = config_sender["peerId"] + "." + config_sender["did"] - receiver_address = config_receiver["peerId"] + "." + config_receiver["did"] - +from .commands import cmd_run_rubix_servers, cmd_get_peer_id, cmd_create_did, cmd_register_did, \ + cmd_generate_rbt, cmd_add_quorum_dids, cmd_setup_quorum_dids, cmd_rbt_transfer, get_build_dir +from .utils import get_node_name_from_idx, save_to_json + +def add_quorums(node_config: dict): + for config in node_config.values(): + cmd_add_quorum_dids( + config["server"], + config["grpcPort"] + ) + +def setup_quorums(node_config: dict): + for config in node_config.values(): + cmd_setup_quorum_dids( + config["did"], + config["server"], + config["grpcPort"] + ) + +def quorum_config(node_config: dict, skip_adding_quorums: bool = False, create_quorum_list: bool = False): + # Prepare quorumlist.json + quorum_list = [] + if create_quorum_list: + for config in node_config.values(): + quorum_info = { + "type": 2, + "address": config["peerId"] + "." + config["did"] + } + + build_dir = get_build_dir() + quorum_list_file_path = f"../{build_dir}/quorumlist.json" + quorum_list.append(quorum_info) + + save_to_json(quorum_list_file_path, quorum_list) + + # # add quorums + if not skip_adding_quorums: + add_quorums(node_config) + + setup_quorums(node_config) + + +def get_base_ports(): + base_ens_server = 20000 + base_grpc_port = 10500 + + return base_ens_server, base_grpc_port + +def setup_rubix_nodes(node_count: int = 0, node_prefix_str: str = "node"): + base_ens_server, base_grpc_port = get_base_ports() + + node_config = {} + + # Start rubix servers + loop_start_idx, loop_end_idx = 0, node_count + + for i in range(loop_start_idx, loop_end_idx): + k = i if node_prefix_str == "node" else (10+i) + + ens_server = base_ens_server + k + print(f"Running server at port: {ens_server}") + grpc_port = base_grpc_port + k + + node_name = get_node_name_from_idx(k, node_prefix_str) + + cmd_run_rubix_servers(node_name, k, grpc_port) + + node_config[node_name] = { + "did": "", + "server": ens_server, + "grpcPort": grpc_port, + "peerId": "" + } + + return node_config + + +def fetch_peer_ids(node_config: dict): + print("Fetching Node IDs........") + for config in node_config.values(): + peer_id = cmd_get_peer_id(config["server"], config["grpcPort"]) + config["peerId"] = peer_id + print("Fetched all Node IDs") + + +def create_and_register_did(node_config: dict, register_did: bool = True): + for config in node_config.values(): + did_id = cmd_create_did(config["server"], config["grpcPort"]) + print("Created DID : ", did_id) + + if register_did: + print(f"Registering DID: {did_id}") + cmd_register_did(did_id, config["server"], config["grpcPort"]) + print("DID is registered successfully\n") + + config["did"] = did_id + +def fund_dids_with_rbt(node_config: dict, rbt_amount: int = 30): + for config in node_config.values(): + cmd_generate_rbt(config["did"], rbt_amount, config["server"], config["grpcPort"]) + print("DID ", config["did"], f" is funded with {rbt_amount} RBT") + +def fund_did_with_rbt(config: dict, rbt_amount: int = 30): + output = cmd_generate_rbt(config["did"], rbt_amount, config["server"], config["grpcPort"]) + print(output) + return output + +def rbt_transfer(config_sender: dict, config_receiver: dict, transfer_rbt_amount: int): + sender_address = config_sender["peerId"] + "." + config_sender["did"] + receiver_address = config_receiver["peerId"] + "." + config_receiver["did"] + cmd_rbt_transfer(sender_address, receiver_address, transfer_rbt_amount, config_sender["server"], config_sender["grpcPort"]) \ No newline at end of file diff --git a/tests/node/commands.py b/tests/node/commands.py index 542a56df..8ca91ce3 100644 --- a/tests/node/commands.py +++ b/tests/node/commands.py @@ -1,155 +1,186 @@ -import subprocess -import os -import re -import platform - -def get_build_dir(): - os_name = platform.system() - build_folder = "" - if os_name == "Linux": - build_folder = "linux" - elif os_name == "Windows": - build_folder = "windows" - elif os_name == "Darwin": - build_folder = "mac" - - return build_folder - -def run_command(cmd_string, is_output_from_stderr=False): - assert isinstance(cmd_string, str), "command must be of string type" - cmd_result = subprocess.run(cmd_string, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True) - code = cmd_result.returncode - - if int(code) != 0: - err_output = cmd_result.stderr.decode('utf-8')[:-1] - print(err_output) - return err_output, int(code) - - output = "" - if not is_output_from_stderr: - output = cmd_result.stdout.decode('utf-8')[:-1] - print(output) - if output.find('[ERROR]') > 0 or output.find('parse error') > 0: - return output, 1 - else: - return output, code - else: - output = cmd_result.stderr.decode('utf-8')[:-1] - if output.find('[ERROR]') > 0 or output.find('parse error') > 0: - return output, 1 - else: - return output, code - -def cmd_run_rubix_servers(node_name, server_port_idx, grpc_port): - os.chdir("../" + get_build_dir()) - cmd_string = f"tmux new -s {node_name} -d ./rubixgoplatform run -p {node_name} -n {server_port_idx} -s -testNet -grpcPort {grpc_port}" - _, code = run_command(cmd_string) - if code != 0: - raise Exception("Error occurred while run the command: " + cmd_string) - os.chdir("../tests") - -def cmd_create_did(server_port, grpc_port): - os.chdir("../" + get_build_dir()) - cmd_string = f"./rubixgoplatform createdid -port {server_port} -grpcPort {grpc_port}" - output, code = run_command(cmd_string, True) - - if code != 0: - raise Exception("Error occurred while run the command: " + cmd_string) - - did_id = "" - if "successfully" in output: - pattern = r'bafybmi\w+' - matches = re.findall(pattern, output) - if matches: - did_id = matches[0] - else: - raise Exception("unable to extract DID ID") - - os.chdir("../tests") - return did_id - -def cmd_register_did(did_id, server_port, grpc_port): - os.chdir("../" + get_build_dir()) - cmd_string = f"./rubixgoplatform registerdid -did {did_id} -port {server_port} -grpcPort {grpc_port}" - output, code = run_command(cmd_string) - print(output) - - if code != 0: - raise Exception("Error occurred while run the command: " + cmd_string) - - os.chdir("../tests") - return output - -def cmd_generate_rbt(did_id, numTokens, server_port, grpc_port): - os.chdir("../" + get_build_dir()) - cmd_string = f"./rubixgoplatform generatetestrbt -did {did_id} -numTokens {numTokens} -port {server_port} -grpcPort {grpc_port}" - output, code = run_command(cmd_string, True) - - if code != 0: - raise Exception("Error occurred while run the command: " + cmd_string) - - os.chdir("../tests") - return output - -def cmd_add_quorum_dids(server_port, grpc_port): - os.chdir("../" + get_build_dir()) - cmd_string = f"./rubixgoplatform addquorum -port {server_port} -grpcPort {grpc_port}" - output, code = run_command(cmd_string, True) - print(output) - if code != 0: - raise Exception("Error occurred while run the command: " + cmd_string) - - os.chdir("../tests") - return output - -def cmd_shutdown_node(server_port, grpc_port): - os.chdir("../" + get_build_dir()) - cmd_string = f"./rubixgoplatform shutdown -port {server_port} -grpcPort {grpc_port}" - output, _ = run_command(cmd_string, True) - print(output) - - os.chdir("../tests") - return output - -def cmd_setup_quorum_dids(did, server_port, grpc_port): - os.chdir("../" + get_build_dir()) - cmd_string = f"./rubixgoplatform setupquorum -did {did} -port {server_port} -grpcPort {grpc_port}" - output, code = run_command(cmd_string, True) - print(output) - if code != 0: - raise Exception("Error occurred while run the command: " + cmd_string) - - os.chdir("../tests") - return output - -def cmd_get_peer_id(server_port, grpc_port): - os.chdir("../" + get_build_dir()) - cmd_string = f"./rubixgoplatform get-peer-id -port {server_port} -grpcPort {grpc_port}" - output, code = run_command(cmd_string) - - if code != 0: - raise Exception("Error occurred while run the command: " + cmd_string) - os.chdir("../tests") - return output - -def check_account_info(did, server_port, grpc_port): - os.chdir("../" + get_build_dir()) - cmd_string = f"./rubixgoplatform getaccountinfo -did {did} -port {server_port} -grpcPort {grpc_port}" - output, code = run_command(cmd_string) - - if code != 0: - raise Exception("Error occurred while run the command: " + cmd_string) - os.chdir("../tests") - return output - -# Note: address != did, address = peerId.didId -def cmd_rbt_transfer(sender_address, receiver_address, rbt_amount, server_port, grpc_port): - os.chdir("../" + get_build_dir()) - cmd_string = f"./rubixgoplatform transferrbt -senderAddr {sender_address} -receiverAddr {receiver_address} -rbtAmount {rbt_amount} -port {server_port} -grpcPort {grpc_port}" - output, code = run_command(cmd_string, True) - print(output) - if code != 0: - raise Exception("Error occurred while run the command: " + cmd_string) - - os.chdir("../tests") +import subprocess +import os +import re +import platform + +def is_windows_os(): + os_name = platform.system() + return os_name == "Windows" + +def get_build_dir(): + os_name = platform.system() + build_folder = "" + if os_name == "Linux": + build_folder = "linux" + elif os_name == "Windows": + build_folder = "windows" + elif os_name == "Darwin": + build_folder = "mac" + + return build_folder + +def run_command(cmd_string, is_output_from_stderr=False): + assert isinstance(cmd_string, str), "command must be of string type" + cmd_result = subprocess.run(cmd_string, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True) + code = cmd_result.returncode + + if int(code) != 0: + err_output = cmd_result.stderr.decode('utf-8')[:-1] + print(err_output) + return err_output, int(code) + + output = "" + if not is_output_from_stderr: + output = cmd_result.stdout.decode('utf-8')[:-1] + print(output) + if output.find('[ERROR]') > 0 or output.find('parse error') > 0: + return output, 1 + else: + return output, code + else: + output = cmd_result.stderr.decode('utf-8')[:-1] + if output.find('[ERROR]') > 0 or output.find('parse error') > 0: + print(output) + return output, 1 + else: + return output, code + +def cmd_run_rubix_servers(node_name, server_port_idx, grpc_port): + os.chdir("../" + get_build_dir()) + + cmd_string = "" + if is_windows_os(): + #cmd = f".\\rubixgoplatform run -p {node_name} -n {server_port_idx} -s -testNet -grpcPort {grpc_port}" + cmd_string = f"powershell -Command Start-Process -FilePath '.\\rubixgoplatform.exe' -ArgumentList 'run -p {node_name} -n {server_port_idx} -s -testNet -grpcPort {grpc_port}' -WindowStyle Hidden" + else: + cmd_string = f"tmux new -s {node_name} -d ./rubixgoplatform run -p {node_name} -n {server_port_idx} -s -testNet -grpcPort {grpc_port}" + + _, code = run_command(cmd_string) + if code != 0: + raise Exception("Error occurred while run the command: " + cmd_string) + os.chdir("../tests") + +def cmd_create_did(server_port, grpc_port): + os.chdir("../" + get_build_dir()) + + cmd_string = f"./rubixgoplatform createdid -port {server_port} -grpcPort {grpc_port}" + if is_windows_os(): + cmd_string = f".\\rubixgoplatform createdid -port {server_port} -grpcPort {grpc_port}" + output, code = run_command(cmd_string, True) + + if code != 0: + raise Exception("Error occurred while run the command: " + cmd_string) + + did_id = "" + if "successfully" in output: + pattern = r'bafybmi\w+' + matches = re.findall(pattern, output) + if matches: + did_id = matches[0] + else: + raise Exception("unable to extract DID ID") + + os.chdir("../tests") + return did_id + +def cmd_register_did(did_id, server_port, grpc_port): + os.chdir("../" + get_build_dir()) + cmd_string = f"./rubixgoplatform registerdid -did {did_id} -port {server_port} -grpcPort {grpc_port}" + if is_windows_os(): + cmd_string = f".\\rubixgoplatform registerdid -did {did_id} -port {server_port} -grpcPort {grpc_port}" + output, code = run_command(cmd_string) + print(output) + + if code != 0: + raise Exception("Error occurred while run the command: " + cmd_string) + + os.chdir("../tests") + return output + +def cmd_generate_rbt(did_id, numTokens, server_port, grpc_port): + os.chdir("../" + get_build_dir()) + cmd_string = f"./rubixgoplatform generatetestrbt -did {did_id} -numTokens {numTokens} -port {server_port} -grpcPort {grpc_port}" + if is_windows_os(): + cmd_string = f".\\rubixgoplatform generatetestrbt -did {did_id} -numTokens {numTokens} -port {server_port} -grpcPort {grpc_port}" + output, code = run_command(cmd_string, True) + + if code != 0: + raise Exception("Error occurred while run the command: " + cmd_string) + + os.chdir("../tests") + return output + +def cmd_add_quorum_dids(server_port, grpc_port): + os.chdir("../" + get_build_dir()) + cmd_string = f"./rubixgoplatform addquorum -port {server_port} -grpcPort {grpc_port}" + if is_windows_os(): + cmd_string = f".\\rubixgoplatform addquorum -port {server_port} -grpcPort {grpc_port}" + output, code = run_command(cmd_string, True) + print(output) + if code != 0: + raise Exception("Error occurred while run the command: " + cmd_string) + + os.chdir("../tests") + return output + +def cmd_shutdown_node(server_port, grpc_port): + os.chdir("../" + get_build_dir()) + cmd_string = f"./rubixgoplatform shutdown -port {server_port} -grpcPort {grpc_port}" + if is_windows_os(): + cmd_string = f".\\rubixgoplatform shutdown -port {server_port} -grpcPort {grpc_port}" + output, _ = run_command(cmd_string, True) + print(output) + + os.chdir("../tests") + return output + +def cmd_setup_quorum_dids(did, server_port, grpc_port): + os.chdir("../" + get_build_dir()) + cmd_string = f"./rubixgoplatform setupquorum -did {did} -port {server_port} -grpcPort {grpc_port}" + if is_windows_os(): + cmd_string = f".\\rubixgoplatform setupquorum -did {did} -port {server_port} -grpcPort {grpc_port}" + output, code = run_command(cmd_string, True) + print(output) + if code != 0: + raise Exception("Error occurred while run the command: " + cmd_string) + + os.chdir("../tests") + return output + +def cmd_get_peer_id(server_port, grpc_port): + os.chdir("../" + get_build_dir()) + cmd_string = f"./rubixgoplatform get-peer-id -port {server_port} -grpcPort {grpc_port}" + if is_windows_os(): + cmd_string = f".\\rubixgoplatform get-peer-id -port {server_port} -grpcPort {grpc_port}" + output, code = run_command(cmd_string) + + if code != 0: + raise Exception("Error occurred while run the command: " + cmd_string) + os.chdir("../tests") + return output + +def check_account_info(did, server_port, grpc_port): + os.chdir("../" + get_build_dir()) + cmd_string = f"./rubixgoplatform getaccountinfo -did {did} -port {server_port} -grpcPort {grpc_port}" + if is_windows_os(): + cmd_string = f".\\rubixgoplatform getaccountinfo -did {did} -port {server_port} -grpcPort {grpc_port}" + output, code = run_command(cmd_string) + + if code != 0: + raise Exception("Error occurred while run the command: " + cmd_string) + os.chdir("../tests") + return output + +# Note: address != did, address = peerId.didId +def cmd_rbt_transfer(sender_address, receiver_address, rbt_amount, server_port, grpc_port): + os.chdir("../" + get_build_dir()) + cmd_string = f"./rubixgoplatform transferrbt -senderAddr {sender_address} -receiverAddr {receiver_address} -rbtAmount {rbt_amount} -port {server_port} -grpcPort {grpc_port}" + if is_windows_os(): + cmd_string = f".\\rubixgoplatform transferrbt -senderAddr {sender_address} -receiverAddr {receiver_address} -rbtAmount {rbt_amount} -port {server_port} -grpcPort {grpc_port}" + output, code = run_command(cmd_string, True) + print(output) + if code != 0: + raise Exception("Error occurred while run the command: " + cmd_string) + + os.chdir("../tests") return output \ No newline at end of file diff --git a/tests/node/quorum.py b/tests/node/quorum.py index b8ca59d7..ba5de3d3 100644 --- a/tests/node/quorum.py +++ b/tests/node/quorum.py @@ -1,67 +1,67 @@ -import pprint -import time - -from .actions import setup_rubix_nodes, fetch_peer_ids, create_and_register_did, \ - fund_dids_with_rbt, quorum_config -from .utils import save_to_json - -def run_quorum_nodes(node_config_path, only_run_nodes, skip_adding_quorums): - node_config_path = "./quorum_config.json" - - print("Running Rubix nodes......") - node_config = setup_rubix_nodes(5) - print("Rubix nodes are now running") - - if not only_run_nodes: - print("Waiting 20 seconds before fetching all node peer IDs............") - time.sleep(20) - - fetch_peer_ids(node_config) - - print("Creation and registeration of quorum DIDs have started") - create_and_register_did(node_config) - print("All quorum DIDs have been registered") - - print("Initiating funding of these quorum DIDs") - fund_dids_with_rbt(node_config) - print("All Quorum DIDs have been funded") - - save_to_json(node_config_path, node_config) - - print("Setting up quorums and saving information about them to quorumlist.json") - quorum_config(node_config, skip_adding_quorums=skip_adding_quorums, create_quorum_list=True) - - pprint.pp(node_config) - print("Quorums have been configured. You can proceed with running Test scenarios") - else: - quorum_config(node_config, skip_adding_quorums=True, create_quorum_list=False) - - return node_config - -def run_non_quorum_nodes(node_config_path, only_run_nodes, skip_adding_quorums): - node_config_path = "./non_quorum_config.json" - - print("Running non-quorum nodes...") - node_config = setup_rubix_nodes(2, "nodeNq") - print("Non-quorum nodes are running successfully") - - if not only_run_nodes: - print("Waiting 20 seconds before fetching all node peer IDs............") - time.sleep(20) - fetch_peer_ids(node_config) - - print("Creation of Non Quorum DIDs have started") - create_and_register_did(node_config, False) - print("Non Quorum DIDs have been created") - - save_to_json(node_config_path, node_config) - - print("Adding and setting up quorum config") - quorum_config(node_config, skip_adding_quorums=skip_adding_quorums, create_quorum_list=False) - - pprint.pp(node_config) - print("Non Quorum nodes have been configured") - else: - quorum_config(node_config, skip_adding_quorums=True, create_quorum_list=False) - +import pprint +import time + +from .actions import setup_rubix_nodes, fetch_peer_ids, create_and_register_did, \ + fund_dids_with_rbt, quorum_config +from .utils import save_to_json + +def run_quorum_nodes(node_config_path, only_run_nodes, skip_adding_quorums): + node_config_path = "./quorum_config.json" + + print("Running Rubix nodes......") + node_config = setup_rubix_nodes(5) + print("Rubix nodes are now running") + + if not only_run_nodes: + print("Waiting 60 seconds before fetching all node peer IDs............") + time.sleep(60) + + fetch_peer_ids(node_config) + + print("Creation and registeration of quorum DIDs have started") + create_and_register_did(node_config) + print("All quorum DIDs have been registered") + + print("Initiating funding of these quorum DIDs") + fund_dids_with_rbt(node_config) + print("All Quorum DIDs have been funded") + + save_to_json(node_config_path, node_config) + + print("Setting up quorums and saving information about them to quorumlist.json") + quorum_config(node_config, skip_adding_quorums=skip_adding_quorums, create_quorum_list=True) + + pprint.pp(node_config) + print("Quorums have been configured") + else: + quorum_config(node_config, skip_adding_quorums=True, create_quorum_list=False) + + return node_config + +def run_non_quorum_nodes(node_config_path, only_run_nodes, skip_adding_quorums): + node_config_path = "./non_quorum_config.json" + + print("Running non-quorum nodes...") + node_config = setup_rubix_nodes(2, "nodeNq") + print("Non-quorum nodes are running successfully") + + if not only_run_nodes: + print("Waiting 30 seconds before fetching all node peer IDs............") + time.sleep(30) + fetch_peer_ids(node_config) + + print("Creation of Non Quorum DIDs have started") + create_and_register_did(node_config, False) + print("Non Quorum DIDs have been created") + + save_to_json(node_config_path, node_config) + + print("Adding and setting up quorum config") + quorum_config(node_config, skip_adding_quorums=skip_adding_quorums, create_quorum_list=False) + + pprint.pp(node_config) + print("Non Quorum nodes have been configured") + else: + quorum_config(node_config, skip_adding_quorums=True, create_quorum_list=False) + return node_config \ No newline at end of file diff --git a/tests/node/utils.py b/tests/node/utils.py index 61bcdbe7..a30cfa47 100644 --- a/tests/node/utils.py +++ b/tests/node/utils.py @@ -1,16 +1,16 @@ -import json -import sys -import os -sys.path.insert(1, os.getcwd()) -from .vars import QUORUM_NODES - -def get_node_name_from_idx(idx, prefix_string: str = "node"): - return prefix_string + str(idx) - -def save_to_json(filepath, obj): - # Check if file exists. If yes, then remove it - if os.path.exists(filepath): - os.remove(filepath) - - with open(filepath, 'w') as f: - json.dump(obj, f, indent=4) +import json +import sys +import os +sys.path.insert(1, os.getcwd()) +from .vars import QUORUM_NODES + +def get_node_name_from_idx(idx, prefix_string: str = "node"): + return prefix_string + str(idx) + +def save_to_json(filepath, obj): + # Check if file exists. If yes, then remove it + if os.path.exists(filepath): + os.remove(filepath) + + with open(filepath, 'w') as f: + json.dump(obj, f, indent=4) diff --git a/tests/node/vars.py b/tests/node/vars.py index 7b683fcb..1cdf27f6 100644 --- a/tests/node/vars.py +++ b/tests/node/vars.py @@ -1,2 +1,2 @@ -QUORUM_NODES = 5 - +QUORUM_NODES = 5 + diff --git a/tests/run.py b/tests/run.py index 7e8c091b..6dbaf35a 100644 --- a/tests/run.py +++ b/tests/run.py @@ -1,169 +1,174 @@ -import platform -import os -import shutil -import requests -import argparse -from node.commands import run_command -from node.quorum import run_quorum_nodes, run_non_quorum_nodes -from scenarios.rbt_transfer import * - -IPFS_KUBO_VERSION = "v0.21.0" -QUORUM_CONFIG_FILE = "./quorum_config.json" -NON_QUORUM_CONFIG_FILE = "./non_quorum_config.json" - -def get_os_info(): - os_name = platform.system() - build_folder = "" - - if os_name == "Linux": - build_folder = "linux" - elif os_name == "Windows": - build_folder = "windows" - elif os_name == "Darwin": - build_folder = "mac" - else: - print("Unsupported operating system to build Rubix") - return None, None - - return os_name, build_folder - -def download_ipfs_binary(os_name, version, build_dir): - download_url = "" - - if os_name == "Linux": - download_url = f"https://dist.ipfs.tech/kubo/{version}/kubo_{version}_linux-amd64.tar.gz" - elif os_name == "Windows": - download_url = f"https://dist.ipfs.tech/kubo/{version}/kubo_{version}_windows-amd64.zip" - elif os_name == "Darwin": # MacOS - download_url = f"https://dist.ipfs.tech/kubo/{version}/kubo_{version}_darwin-amd64.tar.gz" - else: - raise ValueError("Unsupported operating system") - - # Download the IPFS binary archive - download_path = f"kubo_{version}_{os_name.lower()}-amd64.tar.gz" if os_name != "Windows" else f"kubo_{version}_{os_name.lower()}-amd64.zip" - print("Downloading IPFS binary...") - response = requests.get(download_url) - with open(download_path, "wb") as f: - f.write(response.content) - print("Download completed.") - - # Extract the archive - print("Extracting IPFS binary...") - if os_name == "Windows": - # For Windows, we need to use the 'zipfile' module to extract - import zipfile - with zipfile.ZipFile(download_path, "r") as zip_ref: - zip_ref.extractall("kubo") - else: - # For Linux and MacOS, we use tar - import tarfile - with tarfile.open(download_path, "r:gz" if os_name != "Darwin" else "r") as tar_ref: - tar_ref.extractall("kubo") - print("Extraction completed.") - - # Check the contents of the kubo directory - print("Contents of kubo directory:") - for item in os.listdir("kubo"): - print(item) - - # Move IPFS binary to the appropriate folder - print("Moving IPFS binary...") - src_file = os.path.join("kubo", "kubo", "ipfs") - dest_dir = os.path.join(build_dir, "ipfs") - if os.path.exists(src_file): - shutil.move(src_file, dest_dir) - print("IPFS binary moved to", dest_dir) - - # Check if the file is present at the destination - dest_file = os.path.join(dest_dir) - if not os.path.exists(dest_file): - raise FileNotFoundError("IPFS binary not found at the destination after move operation.") - else: - raise FileNotFoundError("Installed IPFS binary file does not exist.") - - # Clean up - os.remove(download_path) - shutil.rmtree("kubo") - print("\nIPFS has been installed succesfully.") - -def copy_fixtures_to_build_dir(build_directory): - fixtures_directory = os.path.join("tests", "fixtures") - - # Copy didimage.png.file - image_file_src = os.path.join(fixtures_directory, "didimage.png.file") - image_file_dest = os.path.join(build_directory, "image.png") - shutil.copyfile(image_file_src, image_file_dest) - - if not os.path.exists(image_file_dest): - raise FileNotFoundError(f"Copy operation for didimage.png.file failed. Destination file not found: {image_file_dest}") - - # Copy testswarm.key - swarmkey_src = os.path.join(fixtures_directory, "testswarm.key") - swarmkey_dest = os.path.join(build_directory, "testswarm.key") - shutil.copyfile(swarmkey_src, swarmkey_dest) - - if not os.path.exists(swarmkey_dest): - raise FileNotFoundError(f"Copy operation for testswarm.key failed. Destination file not found: {swarmkey_dest}") - - print("\nimage.png and swarm key have been added to build directory successfully") - -def cli(): - parser = argparse.ArgumentParser(description="CLI to run tests for Rubix") - parser.add_argument("--skip_prerequisite", action=argparse.BooleanOptionalAction, help="skip prerequisite steps such as installing IPFS and building Rubix") - parser.add_argument("--run_nodes_only", action=argparse.BooleanOptionalAction, help="only run the rubix nodes and skip the setup") - parser.add_argument("--skip_adding_quorums", action=argparse.BooleanOptionalAction, help="skips adding quorums") - parser.add_argument("--run_tests_only", action=argparse.BooleanOptionalAction, help="only proceed with running tests") - return parser.parse_args() - - -if __name__=='__main__': - os.chdir("../") - - args = cli() - skip_prerequisite = args.skip_prerequisite - run_nodes_only = args.run_nodes_only - skip_adding_quorums = args.skip_adding_quorums - run_tests_only = args.run_tests_only - - non_quorum_node_config = {} - - if not run_tests_only: - os_name, build_folder = get_os_info() - if os_name is None: - exit(1) - - if not skip_prerequisite: - print(f"Building Rubix binary for {os_name}\n") - build_command = "" - if os_name == "Linux": - build_command = "make compile-linux" - elif os_name == "Windows": - build_command = "make compile-windows" - elif os_name == "Darwin": - build_command = "make compile-mac" - - output, code = run_command(build_command) - if code != 0: - print("build failed with error:", output) - exit(1) - else: - print("\nBuild successful\n") - - - download_ipfs_binary(os_name, IPFS_KUBO_VERSION, build_folder) - copy_fixtures_to_build_dir(build_folder) - os.chdir("./tests") - - run_quorum_nodes(QUORUM_CONFIG_FILE, run_nodes_only, skip_adding_quorums=skip_adding_quorums) - - non_quorum_node_config = run_non_quorum_nodes(NON_QUORUM_CONFIG_FILE, run_nodes_only, skip_adding_quorums=skip_adding_quorums) - - # Run RBT Transfer related tests - rbt_transfer_test_list = [ - shuttle_transfer, - insufficient_balance_transfer, - max_decimal_place_transfer - ] - for testFn in rbt_transfer_test_list: - testFn(non_quorum_node_config) - +import platform +import os +import shutil +import requests +import argparse +from node.commands import run_command +from node.quorum import run_quorum_nodes, run_non_quorum_nodes +from scenarios.rbt_transfer import * + +IPFS_KUBO_VERSION = "v0.21.0" +QUORUM_CONFIG_FILE = "./quorum_config.json" +NON_QUORUM_CONFIG_FILE = "./non_quorum_config.json" + +def get_os_info(): + os_name = platform.system() + build_folder = "" + + if os_name == "Linux": + build_folder = "linux" + elif os_name == "Windows": + build_folder = "windows" + elif os_name == "Darwin": + build_folder = "mac" + else: + print("Unsupported operating system to build Rubix") + return None, None + + return os_name, build_folder + +def download_ipfs_binary(os_name, version, build_dir): + download_url = "" + + if os_name == "Linux": + download_url = f"https://dist.ipfs.tech/kubo/{version}/kubo_{version}_linux-amd64.tar.gz" + elif os_name == "Windows": + download_url = f"https://dist.ipfs.tech/kubo/{version}/kubo_{version}_windows-amd64.zip" + elif os_name == "Darwin": # MacOS + download_url = f"https://dist.ipfs.tech/kubo/{version}/kubo_{version}_darwin-amd64.tar.gz" + else: + raise ValueError("Unsupported operating system") + + # Download the IPFS binary archive + download_path = f"kubo_{version}_{os_name.lower()}-amd64.tar.gz" if os_name != "Windows" else f"kubo_{version}_{os_name.lower()}-amd64.zip" + print("Downloading IPFS binary...") + response = requests.get(download_url) + with open(download_path, "wb") as f: + f.write(response.content) + print("Download completed.") + + # Extract the archive + print("Extracting IPFS binary...") + if os_name == "Windows": + # For Windows, we need to use the 'zipfile' module to extract + import zipfile + with zipfile.ZipFile(download_path, "r") as zip_ref: + zip_ref.extractall("kubo") + else: + # For Linux and MacOS, we use tar + import tarfile + with tarfile.open(download_path, "r:gz" if os_name != "Darwin" else "r") as tar_ref: + tar_ref.extractall("kubo") + print("Extraction completed.") + + # Check the contents of the kubo directory + print("Contents of kubo directory:") + for item in os.listdir("kubo"): + print(item) + + # Move IPFS binary to the appropriate folder + print("Moving IPFS binary...") + + ipfs_bin_name = "ipfs" + if os_name == "Windows": + ipfs_bin_name = "ipfs.exe" + + src_file = os.path.join("kubo", "kubo", ipfs_bin_name) + dest_dir = os.path.join(build_dir, ipfs_bin_name) + if os.path.exists(src_file): + shutil.move(src_file, dest_dir) + print("IPFS binary moved to", dest_dir) + + # Check if the file is present at the destination + dest_file = os.path.join(dest_dir) + if not os.path.exists(dest_file): + raise FileNotFoundError("IPFS binary not found at the destination after move operation.") + else: + raise FileNotFoundError("Installed IPFS binary file does not exist.") + + # Clean up + os.remove(download_path) + shutil.rmtree("kubo") + print("\nIPFS has been installed succesfully.") + +def copy_fixtures_to_build_dir(build_directory): + fixtures_directory = os.path.join("tests", "fixtures") + + # Copy didimage.png.file + image_file_src = os.path.join(fixtures_directory, "didimage.png.file") + image_file_dest = os.path.join(build_directory, "image.png") + shutil.copyfile(image_file_src, image_file_dest) + + if not os.path.exists(image_file_dest): + raise FileNotFoundError(f"Copy operation for didimage.png.file failed. Destination file not found: {image_file_dest}") + + # Copy testswarm.key + swarmkey_src = os.path.join(fixtures_directory, "testswarm.key") + swarmkey_dest = os.path.join(build_directory, "testswarm.key") + shutil.copyfile(swarmkey_src, swarmkey_dest) + + if not os.path.exists(swarmkey_dest): + raise FileNotFoundError(f"Copy operation for testswarm.key failed. Destination file not found: {swarmkey_dest}") + + print("\nimage.png and swarm key have been added to build directory successfully") + +def cli(): + parser = argparse.ArgumentParser(description="CLI to run tests for Rubix") + parser.add_argument("--skip_prerequisite", action=argparse.BooleanOptionalAction, help="skip prerequisite steps such as installing IPFS and building Rubix") + parser.add_argument("--run_nodes_only", action=argparse.BooleanOptionalAction, help="only run the rubix nodes and skip the setup") + parser.add_argument("--skip_adding_quorums", action=argparse.BooleanOptionalAction, help="skips adding quorums") + parser.add_argument("--run_tests_only", action=argparse.BooleanOptionalAction, help="only proceed with running tests") + return parser.parse_args() + + +if __name__=='__main__': + os.chdir("../") + + args = cli() + skip_prerequisite = args.skip_prerequisite + run_nodes_only = args.run_nodes_only + skip_adding_quorums = args.skip_adding_quorums + run_tests_only = args.run_tests_only + + non_quorum_node_config = {} + + if not run_tests_only: + os_name, build_folder = get_os_info() + if os_name is None: + exit(1) + + if not skip_prerequisite: + print(f"Building Rubix binary for {os_name}\n") + build_command = "" + if os_name == "Linux": + build_command = "make compile-linux" + elif os_name == "Windows": + build_command = "make compile-windows" + elif os_name == "Darwin": + build_command = "make compile-mac" + + output, code = run_command(build_command) + if code != 0: + print("build failed with error:", output) + exit(1) + else: + print("\nBuild successful\n") + + + download_ipfs_binary(os_name, IPFS_KUBO_VERSION, build_folder) + copy_fixtures_to_build_dir(build_folder) + os.chdir("./tests") + + run_quorum_nodes(QUORUM_CONFIG_FILE, run_nodes_only, skip_adding_quorums=skip_adding_quorums) + + non_quorum_node_config = run_non_quorum_nodes(NON_QUORUM_CONFIG_FILE, run_nodes_only, skip_adding_quorums=skip_adding_quorums) + + # Run RBT Transfer related tests + rbt_transfer_test_list = [ + shuttle_transfer, + insufficient_balance_transfer, + max_decimal_place_transfer + ] + for testFn in rbt_transfer_test_list: + testFn(non_quorum_node_config) + diff --git a/tests/scenarios/rbt_transfer.py b/tests/scenarios/rbt_transfer.py index 78454198..f8688744 100644 --- a/tests/scenarios/rbt_transfer.py +++ b/tests/scenarios/rbt_transfer.py @@ -1,84 +1,84 @@ -from node.actions import rbt_transfer, fund_did_with_rbt -from helper.utils import expect_failure, expect_success - -def max_decimal_place_transfer(config): - node_A_info = config["nodeNq10"] - node_B_info = config["nodeNq11"] - - print("------ Test Case (FAIL) : Transferring 0.00000009 RBT from B which is more than allowed decimal places ------") - - print("\nTransferring 0.00000009 RBT from B to A....") - expect_failure(rbt_transfer)(node_B_info, node_A_info, 0.00000009) - - print("\n------ Test Case (FAIL) : Transferring 0.00000009 RBT from B which is more than allowed decimal places completed ------\n") - -def insufficient_balance_transfer(config): - node_A_info = config["nodeNq10"] - node_B_info = config["nodeNq11"] - - print("\n------ Test Case (FAIL) : Transferring 100 RBT from A which has zero balance ------") - - print("\nTransferring 100 RBT from A to B....") - expect_failure(rbt_transfer)(node_A_info, node_B_info, 100) - - print("\n------ Test Case (FAIL) : Transferring 100 RBT from A which has zero balance completed ------\n") - - - print("\n------ Test Case (FAIL) : Transferring 100 RBT from B which has insufficient balance ------") - - print("\nTransferring 100 RBT from B to A....") - expect_failure(rbt_transfer)(node_B_info, node_A_info, 100) - - print("\n------ Test Case (FAIL) : Transferring 100 RBT from B which has insufficient balance completed ------\n") - -def shuttle_transfer(config): - node_A_info = config["nodeNq10"] - node_B_info = config["nodeNq11"] - - print("------ Test Case (PASS): Shuttle transfer started ------\n") - - print("\n1. Generating 2 whole RBT for A") - expect_success(fund_did_with_rbt)(node_A_info, 2) - print("Funded node A with 2 RBT") - - print("\n2. Transferring 0.5 RBT from A to B....") - expect_success(rbt_transfer)(node_A_info, node_B_info, 0.5) - print("Transferred 0.5 RBT from A to B") - - print("\n3. Transferring 1.499 RBT from A to B....") - expect_success(rbt_transfer)(node_A_info, node_B_info, 1.499) - print("Transferred 1.499 RBT from A to B") - - print("\n4. Transferring 0.25 RBT from B to A....") - expect_success(rbt_transfer)(node_B_info, node_A_info, 0.25) - print("Transferred 0.25 RBT from B to A") - - print("\n5. Transferring 0.25 RBT from B to A....") - expect_success(rbt_transfer)(node_B_info, node_A_info, 0.25) - print("Transferred 0.25 RBT from B to A") - - print("\n6. Transferring 0.25 RBT from B to A....") - expect_success(rbt_transfer)(node_B_info, node_A_info, 0.25) - print("Transferred 0.25 RBT from B to A") - - print("\n7. Transferring 0.25 RBT from B to A....") - expect_success(rbt_transfer)(node_B_info, node_A_info, 0.25) - print("Transferred 0.25 RBT from B to A") - - print("\n8. Transferring 1 RBT from A to B....") - expect_success(rbt_transfer)(node_A_info, node_B_info, 1) - print("Transferred 1 RBT from A to B") - - print("\n9. Generating 2 whole RBT for A") - expect_success(fund_did_with_rbt)(node_A_info, 2) - print("Funded node A with 2 RBT") - - print("\n10. Transferring 2 RBT from A to B....") - expect_success(rbt_transfer)(node_A_info, node_B_info, 2) - print("Transferred 2 RBT from A to B") - - print("\n11. Transferring 0.001 RBT from A to B....") - expect_success(rbt_transfer)(node_A_info, node_B_info, 0.001) - print("Transferred 0.001 RBT from A to B") - - print("\n------ Test Case (PASS): Shuttle transfer completed ------\n") +from node.actions import rbt_transfer, fund_did_with_rbt +from helper.utils import expect_failure, expect_success + +def max_decimal_place_transfer(config): + node_A_info = config["nodeNq10"] + node_B_info = config["nodeNq11"] + + print("------ Test Case (FAIL) : Transferring 0.00000009 RBT from B which is more than allowed decimal places ------") + + print("\nTransferring 0.00000009 RBT from B to A....") + expect_failure(rbt_transfer)(node_B_info, node_A_info, 0.00000009) + + print("\n------ Test Case (FAIL) : Transferring 0.00000009 RBT from B which is more than allowed decimal places completed ------\n") + +def insufficient_balance_transfer(config): + node_A_info = config["nodeNq10"] + node_B_info = config["nodeNq11"] + + print("\n------ Test Case (FAIL) : Transferring 100 RBT from A which has zero balance ------") + + print("\nTransferring 100 RBT from A to B....") + expect_failure(rbt_transfer)(node_A_info, node_B_info, 100) + + print("\n------ Test Case (FAIL) : Transferring 100 RBT from A which has zero balance completed ------\n") + + + print("\n------ Test Case (FAIL) : Transferring 100 RBT from B which has insufficient balance ------") + + print("\nTransferring 100 RBT from B to A....") + expect_failure(rbt_transfer)(node_B_info, node_A_info, 100) + + print("\n------ Test Case (FAIL) : Transferring 100 RBT from B which has insufficient balance completed ------\n") + +def shuttle_transfer(config): + node_A_info = config["nodeNq10"] + node_B_info = config["nodeNq11"] + + print("------ Test Case (PASS): Shuttle transfer started ------\n") + + print("\n1. Generating 2 whole RBT for A") + expect_success(fund_did_with_rbt)(node_A_info, 2) + print("Funded node A with 2 RBT") + + print("\n2. Transferring 0.5 RBT from A to B....") + expect_success(rbt_transfer)(node_A_info, node_B_info, 0.5) + print("Transferred 0.5 RBT from A to B") + + print("\n3. Transferring 1.499 RBT from A to B....") + expect_success(rbt_transfer)(node_A_info, node_B_info, 1.499) + print("Transferred 1.499 RBT from A to B") + + print("\n4. Transferring 0.25 RBT from B to A....") + expect_success(rbt_transfer)(node_B_info, node_A_info, 0.25) + print("Transferred 0.25 RBT from B to A") + + print("\n5. Transferring 0.25 RBT from B to A....") + expect_success(rbt_transfer)(node_B_info, node_A_info, 0.25) + print("Transferred 0.25 RBT from B to A") + + print("\n6. Transferring 0.25 RBT from B to A....") + expect_success(rbt_transfer)(node_B_info, node_A_info, 0.25) + print("Transferred 0.25 RBT from B to A") + + print("\n7. Transferring 0.25 RBT from B to A....") + expect_success(rbt_transfer)(node_B_info, node_A_info, 0.25) + print("Transferred 0.25 RBT from B to A") + + print("\n8. Transferring 1 RBT from A to B....") + expect_success(rbt_transfer)(node_A_info, node_B_info, 1) + print("Transferred 1 RBT from A to B") + + print("\n9. Generating 2 whole RBT for A") + expect_success(fund_did_with_rbt)(node_A_info, 2) + print("Funded node A with 2 RBT") + + print("\n10. Transferring 2 RBT from A to B....") + expect_success(rbt_transfer)(node_A_info, node_B_info, 2) + print("Transferred 2 RBT from A to B") + + print("\n11. Transferring 0.001 RBT from A to B....") + expect_success(rbt_transfer)(node_A_info, node_B_info, 0.001) + print("Transferred 0.001 RBT from A to B") + + print("\n------ Test Case (PASS): Shuttle transfer completed ------\n") diff --git a/tests/shutdown.py b/tests/shutdown.py index 05c6a090..5e9d2399 100644 --- a/tests/shutdown.py +++ b/tests/shutdown.py @@ -1,16 +1,16 @@ -from node.commands import cmd_shutdown_node -from node.actions import get_base_ports - -quorum_base_server, quorum_grpc_server = get_base_ports() - -for i in range(0, 5): - server_port = quorum_base_server + i - grpc_port = quorum_grpc_server + i - - cmd_shutdown_node(server_port, grpc_port) - -for i in range(0, 2): - server_port = quorum_base_server + 10 + i - grpc_port = quorum_grpc_server + 10 + i - - cmd_shutdown_node(server_port, grpc_port) +from node.commands import cmd_shutdown_node +from node.actions import get_base_ports + +quorum_base_server, quorum_grpc_server = get_base_ports() + +for i in range(0, 5): + server_port = quorum_base_server + i + grpc_port = quorum_grpc_server + i + + cmd_shutdown_node(server_port, grpc_port) + +for i in range(0, 2): + server_port = quorum_base_server + 10 + i + grpc_port = quorum_grpc_server + 10 + i + + cmd_shutdown_node(server_port, grpc_port) From 78d03f42d3566397ce2f012ef24dc0bc21ea68b1 Mon Sep 17 00:00:00 2001 From: Arnab Ghose Date: Mon, 13 May 2024 10:04:32 +0530 Subject: [PATCH 44/62] feat: added test workflow --- .github/workflows/tests.yml | 93 +++++++++++++++++++++++++++++++++ tests/node/actions.py | 12 +++-- tests/node/commands.py | 26 ++++++++- tests/node/quorum.py | 7 +-- tests/scenarios/rbt_transfer.py | 10 ++-- tests/scenarios/util.py | 9 ++++ tests/shutdown.py | 5 +- 7 files changed, 142 insertions(+), 20 deletions(-) create mode 100644 .github/workflows/tests.yml create mode 100644 tests/scenarios/util.py diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml new file mode 100644 index 00000000..0f9dc3de --- /dev/null +++ b/.github/workflows/tests.yml @@ -0,0 +1,93 @@ +name: Test Workflow + +on: + pull_request: + branches: + - development + - main + +jobs: + test-linux: + name: "Test - Linux Environment" + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + with: + fetch-depth: 0 + + - name: Setup Golang v1.21.9 + uses: actions/setup-go@v5 + with: + go-version: '1.21.9' + + - name: Setup Python v3.11 + uses: actions/setup-python@v5 + with: + python-version: '3.11' + + - name: Install test dependency + run: | + pip3 install requests + + - name: Run tests + run: | + cd tests && ls && python3 -u run.py + + test-macos: + name: "Test - MacOS Environment" + runs-on: macos-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + with: + fetch-depth: 0 + + - name: Setup Golang v1.21.9 + uses: actions/setup-go@v5 + with: + go-version: '1.21.9' + + - name: Setup Python v3.11 + uses: actions/setup-python@v5 + with: + python-version: '3.11' + + - name: Install test dependency + run: | + pip3 install requests + + - name: MacOS install tmux + run: brew install tmux + + - name: Run tests + run: | + cd tests && ls && python3 -u run.py + + test-windows: + name: "Test - Windows Environment" + runs-on: windows-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + with: + fetch-depth: 0 + + - name: Setup Golang v1.21.9 + uses: actions/setup-go@v5 + with: + go-version: '1.21.9' + + - name: Setup Python v3.11 + uses: actions/setup-python@v5 + with: + python-version: '3.11' + + - name: Install test dependency + run: | + pip3 install requests + + - name: Run tests + run: | + cd tests && ls && python3 -u run.py + diff --git a/tests/node/actions.py b/tests/node/actions.py index 9cc014e4..450be822 100644 --- a/tests/node/actions.py +++ b/tests/node/actions.py @@ -53,9 +53,10 @@ def setup_rubix_nodes(node_count: int = 0, node_prefix_str: str = "node"): # Start rubix servers loop_start_idx, loop_end_idx = 0, node_count - + offset = 4 + for i in range(loop_start_idx, loop_end_idx): - k = i if node_prefix_str == "node" else (10+i) + k = (i + offset) if node_prefix_str == "node" else (10 + i + offset) ens_server = base_ens_server + k print(f"Running server at port: {ens_server}") @@ -96,9 +97,10 @@ def create_and_register_did(node_config: dict, register_did: bool = True): config["did"] = did_id def fund_dids_with_rbt(node_config: dict, rbt_amount: int = 30): - for config in node_config.values(): - cmd_generate_rbt(config["did"], rbt_amount, config["server"], config["grpcPort"]) - print("DID ", config["did"], f" is funded with {rbt_amount} RBT") + for node, config in node_config.items(): + if node not in ["node5", "node6", "node7", "node8"]: + cmd_generate_rbt(config["did"], rbt_amount, config["server"], config["grpcPort"]) + print("DID ", config["did"], f" is funded with {rbt_amount} RBT") def fund_did_with_rbt(config: dict, rbt_amount: int = 30): output = cmd_generate_rbt(config["did"], rbt_amount, config["server"], config["grpcPort"]) diff --git a/tests/node/commands.py b/tests/node/commands.py index 8ca91ce3..4d674cc5 100644 --- a/tests/node/commands.py +++ b/tests/node/commands.py @@ -2,6 +2,8 @@ import os import re import platform +import time +import requests def is_windows_os(): os_name = platform.system() @@ -50,7 +52,6 @@ def cmd_run_rubix_servers(node_name, server_port_idx, grpc_port): cmd_string = "" if is_windows_os(): - #cmd = f".\\rubixgoplatform run -p {node_name} -n {server_port_idx} -s -testNet -grpcPort {grpc_port}" cmd_string = f"powershell -Command Start-Process -FilePath '.\\rubixgoplatform.exe' -ArgumentList 'run -p {node_name} -n {server_port_idx} -s -testNet -grpcPort {grpc_port}' -WindowStyle Hidden" else: cmd_string = f"tmux new -s {node_name} -d ./rubixgoplatform run -p {node_name} -n {server_port_idx} -s -testNet -grpcPort {grpc_port}" @@ -58,8 +59,31 @@ def cmd_run_rubix_servers(node_name, server_port_idx, grpc_port): _, code = run_command(cmd_string) if code != 0: raise Exception("Error occurred while run the command: " + cmd_string) + + print("Waiting for 60 seconds before checking if its running....") + time.sleep(60) + try: + check_if_all_nodes_are_running(server_port_idx) + except Exception as e: + raise e os.chdir("../tests") +def check_if_all_nodes_are_running(server_idx): + + base_server = 20000 + port = base_server + int(server_idx) + print(f"Check if server with ENS web server port {port} is running...") + url = f"http://localhost:{port}/api/getalldid" + try: + print(f"Sending GET request to URL: {url}") + response = requests.get(url) + if response.status_code == 200: + print(f"Server with port {port} is running successfully") + else: + raise Exception(f"Failed with Status Code: {response.status_code} | Server with port {port} is NOT running successfully") + except: + raise Exception(f"ConnectionError | Server with port {port} is NOT running successfully") + def cmd_create_did(server_port, grpc_port): os.chdir("../" + get_build_dir()) diff --git a/tests/node/quorum.py b/tests/node/quorum.py index ba5de3d3..62701bf4 100644 --- a/tests/node/quorum.py +++ b/tests/node/quorum.py @@ -13,9 +13,6 @@ def run_quorum_nodes(node_config_path, only_run_nodes, skip_adding_quorums): print("Rubix nodes are now running") if not only_run_nodes: - print("Waiting 60 seconds before fetching all node peer IDs............") - time.sleep(60) - fetch_peer_ids(node_config) print("Creation and registeration of quorum DIDs have started") @@ -45,9 +42,7 @@ def run_non_quorum_nodes(node_config_path, only_run_nodes, skip_adding_quorums): node_config = setup_rubix_nodes(2, "nodeNq") print("Non-quorum nodes are running successfully") - if not only_run_nodes: - print("Waiting 30 seconds before fetching all node peer IDs............") - time.sleep(30) + if not only_run_nodes: fetch_peer_ids(node_config) print("Creation of Non Quorum DIDs have started") diff --git a/tests/scenarios/rbt_transfer.py b/tests/scenarios/rbt_transfer.py index f8688744..315960fd 100644 --- a/tests/scenarios/rbt_transfer.py +++ b/tests/scenarios/rbt_transfer.py @@ -1,9 +1,9 @@ from node.actions import rbt_transfer, fund_did_with_rbt from helper.utils import expect_failure, expect_success +from .util import get_non_quorum_node_configs def max_decimal_place_transfer(config): - node_A_info = config["nodeNq10"] - node_B_info = config["nodeNq11"] + node_A_info, node_B_info = config["nodeNq14"], config["nodeNq15"] print("------ Test Case (FAIL) : Transferring 0.00000009 RBT from B which is more than allowed decimal places ------") @@ -13,8 +13,7 @@ def max_decimal_place_transfer(config): print("\n------ Test Case (FAIL) : Transferring 0.00000009 RBT from B which is more than allowed decimal places completed ------\n") def insufficient_balance_transfer(config): - node_A_info = config["nodeNq10"] - node_B_info = config["nodeNq11"] + node_A_info, node_B_info = config["nodeNq14"], config["nodeNq15"] print("\n------ Test Case (FAIL) : Transferring 100 RBT from A which has zero balance ------") @@ -32,8 +31,7 @@ def insufficient_balance_transfer(config): print("\n------ Test Case (FAIL) : Transferring 100 RBT from B which has insufficient balance completed ------\n") def shuttle_transfer(config): - node_A_info = config["nodeNq10"] - node_B_info = config["nodeNq11"] + node_A_info, node_B_info = config["nodeNq14"], config["nodeNq15"] print("------ Test Case (PASS): Shuttle transfer started ------\n") diff --git a/tests/scenarios/util.py b/tests/scenarios/util.py new file mode 100644 index 00000000..a851d784 --- /dev/null +++ b/tests/scenarios/util.py @@ -0,0 +1,9 @@ +def get_non_quorum_node_configs(config: dict): + sender_config = {} + receiver_config = {} + + for node in config: + sender_config = config[node] + receiver_config = config[node] + + return sender_config, receiver_config \ No newline at end of file diff --git a/tests/shutdown.py b/tests/shutdown.py index 5e9d2399..fc78cd92 100644 --- a/tests/shutdown.py +++ b/tests/shutdown.py @@ -2,14 +2,15 @@ from node.actions import get_base_ports quorum_base_server, quorum_grpc_server = get_base_ports() +offset = 4 -for i in range(0, 5): +for i in range(offset, 5 + offset): server_port = quorum_base_server + i grpc_port = quorum_grpc_server + i cmd_shutdown_node(server_port, grpc_port) -for i in range(0, 2): +for i in range(offset, 2 + offset): server_port = quorum_base_server + 10 + i grpc_port = quorum_grpc_server + 10 + i From d1cd6ffc2bb33b9d1f3f9447779f10492e8ca03f Mon Sep 17 00:00:00 2001 From: Maneesha-rubix Date: Mon, 13 May 2024 16:59:02 +0530 Subject: [PATCH 45/62] tested port-unavailability-fix on MacOs --- core/ipfsport/peer.go | 3 --- 1 file changed, 3 deletions(-) diff --git a/core/ipfsport/peer.go b/core/ipfsport/peer.go index b5837baa..cee13a43 100644 --- a/core/ipfsport/peer.go +++ b/core/ipfsport/peer.go @@ -70,11 +70,8 @@ func (pm *PeerManager) getPeerPort() uint16 { availability := isPortAvailable(port) if availability { - fmt.Println("available port: ", port, availability) pm.ps[i] = true return pm.startPort + uint16(i) - } else { - fmt.Println("NOT available port: ", port, availability) } } } From 56b19fda5525886c99a35e471c9311b9ec92b121 Mon Sep 17 00:00:00 2001 From: Arnab Ghose Date: Wed, 15 May 2024 09:30:55 +0530 Subject: [PATCH 46/62] added dockerfile for running tests in ubuntu-amd64 environment --- tests/README.md | 14 ++++++++++++++ tests/docker/ubuntu_test.Dockerfile | 18 ++++++++++++++++++ 2 files changed, 32 insertions(+) create mode 100644 tests/docker/ubuntu_test.Dockerfile diff --git a/tests/README.md b/tests/README.md index 2d6f8ff0..e3506621 100644 --- a/tests/README.md +++ b/tests/README.md @@ -35,6 +35,20 @@ To start the test. Please NOTE that it must be run from the `tests` directory on python3 run.py ``` +## Running tests in Docker + +To run the tests in a Docker Ubuntu environment, run the following: + +1. Build the image +``` +docker build -t rubix_test_image_ubuntu --no-cache -f tests/docker/ubuntu_test.Dockerfile . +``` + +2. Run the container +``` +docker run --rm --name rubix_test_container_ubuntu rubix_test_image_ubuntu +``` + ### Flags The test script is equipped with CLI Parser. Following are the flags and their description diff --git a/tests/docker/ubuntu_test.Dockerfile b/tests/docker/ubuntu_test.Dockerfile new file mode 100644 index 00000000..8ba1dd2c --- /dev/null +++ b/tests/docker/ubuntu_test.Dockerfile @@ -0,0 +1,18 @@ +FROM amd64/ubuntu + +# Install python3 and requests dependency +RUN apt-get update && apt-get install -y python3 python3-requests wget build-essential tmux + +# Install golang 1.21 +RUN wget https://go.dev/dl/go1.21.10.linux-amd64.tar.gz +RUN tar -C /usr/local -xzf go1.21.10.linux-amd64.tar.gz +ENV PATH="/usr/local/go/bin:${PATH}" + +# Copy the tests directory +COPY . /usr/node/ + +# Change directory to test +WORKDIR /usr/node/tests + +# Run tests +CMD ["python3", "-u", "run.py"] From dca12e533ade5d93d23f95b761e0ae176e2271e5 Mon Sep 17 00:00:00 2001 From: Arnab Ghose Date: Wed, 15 May 2024 09:45:48 +0530 Subject: [PATCH 47/62] added script to collect all quorum and non-quorum logs; added step in test workflow to upload the node logs as artifacts in Github Action sessions --- .github/workflows/tests.yml | 37 ++++++++++++++++++++++++++++++++++++- tests/pack_node_logs.py | 33 +++++++++++++++++++++++++++++++++ 2 files changed, 69 insertions(+), 1 deletion(-) create mode 100644 tests/pack_node_logs.py diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 0f9dc3de..cfc33d46 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -33,6 +33,18 @@ jobs: - name: Run tests run: | cd tests && ls && python3 -u run.py + + - name: Packing Quorum and Non-Quorum node logs + if: always() + run: | + cd tests && python3 -u pack_node_logs.py + + - name: Uploading Quorum and Non-Quorum node logs as Artifacts + if: always() + uses: actions/upload-artifact@v4 + with: + name: artifact-log + path: tests/node_logs test-macos: name: "Test - MacOS Environment" @@ -64,6 +76,18 @@ jobs: run: | cd tests && ls && python3 -u run.py + - name: Packing Quorum and Non-Quorum node logs + if: always() + run: | + cd tests && python3 -u pack_node_logs.py + + - name: Uploading Quorum and Non-Quorum node logs as Artifacts + if: always() + uses: actions/upload-artifact@v4 + with: + name: artifact-log + path: tests/node_logs + test-windows: name: "Test - Windows Environment" runs-on: windows-latest @@ -90,4 +114,15 @@ jobs: - name: Run tests run: | cd tests && ls && python3 -u run.py - + + - name: Packing Quorum and Non-Quorum node logs + if: always() + run: | + cd tests && python3 -u pack_node_logs.py + + - name: Uploading Quorum and Non-Quorum node logs as Artifacts + if: always() + uses: actions/upload-artifact@v4 + with: + name: artifact-log + path: tests/node_logs diff --git a/tests/pack_node_logs.py b/tests/pack_node_logs.py new file mode 100644 index 00000000..afe56433 --- /dev/null +++ b/tests/pack_node_logs.py @@ -0,0 +1,33 @@ +# This script packs all the quorum and non-quorum node logs in `tests/node_logs` + +import os +import shutil + +def collect_logs(base_dir, output_dir): + # Ensure the output directory exists + os.makedirs(output_dir, exist_ok=True) + + # Iterate over files and directories in the build directory + for env in ['linux', 'windows', 'mac']: + env_path = os.path.join(base_dir, env) + if os.path.isdir(env_path): + for item in os.listdir(env_path): + item_path = os.path.join(env_path, item) + # Check if the directory name starts with `node`. + if os.path.isdir(item_path) and item.startswith('node'): + log_file_path = os.path.join(item_path, 'log.txt') + if os.path.exists(log_file_path): + # Rename the log file in `log__.txt` + new_log_name = f'log_{env}_{item}.txt' + new_log_path = os.path.join(output_dir, new_log_name) + # Copy the log file to the output directory + shutil.copyfile(log_file_path, new_log_path) + print(f'Copied {new_log_name} to {output_dir}') + else: + print(f'log.txt not found in {item_path}') + +if __name__ == "__main__": + base_directory = '..' # Parent directory of 'tests' where build directory is located + output_directory = './node_logs' # Directory to store collected logs + collect_logs(base_directory, output_directory) + print(f'All logs collected into {output_directory}') \ No newline at end of file From 0ffbfc78942bda7383d0a6d3101535bf04aa6dff Mon Sep 17 00:00:00 2001 From: Arnab Ghose Date: Wed, 15 May 2024 09:46:51 +0530 Subject: [PATCH 48/62] reduced node liveness wait time from 60 seconds to 15 seconds --- tests/node/commands.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/node/commands.py b/tests/node/commands.py index 4d674cc5..d654a0c4 100644 --- a/tests/node/commands.py +++ b/tests/node/commands.py @@ -60,8 +60,8 @@ def cmd_run_rubix_servers(node_name, server_port_idx, grpc_port): if code != 0: raise Exception("Error occurred while run the command: " + cmd_string) - print("Waiting for 60 seconds before checking if its running....") - time.sleep(60) + print("Waiting for 15 seconds before checking if its running....") + time.sleep(15) try: check_if_all_nodes_are_running(server_port_idx) except Exception as e: From 30bafad6c2b22dc12b0c4d345b98f68aeff7aa98 Mon Sep 17 00:00:00 2001 From: Arnab Ghose Date: Wed, 15 May 2024 09:55:50 +0530 Subject: [PATCH 49/62] increased node liveness wait time to 40 seconds --- tests/node/commands.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/node/commands.py b/tests/node/commands.py index d654a0c4..ac633951 100644 --- a/tests/node/commands.py +++ b/tests/node/commands.py @@ -60,8 +60,8 @@ def cmd_run_rubix_servers(node_name, server_port_idx, grpc_port): if code != 0: raise Exception("Error occurred while run the command: " + cmd_string) - print("Waiting for 15 seconds before checking if its running....") - time.sleep(15) + print("Waiting for 40 seconds before checking if its running....") + time.sleep(40) try: check_if_all_nodes_are_running(server_port_idx) except Exception as e: From 204d34074e6b1aa691ee3a042e820ef9d644455e Mon Sep 17 00:00:00 2001 From: Arnab Ghose Date: Wed, 15 May 2024 09:57:00 +0530 Subject: [PATCH 50/62] added OS alias in artifact name --- .github/workflows/tests.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index cfc33d46..3148c845 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -43,7 +43,7 @@ jobs: if: always() uses: actions/upload-artifact@v4 with: - name: artifact-log + name: artifact-log-linux path: tests/node_logs test-macos: @@ -85,7 +85,7 @@ jobs: if: always() uses: actions/upload-artifact@v4 with: - name: artifact-log + name: artifact-log-mac path: tests/node_logs test-windows: @@ -124,5 +124,5 @@ jobs: if: always() uses: actions/upload-artifact@v4 with: - name: artifact-log + name: artifact-log-windows path: tests/node_logs From 596e0d5e293b4739f8e3a2e3374276623a4462b7 Mon Sep 17 00:00:00 2001 From: Arnab Ghose Date: Wed, 15 May 2024 10:37:10 +0530 Subject: [PATCH 51/62] changed test swarm key --- tests/fixtures/testswarm.key | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/fixtures/testswarm.key b/tests/fixtures/testswarm.key index 6f0cf118..f9c579b7 100644 --- a/tests/fixtures/testswarm.key +++ b/tests/fixtures/testswarm.key @@ -1,3 +1,3 @@ /key/swarm/psk/1.0.0/ /base16/ -278b9a199c43fa84178920bd9f5cbcd69e933ddf02a8f69e47a3ea5a1705512f \ No newline at end of file +9e56c3b3d62d9f3b2a9c4a9344b8e5d02c92a2c9b5f8a2b3a4e5b8c4f6a7c5e1 \ No newline at end of file From d43d21f92339f20690c20404868141a6414fefb7 Mon Sep 17 00:00:00 2001 From: Arnab Ghose Date: Wed, 15 May 2024 15:05:07 +0530 Subject: [PATCH 52/62] non quorums DIDs are now being registered for the RBT transfer transaction to happen successfully --- tests/fixtures/testswarm.key | 2 +- tests/node/actions.py | 4 ++-- tests/node/commands.py | 11 ++++++----- tests/node/quorum.py | 2 +- 4 files changed, 10 insertions(+), 9 deletions(-) diff --git a/tests/fixtures/testswarm.key b/tests/fixtures/testswarm.key index f9c579b7..6f0cf118 100644 --- a/tests/fixtures/testswarm.key +++ b/tests/fixtures/testswarm.key @@ -1,3 +1,3 @@ /key/swarm/psk/1.0.0/ /base16/ -9e56c3b3d62d9f3b2a9c4a9344b8e5d02c92a2c9b5f8a2b3a4e5b8c4f6a7c5e1 \ No newline at end of file +278b9a199c43fa84178920bd9f5cbcd69e933ddf02a8f69e47a3ea5a1705512f \ No newline at end of file diff --git a/tests/node/actions.py b/tests/node/actions.py index 450be822..a7dcdbf4 100644 --- a/tests/node/actions.py +++ b/tests/node/actions.py @@ -84,9 +84,9 @@ def fetch_peer_ids(node_config: dict): print("Fetched all Node IDs") -def create_and_register_did(node_config: dict, register_did: bool = True): +def create_and_register_did(node_config: dict, register_did: bool = True, did_type: int = 4): for config in node_config.values(): - did_id = cmd_create_did(config["server"], config["grpcPort"]) + did_id = cmd_create_did(config["server"], config["grpcPort"], did_type) print("Created DID : ", did_id) if register_did: diff --git a/tests/node/commands.py b/tests/node/commands.py index ac633951..82cb1c57 100644 --- a/tests/node/commands.py +++ b/tests/node/commands.py @@ -84,14 +84,15 @@ def check_if_all_nodes_are_running(server_idx): except: raise Exception(f"ConnectionError | Server with port {port} is NOT running successfully") -def cmd_create_did(server_port, grpc_port): +def cmd_create_did(server_port, grpc_port, did_type = 4): os.chdir("../" + get_build_dir()) - cmd_string = f"./rubixgoplatform createdid -port {server_port} -grpcPort {grpc_port}" + cmd_string = f"./rubixgoplatform createdid -port {server_port} -grpcPort {grpc_port} -didType {did_type}" if is_windows_os(): - cmd_string = f".\\rubixgoplatform createdid -port {server_port} -grpcPort {grpc_port}" + cmd_string = f".\\rubixgoplatform createdid -port {server_port} -grpcPort {grpc_port} -didType {did_type}" output, code = run_command(cmd_string, True) - + print(output) + if code != 0: raise Exception("Error occurred while run the command: " + cmd_string) @@ -112,7 +113,7 @@ def cmd_register_did(did_id, server_port, grpc_port): cmd_string = f"./rubixgoplatform registerdid -did {did_id} -port {server_port} -grpcPort {grpc_port}" if is_windows_os(): cmd_string = f".\\rubixgoplatform registerdid -did {did_id} -port {server_port} -grpcPort {grpc_port}" - output, code = run_command(cmd_string) + output, code = run_command(cmd_string, True) print(output) if code != 0: diff --git a/tests/node/quorum.py b/tests/node/quorum.py index 62701bf4..8f3e82aa 100644 --- a/tests/node/quorum.py +++ b/tests/node/quorum.py @@ -46,7 +46,7 @@ def run_non_quorum_nodes(node_config_path, only_run_nodes, skip_adding_quorums): fetch_peer_ids(node_config) print("Creation of Non Quorum DIDs have started") - create_and_register_did(node_config, False) + create_and_register_did(node_config, True) print("Non Quorum DIDs have been created") save_to_json(node_config_path, node_config) From 316ea9a0a8a0a4f2704cfc8a687f14a7a3fd22da Mon Sep 17 00:00:00 2001 From: Arnab Ghose Date: Thu, 16 May 2024 17:00:42 +0530 Subject: [PATCH 53/62] added node_registry.json config to list all the node server indeces; run_non_quorum_nodes is removed --- .gitignore | 5 +- tests/config/__init__.py | 0 tests/config/node_registry.json | 4 + tests/config/utils.py | 39 +++++++++ tests/helper/utils.py | 4 +- tests/node/actions.py | 138 ++++++++++++++++---------------- tests/node/commands.py | 16 ++-- tests/node/quorum.py | 74 ++++++----------- tests/node/utils.py | 15 ++-- tests/run.py | 33 ++++---- tests/scenarios/rbt_transfer.py | 93 ++++++++++++++++----- tests/scenarios/util.py | 9 --- tests/shutdown.py | 29 +++---- 13 files changed, 261 insertions(+), 198 deletions(-) create mode 100644 tests/config/__init__.py create mode 100644 tests/config/node_registry.json create mode 100644 tests/config/utils.py delete mode 100644 tests/scenarios/util.py diff --git a/.gitignore b/.gitignore index f4bbfef5..1105ae9e 100644 --- a/.gitignore +++ b/.gitignore @@ -25,4 +25,7 @@ __pycache__ ipfs linux/ mac/ -windows/ \ No newline at end of file +windows/ + +# used for testing purpose +!node_registry.json \ No newline at end of file diff --git a/tests/config/__init__.py b/tests/config/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/tests/config/node_registry.json b/tests/config/node_registry.json new file mode 100644 index 00000000..de13ce6b --- /dev/null +++ b/tests/config/node_registry.json @@ -0,0 +1,4 @@ +{ + "quorum": [4, 5, 6, 7, 8], + "rbt_transfer": [9, 10] +} \ No newline at end of file diff --git a/tests/config/utils.py b/tests/config/utils.py new file mode 100644 index 00000000..af10b5cb --- /dev/null +++ b/tests/config/utils.py @@ -0,0 +1,39 @@ +import json +import os + +def get_node_registry(): + current_dir = os.path.dirname(os.path.abspath(__file__)) + node_registry_path = os.path.join(current_dir, "node_registry.json") + config = load_from_config_file(node_registry_path) + + if config == {}: + raise Exception("node registry config is empty") + return config + +def load_from_config_file(config_file_path): + try: + with open(config_file_path, 'r') as file: + config_data = json.load(file) + return config_data + except FileNotFoundError as e: + return {} + except json.JSONDecodeError as e: + raise ValueError(f"Error: The file at {config_file_path} is not a valid JSON file.") from e + except Exception as e: + raise Exception(f"An unexpected error occurred: {e}") from e + +def save_to_config_file(config_file_path, config): + try: + if os.path.exists(config_file_path): + os.remove(config_file_path) + + with open(config_file_path, 'w') as f: + json.dump(config, f, indent=4) + except FileNotFoundError as e: + raise FileNotFoundError(f"Error: The file at {config_file_path} could not be found.") from e + except PermissionError as e: + raise PermissionError(f"Error: Permission denied when trying to write to {config_file_path}.") from e + except TypeError as e: # JSON serialization errors raise TypeError, not JSONDecodeError + raise TypeError(f"Error: Failed to serialize the config data to JSON.") from e + except Exception as e: + raise Exception(f"An unexpected error occurred: {e}") from e diff --git a/tests/helper/utils.py b/tests/helper/utils.py index 68d8649f..d0732faa 100644 --- a/tests/helper/utils.py +++ b/tests/helper/utils.py @@ -3,14 +3,14 @@ def wrapper(*args, **kwargs): try: func(*args, **kwargs) except: - raise Exception("The action was expected to pass, but it failed") + raise Exception("The transaction/action was expected to pass, but it failed") return wrapper def expect_failure(func): def wrapper(*args, **kwargs): try: func(*args, **kwargs) - raise Exception("The action was expected to fail, but it passed") + raise Exception("The transaction/action was expected to fail, but it passed") except: return 0 return wrapper \ No newline at end of file diff --git a/tests/node/actions.py b/tests/node/actions.py index a7dcdbf4..72dcad05 100644 --- a/tests/node/actions.py +++ b/tests/node/actions.py @@ -1,6 +1,7 @@ from .commands import cmd_run_rubix_servers, cmd_get_peer_id, cmd_create_did, cmd_register_did, \ cmd_generate_rbt, cmd_add_quorum_dids, cmd_setup_quorum_dids, cmd_rbt_transfer, get_build_dir -from .utils import get_node_name_from_idx, save_to_json +from .utils import get_node_name_from_idx, get_did_by_alias +from config.utils import save_to_config_file, get_node_registry def add_quorums(node_config: dict): for config in node_config.values(): @@ -9,106 +10,101 @@ def add_quorums(node_config: dict): config["grpcPort"] ) -def setup_quorums(node_config: dict): - for config in node_config.values(): +def setup_quorums(node_config: dict, node_did_alias_map: dict): + for node, config in node_config.items(): + did = get_did_by_alias(config, node_did_alias_map[node]) cmd_setup_quorum_dids( - config["did"], + did, config["server"], config["grpcPort"] ) -def quorum_config(node_config: dict, skip_adding_quorums: bool = False, create_quorum_list: bool = False): +def quorum_config(node_config: dict, node_did_alias_map: dict, skip_adding_quorums: bool = False): # Prepare quorumlist.json quorum_list = [] - if create_quorum_list: - for config in node_config.values(): + build_dir = get_build_dir() + quorum_list_file_path = f"../{build_dir}/quorumlist.json" + + if skip_adding_quorums: + setup_quorums(node_config, node_did_alias_map) + else: + for node, config in node_config.items(): + did = get_did_by_alias(config, node_did_alias_map[node]) + print("got the didby alias: ", did) quorum_info = { "type": 2, - "address": config["peerId"] + "." + config["did"] + "address": config["peerId"] + "." + did } - build_dir = get_build_dir() - quorum_list_file_path = f"../{build_dir}/quorumlist.json" quorum_list.append(quorum_info) - save_to_json(quorum_list_file_path, quorum_list) + save_to_config_file(quorum_list_file_path, quorum_list) - # # add quorums - if not skip_adding_quorums: add_quorums(node_config) - setup_quorums(node_config) + setup_quorums(node_config, node_did_alias_map) -def get_base_ports(): - base_ens_server = 20000 - base_grpc_port = 10500 +def setup_rubix_nodes(node_registry_config_key): + if node_registry_config_key == "": + raise Exception("a key is needed to fetch node_registry.json config") + + node_registry = get_node_registry() + if not node_registry_config_key in node_registry: + raise Exception(f"config key {node_registry_config_key} not found in node_registry.json config") - return base_ens_server, base_grpc_port + node_indices = node_registry[node_registry_config_key] + + if not isinstance(node_indices, list): + raise Exception(f"the correspoding value for {node_registry_config_key} in node_registry.json must of List type") + + if len(node_indices) == 0: + raise Exception(f"no indices found for {node_registry_config_key} in node_registry.json, provide at least one index") -def setup_rubix_nodes(node_count: int = 0, node_prefix_str: str = "node"): - base_ens_server, base_grpc_port = get_base_ports() - node_config = {} - # Start rubix servers - loop_start_idx, loop_end_idx = 0, node_count - offset = 4 - - for i in range(loop_start_idx, loop_end_idx): - k = (i + offset) if node_prefix_str == "node" else (10 + i + offset) - - ens_server = base_ens_server + k - print(f"Running server at port: {ens_server}") - grpc_port = base_grpc_port + k - - node_name = get_node_name_from_idx(k, node_prefix_str) - - cmd_run_rubix_servers(node_name, k, grpc_port) - - node_config[node_name] = { - "did": "", - "server": ens_server, - "grpcPort": grpc_port, + for idx in node_indices: + node_name = "node" + str(idx) + node_server, grpc_server = cmd_run_rubix_servers(node_name, idx) + + cfg = { + "dids": {}, + "server": node_server, + "grpcPort": grpc_server, "peerId": "" } - return node_config - + fetch_peer_id(cfg) + node_config[node_name] = cfg -def fetch_peer_ids(node_config: dict): - print("Fetching Node IDs........") - for config in node_config.values(): - peer_id = cmd_get_peer_id(config["server"], config["grpcPort"]) - config["peerId"] = peer_id - print("Fetched all Node IDs") + return node_config +def fetch_peer_id(config): + peer_id = cmd_get_peer_id(config["server"], config["grpcPort"]) + config["peerId"] = peer_id -def create_and_register_did(node_config: dict, register_did: bool = True, did_type: int = 4): - for config in node_config.values(): - did_id = cmd_create_did(config["server"], config["grpcPort"], did_type) - print("Created DID : ", did_id) - - if register_did: - print(f"Registering DID: {did_id}") - cmd_register_did(did_id, config["server"], config["grpcPort"]) - print("DID is registered successfully\n") +def create_and_register_did(config: dict, did_alias: str, did_type: int = 4, register_did: bool = True): + did = cmd_create_did(config["server"], config["grpcPort"], did_type) + print(f"DID {did} has been created successfully") - config["did"] = did_id + config["dids"] = { + did_alias: did + } -def fund_dids_with_rbt(node_config: dict, rbt_amount: int = 30): - for node, config in node_config.items(): - if node not in ["node5", "node6", "node7", "node8"]: - cmd_generate_rbt(config["did"], rbt_amount, config["server"], config["grpcPort"]) - print("DID ", config["did"], f" is funded with {rbt_amount} RBT") + if register_did: + cmd_register_did(did, config["server"], config["grpcPort"]) + print(f"DID {did} has been registered successfully") -def fund_did_with_rbt(config: dict, rbt_amount: int = 30): - output = cmd_generate_rbt(config["did"], rbt_amount, config["server"], config["grpcPort"]) - print(output) - return output + return did -def rbt_transfer(config_sender: dict, config_receiver: dict, transfer_rbt_amount: int): - sender_address = config_sender["peerId"] + "." + config_sender["did"] - receiver_address = config_receiver["peerId"] + "." + config_receiver["did"] +def fund_did_with_rbt(node_config: dict, did: str, rbt_amount: int = 70): + cmd_generate_rbt(did, rbt_amount, node_config["server"], node_config["grpcPort"]) + print("DID ", did, f" is funded with {rbt_amount} RBT") - cmd_rbt_transfer(sender_address, receiver_address, transfer_rbt_amount, config_sender["server"], config_sender["grpcPort"]) \ No newline at end of file +def rbt_transfer( + sender_address: str, + receiver_address: str, + transfer_rbt: float, + sender_server_port: int, + sender_grpc_port: int): + cmd_rbt_transfer(sender_address, receiver_address, transfer_rbt, sender_server_port, sender_grpc_port) diff --git a/tests/node/commands.py b/tests/node/commands.py index 82cb1c57..999f316c 100644 --- a/tests/node/commands.py +++ b/tests/node/commands.py @@ -4,6 +4,7 @@ import platform import time import requests +from .utils import get_base_ports def is_windows_os(): os_name = platform.system() @@ -47,9 +48,13 @@ def run_command(cmd_string, is_output_from_stderr=False): else: return output, code -def cmd_run_rubix_servers(node_name, server_port_idx, grpc_port): +def cmd_run_rubix_servers(node_name, server_port_idx): os.chdir("../" + get_build_dir()) + base_node_server, base_grpc_port = get_base_ports() + grpc_port = base_grpc_port + server_port_idx + node_server = base_node_server + server_port_idx + cmd_string = "" if is_windows_os(): cmd_string = f"powershell -Command Start-Process -FilePath '.\\rubixgoplatform.exe' -ArgumentList 'run -p {node_name} -n {server_port_idx} -s -testNet -grpcPort {grpc_port}' -WindowStyle Hidden" @@ -63,14 +68,15 @@ def cmd_run_rubix_servers(node_name, server_port_idx, grpc_port): print("Waiting for 40 seconds before checking if its running....") time.sleep(40) try: - check_if_all_nodes_are_running(server_port_idx) + check_if_nodes_is_running(server_port_idx) except Exception as e: raise e + os.chdir("../tests") + return node_server, grpc_port -def check_if_all_nodes_are_running(server_idx): - - base_server = 20000 +def check_if_nodes_is_running(server_idx): + base_server, _ = get_base_ports() port = base_server + int(server_idx) print(f"Check if server with ENS web server port {port} is running...") url = f"http://localhost:{port}/api/getalldid" diff --git a/tests/node/quorum.py b/tests/node/quorum.py index 8f3e82aa..cb65ccbd 100644 --- a/tests/node/quorum.py +++ b/tests/node/quorum.py @@ -1,62 +1,40 @@ import pprint import time -from .actions import setup_rubix_nodes, fetch_peer_ids, create_and_register_did, \ - fund_dids_with_rbt, quorum_config -from .utils import save_to_json +from .actions import setup_rubix_nodes, create_and_register_did, \ + fund_did_with_rbt, quorum_config +from config.utils import save_to_config_file, load_from_config_file -def run_quorum_nodes(node_config_path, only_run_nodes, skip_adding_quorums): - node_config_path = "./quorum_config.json" - - print("Running Rubix nodes......") - node_config = setup_rubix_nodes(5) - print("Rubix nodes are now running") +QUORUM_CONFIG_PATH = "./quorum_config.json" - if not only_run_nodes: - fetch_peer_ids(node_config) - - print("Creation and registeration of quorum DIDs have started") - create_and_register_did(node_config) - print("All quorum DIDs have been registered") - - print("Initiating funding of these quorum DIDs") - fund_dids_with_rbt(node_config) - print("All Quorum DIDs have been funded") - - save_to_json(node_config_path, node_config) - - print("Setting up quorums and saving information about them to quorumlist.json") - quorum_config(node_config, skip_adding_quorums=skip_adding_quorums, create_quorum_list=True) - - pprint.pp(node_config) - print("Quorums have been configured") - else: - quorum_config(node_config, skip_adding_quorums=True, create_quorum_list=False) +def run_quorum_nodes(only_run_nodes, skip_adding_quorums): + print("Running Rubix Quorum nodes......") + node_registry_key = "quorum" + node_config = setup_rubix_nodes(node_registry_key) + print("Rubix Quorum nodes are now running") - return node_config + if not only_run_nodes: + did_alias = "did_quorum" + node_did_alias_map = {} -def run_non_quorum_nodes(node_config_path, only_run_nodes, skip_adding_quorums): - node_config_path = "./non_quorum_config.json" + print("Creating, Registering and Funding Quorum DIDs\n") + for node, config in node_config.items(): + did = create_and_register_did(config, did_alias) - print("Running non-quorum nodes...") - node_config = setup_rubix_nodes(2, "nodeNq") - print("Non-quorum nodes are running successfully") + fund_did_with_rbt(config, did) - if not only_run_nodes: - fetch_peer_ids(node_config) + # Selecting DIDs for quorum setup + node_did_alias_map[node] = did_alias + save_to_config_file(QUORUM_CONFIG_PATH, node_config) + print("\nquorum_config.json is created") - print("Creation of Non Quorum DIDs have started") - create_and_register_did(node_config, True) - print("Non Quorum DIDs have been created") - - save_to_json(node_config_path, node_config) - - print("Adding and setting up quorum config") - quorum_config(node_config, skip_adding_quorums=skip_adding_quorums, create_quorum_list=False) + print("Setting up quorums and saving the info in quorumlist.json") + quorum_config(node_config, node_did_alias_map, skip_adding_quorums=skip_adding_quorums) pprint.pp(node_config) - print("Non Quorum nodes have been configured") + print("Quorums have been configured") else: - quorum_config(node_config, skip_adding_quorums=True, create_quorum_list=False) + quorum_config(node_config, node_did_alias_map, skip_adding_quorums=True) - return node_config \ No newline at end of file +def get_quorum_config(): + return load_from_config_file(QUORUM_CONFIG_PATH) diff --git a/tests/node/utils.py b/tests/node/utils.py index a30cfa47..668c1d10 100644 --- a/tests/node/utils.py +++ b/tests/node/utils.py @@ -7,10 +7,11 @@ def get_node_name_from_idx(idx, prefix_string: str = "node"): return prefix_string + str(idx) -def save_to_json(filepath, obj): - # Check if file exists. If yes, then remove it - if os.path.exists(filepath): - os.remove(filepath) - - with open(filepath, 'w') as f: - json.dump(obj, f, indent=4) +def get_base_ports(): + base_ens_server = 20000 + base_grpc_port = 10500 + + return base_ens_server, base_grpc_port + +def get_did_by_alias(node_config, alias): + return node_config["dids"][alias] \ No newline at end of file diff --git a/tests/run.py b/tests/run.py index 6dbaf35a..af5c115d 100644 --- a/tests/run.py +++ b/tests/run.py @@ -4,12 +4,13 @@ import requests import argparse from node.commands import run_command -from node.quorum import run_quorum_nodes, run_non_quorum_nodes -from scenarios.rbt_transfer import * +from node.quorum import run_quorum_nodes + +from scenarios import ( + rbt_transfer +) IPFS_KUBO_VERSION = "v0.21.0" -QUORUM_CONFIG_FILE = "./quorum_config.json" -NON_QUORUM_CONFIG_FILE = "./non_quorum_config.json" def get_os_info(): os_name = platform.system() @@ -120,10 +121,7 @@ def cli(): parser.add_argument("--run_tests_only", action=argparse.BooleanOptionalAction, help="only proceed with running tests") return parser.parse_args() - if __name__=='__main__': - os.chdir("../") - args = cli() skip_prerequisite = args.skip_prerequisite run_nodes_only = args.run_nodes_only @@ -138,6 +136,7 @@ def cli(): exit(1) if not skip_prerequisite: + os.chdir("../") print(f"Building Rubix binary for {os_name}\n") build_command = "" if os_name == "Linux": @@ -154,21 +153,17 @@ def cli(): else: print("\nBuild successful\n") - download_ipfs_binary(os_name, IPFS_KUBO_VERSION, build_folder) copy_fixtures_to_build_dir(build_folder) os.chdir("./tests") - run_quorum_nodes(QUORUM_CONFIG_FILE, run_nodes_only, skip_adding_quorums=skip_adding_quorums) + run_quorum_nodes(run_nodes_only, skip_adding_quorums=skip_adding_quorums) - non_quorum_node_config = run_non_quorum_nodes(NON_QUORUM_CONFIG_FILE, run_nodes_only, skip_adding_quorums=skip_adding_quorums) - - # Run RBT Transfer related tests - rbt_transfer_test_list = [ - shuttle_transfer, - insufficient_balance_transfer, - max_decimal_place_transfer + # It will carry list of Python files containing the function `run()` + # that consists of logic to run all the necessary tests + modules = [ + rbt_transfer ] - for testFn in rbt_transfer_test_list: - testFn(non_quorum_node_config) - + + for module in modules: + module.run() diff --git a/tests/scenarios/rbt_transfer.py b/tests/scenarios/rbt_transfer.py index 315960fd..7f5c2da0 100644 --- a/tests/scenarios/rbt_transfer.py +++ b/tests/scenarios/rbt_transfer.py @@ -1,82 +1,135 @@ -from node.actions import rbt_transfer, fund_did_with_rbt +from node.actions import rbt_transfer, fund_did_with_rbt, setup_rubix_nodes, \ + create_and_register_did, add_quorums +from node.utils import get_did_by_alias +from config.utils import save_to_config_file, load_from_config_file from helper.utils import expect_failure, expect_success -from .util import get_non_quorum_node_configs + +__node_config_path = "./rbt_transfer_config.json" + +def setup(): + print("Setting up test.....") + print("Configuring and running node9 and node10...") + + node_config = setup_rubix_nodes("rbt_transfer") + + config_A = node_config["node9"] + config_B = node_config["node10"] + + create_and_register_did(config_A, "did_a") + create_and_register_did(config_B, "did_b") + + save_to_config_file(__node_config_path, node_config) + + print("Adding quorums") + add_quorums(node_config) + + print("Setup Done\n") + return node_config + +def run(skip_setup: bool = False): + print("\n----------- 1. Running Tests related to RBT Transfer -----------\n") + node_config = {} + + # In some cases, we may wish to run tests for an existing test configuration + # where the nodes are running already. If skip_setup is True, the setup steps + # are skipped and we proceed to directly run the test cases and load the config + # from the config file + if not skip_setup: + node_config = setup() + else: + node_config = load_from_config_file(__node_config_path) + + shuttle_transfer(node_config) + insufficient_balance_transfer(node_config) + max_decimal_place_transfer(node_config) + + print("\n-------------- Tests Completed -------------------\n") def max_decimal_place_transfer(config): - node_A_info, node_B_info = config["nodeNq14"], config["nodeNq15"] + node_A_info, node_B_info = config["node9"], config["node10"] + server_port_B, grpc_port_B = node_B_info["server"], node_B_info["grpcPort"] + did_A, did_B = get_did_by_alias(node_A_info, "did_a"), get_did_by_alias(node_B_info, "did_b") + address_A, address_B = node_A_info["peerId"]+"."+did_A, node_B_info["peerId"]+"."+did_B print("------ Test Case (FAIL) : Transferring 0.00000009 RBT from B which is more than allowed decimal places ------") print("\nTransferring 0.00000009 RBT from B to A....") - expect_failure(rbt_transfer)(node_B_info, node_A_info, 0.00000009) + expect_failure(rbt_transfer)(address_B, address_A, 0.00000009, server_port_B, grpc_port_B) print("\n------ Test Case (FAIL) : Transferring 0.00000009 RBT from B which is more than allowed decimal places completed ------\n") def insufficient_balance_transfer(config): - node_A_info, node_B_info = config["nodeNq14"], config["nodeNq15"] + node_A_info, node_B_info = config["node9"], config["node10"] + server_port_A, grpc_port_A = node_A_info["server"], node_A_info["grpcPort"] + server_port_B, grpc_port_B = node_B_info["server"], node_B_info["grpcPort"] + did_A, did_B = get_did_by_alias(node_A_info, "did_a"), get_did_by_alias(node_B_info, "did_b") + address_A, address_B = node_A_info["peerId"]+"."+did_A, node_B_info["peerId"]+"."+did_B print("\n------ Test Case (FAIL) : Transferring 100 RBT from A which has zero balance ------") print("\nTransferring 100 RBT from A to B....") - expect_failure(rbt_transfer)(node_A_info, node_B_info, 100) + expect_failure(rbt_transfer)(address_A, address_B, 100, server_port_A, grpc_port_A) print("\n------ Test Case (FAIL) : Transferring 100 RBT from A which has zero balance completed ------\n") - print("\n------ Test Case (FAIL) : Transferring 100 RBT from B which has insufficient balance ------") print("\nTransferring 100 RBT from B to A....") - expect_failure(rbt_transfer)(node_B_info, node_A_info, 100) + expect_failure(rbt_transfer)(address_B, address_A, 0.25, server_port_B, grpc_port_B) print("\n------ Test Case (FAIL) : Transferring 100 RBT from B which has insufficient balance completed ------\n") def shuttle_transfer(config): - node_A_info, node_B_info = config["nodeNq14"], config["nodeNq15"] + node_A_info, node_B_info = config["node9"], config["node10"] + server_port_A, grpc_port_A = node_A_info["server"], node_A_info["grpcPort"] + server_port_B, grpc_port_B = node_B_info["server"], node_B_info["grpcPort"] + did_A, did_B = get_did_by_alias(node_A_info, "did_a"), get_did_by_alias(node_B_info, "did_b") + address_A, address_B = node_A_info["peerId"]+"."+did_A, node_B_info["peerId"]+"."+did_B print("------ Test Case (PASS): Shuttle transfer started ------\n") print("\n1. Generating 2 whole RBT for A") - expect_success(fund_did_with_rbt)(node_A_info, 2) + expect_success(fund_did_with_rbt)(node_A_info, did_A, 2) print("Funded node A with 2 RBT") print("\n2. Transferring 0.5 RBT from A to B....") - expect_success(rbt_transfer)(node_A_info, node_B_info, 0.5) + expect_success(rbt_transfer)(address_A, address_B, 0.5, server_port_A, grpc_port_A) print("Transferred 0.5 RBT from A to B") print("\n3. Transferring 1.499 RBT from A to B....") - expect_success(rbt_transfer)(node_A_info, node_B_info, 1.499) + expect_success(rbt_transfer)(address_A, address_B, 1.499, server_port_A, grpc_port_A) print("Transferred 1.499 RBT from A to B") print("\n4. Transferring 0.25 RBT from B to A....") - expect_success(rbt_transfer)(node_B_info, node_A_info, 0.25) + expect_success(rbt_transfer)(address_B, address_A, 0.25, server_port_B, grpc_port_B) print("Transferred 0.25 RBT from B to A") print("\n5. Transferring 0.25 RBT from B to A....") - expect_success(rbt_transfer)(node_B_info, node_A_info, 0.25) + expect_success(rbt_transfer)(address_B, address_A, 0.25, server_port_B, grpc_port_B) print("Transferred 0.25 RBT from B to A") print("\n6. Transferring 0.25 RBT from B to A....") - expect_success(rbt_transfer)(node_B_info, node_A_info, 0.25) + expect_success(rbt_transfer)(address_B, address_A, 0.25, server_port_B, grpc_port_B) print("Transferred 0.25 RBT from B to A") print("\n7. Transferring 0.25 RBT from B to A....") - expect_success(rbt_transfer)(node_B_info, node_A_info, 0.25) + expect_success(rbt_transfer)(address_B, address_A, 0.25, server_port_B, grpc_port_B) print("Transferred 0.25 RBT from B to A") print("\n8. Transferring 1 RBT from A to B....") - expect_success(rbt_transfer)(node_A_info, node_B_info, 1) + expect_success(rbt_transfer)(address_A, address_B, 1, server_port_A, grpc_port_A) print("Transferred 1 RBT from A to B") print("\n9. Generating 2 whole RBT for A") - expect_success(fund_did_with_rbt)(node_A_info, 2) + expect_success(fund_did_with_rbt)(node_A_info, did_A, 2) print("Funded node A with 2 RBT") print("\n10. Transferring 2 RBT from A to B....") - expect_success(rbt_transfer)(node_A_info, node_B_info, 2) + expect_success(rbt_transfer)(address_A, address_B, 2, server_port_A, grpc_port_A) print("Transferred 2 RBT from A to B") print("\n11. Transferring 0.001 RBT from A to B....") - expect_success(rbt_transfer)(node_A_info, node_B_info, 0.001) + expect_success(rbt_transfer)(address_A, address_B, 0.001, server_port_A, grpc_port_A) print("Transferred 0.001 RBT from A to B") print("\n------ Test Case (PASS): Shuttle transfer completed ------\n") diff --git a/tests/scenarios/util.py b/tests/scenarios/util.py deleted file mode 100644 index a851d784..00000000 --- a/tests/scenarios/util.py +++ /dev/null @@ -1,9 +0,0 @@ -def get_non_quorum_node_configs(config: dict): - sender_config = {} - receiver_config = {} - - for node in config: - sender_config = config[node] - receiver_config = config[node] - - return sender_config, receiver_config \ No newline at end of file diff --git a/tests/shutdown.py b/tests/shutdown.py index fc78cd92..8d96c103 100644 --- a/tests/shutdown.py +++ b/tests/shutdown.py @@ -1,17 +1,14 @@ from node.commands import cmd_shutdown_node -from node.actions import get_base_ports - -quorum_base_server, quorum_grpc_server = get_base_ports() -offset = 4 - -for i in range(offset, 5 + offset): - server_port = quorum_base_server + i - grpc_port = quorum_grpc_server + i - - cmd_shutdown_node(server_port, grpc_port) - -for i in range(offset, 2 + offset): - server_port = quorum_base_server + 10 + i - grpc_port = quorum_grpc_server + 10 + i - - cmd_shutdown_node(server_port, grpc_port) +from node.utils import get_base_ports +from config.utils import get_node_registry + +if __name__=='__main__': + base_node_server, base_grpc_server = get_base_ports() + node_registry_config = get_node_registry() + + for indices in node_registry_config.values(): + for i in indices: + server_port = base_node_server + i + grpc_port = base_grpc_server + i + print(f"Shutting down server running at {server_port}") + cmd_shutdown_node(server_port, grpc_port) From 261d5b52ef8ba17b5cba84032bb3739a53e1cc0f Mon Sep 17 00:00:00 2001 From: Arnab Ghose Date: Thu, 16 May 2024 17:11:29 +0530 Subject: [PATCH 54/62] renamed test workflow artifiacts name --- .github/workflows/tests.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 3148c845..cc2a882f 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -43,7 +43,7 @@ jobs: if: always() uses: actions/upload-artifact@v4 with: - name: artifact-log-linux + name: node-logs-linux path: tests/node_logs test-macos: @@ -85,7 +85,7 @@ jobs: if: always() uses: actions/upload-artifact@v4 with: - name: artifact-log-mac + name: node-logs-macos path: tests/node_logs test-windows: @@ -124,5 +124,5 @@ jobs: if: always() uses: actions/upload-artifact@v4 with: - name: artifact-log-windows + name: node-logs-windows path: tests/node_logs From 8c4818fa28e5f13fc3c92d2a1837552ebe735b3e Mon Sep 17 00:00:00 2001 From: Arnab Ghose Date: Fri, 17 May 2024 09:56:07 +0530 Subject: [PATCH 55/62] added test scenario for BIP39 and NLSS transfers --- tests/README.md | 10 ++++ tests/config/node_registry.json | 3 +- tests/run.py | 6 +- tests/scenarios/bip39_nlss_test.py | 89 ++++++++++++++++++++++++++++++ 4 files changed, 105 insertions(+), 3 deletions(-) create mode 100644 tests/scenarios/bip39_nlss_test.py diff --git a/tests/README.md b/tests/README.md index e3506621..c963fb15 100644 --- a/tests/README.md +++ b/tests/README.md @@ -20,6 +20,16 @@ The test script covers the following RBT Transfer scenarios: 3. Transferring 0.00000009 RBT from B which is more than allowed decimal places (Failure Case) +4. Transferring whole, part and mix RBT from NLSS DID to BIP39 DID
+ 4.1 Transfer 1 RBT from NLSS DID to BIP39 DID
+ 4.2 Transfer 1.5 RBT from NLSS DID to BIP39 DID
+ 4.3 Transfer 0.5 RBT from NLSS DID to BIP39 DID
+ +5. Transferring whole, part and mix RBT from BIP39 DID to NLSS DID
+ 5.1 Transfer 0.5 RBT from NLSS DID to BIP39 DID
+ 5.2 Transfer 1.5 RBT from NLSS DID to BIP39 DID
+ 5.3 Transfer 1 RBT from NLSS DID to BIP39 DID
+ ## Prerequisites - Python 3.10+ ([Install Ref](https://www.python.org/downloads/)) diff --git a/tests/config/node_registry.json b/tests/config/node_registry.json index de13ce6b..08c4e27b 100644 --- a/tests/config/node_registry.json +++ b/tests/config/node_registry.json @@ -1,4 +1,5 @@ { "quorum": [4, 5, 6, 7, 8], - "rbt_transfer": [9, 10] + "rbt_transfer": [9, 10], + "bip39_nlss": [11, 12] } \ No newline at end of file diff --git a/tests/run.py b/tests/run.py index af5c115d..f0d78c0e 100644 --- a/tests/run.py +++ b/tests/run.py @@ -7,7 +7,8 @@ from node.quorum import run_quorum_nodes from scenarios import ( - rbt_transfer + rbt_transfer, + bip39_nlss_test ) IPFS_KUBO_VERSION = "v0.21.0" @@ -162,7 +163,8 @@ def cli(): # It will carry list of Python files containing the function `run()` # that consists of logic to run all the necessary tests modules = [ - rbt_transfer + rbt_transfer, + bip39_nlss_test ] for module in modules: diff --git a/tests/scenarios/bip39_nlss_test.py b/tests/scenarios/bip39_nlss_test.py new file mode 100644 index 00000000..74aa300c --- /dev/null +++ b/tests/scenarios/bip39_nlss_test.py @@ -0,0 +1,89 @@ +from node.actions import rbt_transfer, fund_did_with_rbt, setup_rubix_nodes, \ + create_and_register_did, add_quorums +from node.utils import get_did_by_alias +from config.utils import save_to_config_file, load_from_config_file +from helper.utils import expect_failure, expect_success + +__node_config_path = "./bip39_nlss_config.json" + +def setup(): + print("Setting up test.....") + print("Configuring and running node11 and node12...") + + node_config = setup_rubix_nodes("bip39_nlss") + + config_bip39 = node_config["node11"] + config_nlss = node_config["node12"] + + create_and_register_did(config_bip39, "bip39_1", did_type=4) + + + create_and_register_did(config_nlss, "nlss_1", did_type=0) + + save_to_config_file(__node_config_path, node_config) + + print("Adding quorums") + add_quorums(node_config) + + print("Setup Done\n") + return node_config + +def run(skip_setup: bool = False): + print("\n----------- 2. Running Tests related to RBT Transfer between BIP39 and NLSS dids -----------\n") + node_config = {} + + if not skip_setup: + node_config = setup() + else: + node_config = load_from_config_file(__node_config_path) + + nlss_to_bip39(node_config) + bip39_to_nlss(node_config) + print("\n-------------- Tests Completed -------------------\n") + +def nlss_to_bip39(node_config): + node_bip39, node_nlss = node_config["node11"], node_config["node12"] + server_port_nlss, grpc_port_nlss = node_nlss["server"], node_nlss["grpcPort"] + did_bip39, did_nlss = get_did_by_alias(node_bip39, "bip39_1"), get_did_by_alias(node_nlss, "nlss_1") + address_bip39, address_nlss = node_bip39["peerId"]+"."+did_bip39, node_nlss["peerId"]+"."+did_nlss + + print("------ Test Case (PASS): Transferring whole, part and mix RBT from NLSS DID to BIP39 DID ------\n") + + print("\n1. Generating 3 RBT for NLSS DID") + expect_success(fund_did_with_rbt)(node_nlss, did_nlss, 3) + print("Funded NLSS DID with 3 RBT") + + print("\n2. Transferring 1 RBT from NLSS DID to BIP39 DID....") + expect_success(rbt_transfer)(address_nlss, address_bip39, 1, server_port_nlss, grpc_port_nlss) + print("Transferred 1 RBT from NLSS DID to BIP39 DID") + + print("\n3. Transferring 1.5 RBT from NLSS DID to BIP39 DID....") + expect_success(rbt_transfer)(address_nlss, address_bip39, 1.5, server_port_nlss, grpc_port_nlss) + print("Transferred 1.5 RBT from NLSS DID to BIP39 DID") + + print("\n4. Transferring 0.5 RBT from NLSS DID to BIP39 DID....") + expect_success(rbt_transfer)(address_nlss, address_bip39, 0.5, server_port_nlss, grpc_port_nlss) + print("Transferred 0.5 RBT from NLSS DID to BIP39 DID") + + print("\n------ Test Case (PASS): Transferring whole, part and mix RBT from NLSS DID to BIP39 DID completed ------\n") + +def bip39_to_nlss(node_config): + node_bip39, node_nlss = node_config["node11"], node_config["node12"] + server_port_bip39, grpc_port_bip39 = node_bip39["server"], node_bip39["grpcPort"] + did_bip39, did_nlss = get_did_by_alias(node_bip39, "bip39_1"), get_did_by_alias(node_nlss, "nlss_1") + address_bip39, address_nlss = node_bip39["peerId"]+"."+did_bip39, node_nlss["peerId"]+"."+did_nlss + + print("------ Test Case (PASS): Transferring whole, part and mix RBT from BIP39 DID to NLSS DID ------\n") + + print("\n4. Transferring 0.5 RBT from BIP39 DID to NLSS DID....") + expect_success(rbt_transfer)(address_bip39, address_nlss, 0.5, server_port_bip39, grpc_port_bip39) + print("Transferred 0.5 RBT from BIP39 DID to NLSS DID") + + print("\n3. Transferring 1.5 RBT from BIP39 DID to NLSS DID....") + expect_success(rbt_transfer)(address_bip39, address_nlss, 1.5, server_port_bip39, grpc_port_bip39) + print("Transferred 1.5 RBT from BIP39 DID to NLSS DID") + + print("\n2. Transferring 1 RBT from BIP39 DID to NLSS DID....") + expect_success(rbt_transfer)(address_bip39, address_nlss, 1, server_port_bip39, grpc_port_bip39) + print("Transferred 1 RBT from BIP39 DID to NLSS DID") + From 0f567830132720f1fac469870f6d895112ca237c Mon Sep 17 00:00:00 2001 From: Arnab Ghose Date: Fri, 17 May 2024 11:41:03 +0530 Subject: [PATCH 56/62] added entry for .sh file extension --- .gitignore | 1 + tests/README.md | 42 +++++++++++++++++++++--------------------- 2 files changed, 22 insertions(+), 21 deletions(-) diff --git a/.gitignore b/.gitignore index 1105ae9e..e4faed3f 100644 --- a/.gitignore +++ b/.gitignore @@ -12,6 +12,7 @@ api_config.json # Output of the go coverage tool, specifically when used with LiteIDE *.out *.txt +*.sh *.png *.json *.pdf diff --git a/tests/README.md b/tests/README.md index c963fb15..bff954d1 100644 --- a/tests/README.md +++ b/tests/README.md @@ -4,31 +4,31 @@ The test script does the complete setup by building the rubix node based on the The test script covers the following RBT Transfer scenarios: -1. Shuttle Transfer (Success Case)
- 1.1 Generate 2 whole RBT for A
- 1.2 Transfer 0.5 from A to B
- 1.3 Transfer 1.499 from A to B
- 1.4 (Transfer 0.25 from B to A) * 4
- 1.5 Transfer 1 RBT from A to B
- 1.6 Generate 2 whole RBT for A
- 1.7 Transfer 2 RBT from A to B
- 1.8 Transfer 0.001 from A to B
- -2. Insufficient Balance Transfer (Failure Case)
- 2.1 Transferring 100 RBT from A which has zero balance
- 2.2 Transferring 100 RBT from B which has insufficient balance
+1. Shuttle Transfer (Success Case) + 1.1 Generate 2 whole RBT for A + 1.2 Transfer 0.5 from A to B + 1.3 Transfer 1.499 from A to B + 1.4 (Transfer 0.25 from B to A) * 4 + 1.5 Transfer 1 RBT from A to B + 1.6 Generate 2 whole RBT for A + 1.7 Transfer 2 RBT from A to B + 1.8 Transfer 0.001 from A to B + +2. Insufficient Balance Transfer (Failure Case) + 2.1 Transferring 100 RBT from A which has zero balance + 2.2 Transferring 100 RBT from B which has insufficient balance 3. Transferring 0.00000009 RBT from B which is more than allowed decimal places (Failure Case) -4. Transferring whole, part and mix RBT from NLSS DID to BIP39 DID
- 4.1 Transfer 1 RBT from NLSS DID to BIP39 DID
- 4.2 Transfer 1.5 RBT from NLSS DID to BIP39 DID
- 4.3 Transfer 0.5 RBT from NLSS DID to BIP39 DID
+4. Transferring whole, part and mix RBT from NLSS DID to BIP39 DID + 4.1 Transfer 1 RBT from NLSS DID to BIP39 DID + 4.2 Transfer 1.5 RBT from NLSS DID to BIP39 DID + 4.3 Transfer 0.5 RBT from NLSS DID to BIP39 DID -5. Transferring whole, part and mix RBT from BIP39 DID to NLSS DID
- 5.1 Transfer 0.5 RBT from NLSS DID to BIP39 DID
- 5.2 Transfer 1.5 RBT from NLSS DID to BIP39 DID
- 5.3 Transfer 1 RBT from NLSS DID to BIP39 DID
+5. Transferring whole, part and mix RBT from BIP39 DID to NLSS DID + 5.1 Transfer 0.5 RBT from NLSS DID to BIP39 DID + 5.2 Transfer 1.5 RBT from NLSS DID to BIP39 DID + 5.3 Transfer 1 RBT from NLSS DID to BIP39 DID ## Prerequisites From 5353f212727129339516410aaf15c21db89b671c Mon Sep 17 00:00:00 2001 From: Arnab Ghose Date: Mon, 20 May 2024 12:10:49 +0530 Subject: [PATCH 57/62] created three swarm keys for each os environment --- tests/fixtures/testswarm.key | 3 --- tests/fixtures/testswarm_linux.key | 3 +++ tests/fixtures/testswarm_mac.key | 3 +++ tests/fixtures/testswarm_windows.key | 3 +++ tests/run.py | 6 +++--- 5 files changed, 12 insertions(+), 6 deletions(-) delete mode 100644 tests/fixtures/testswarm.key create mode 100644 tests/fixtures/testswarm_linux.key create mode 100644 tests/fixtures/testswarm_mac.key create mode 100644 tests/fixtures/testswarm_windows.key diff --git a/tests/fixtures/testswarm.key b/tests/fixtures/testswarm.key deleted file mode 100644 index 6f0cf118..00000000 --- a/tests/fixtures/testswarm.key +++ /dev/null @@ -1,3 +0,0 @@ -/key/swarm/psk/1.0.0/ -/base16/ -278b9a199c43fa84178920bd9f5cbcd69e933ddf02a8f69e47a3ea5a1705512f \ No newline at end of file diff --git a/tests/fixtures/testswarm_linux.key b/tests/fixtures/testswarm_linux.key new file mode 100644 index 00000000..534e7acb --- /dev/null +++ b/tests/fixtures/testswarm_linux.key @@ -0,0 +1,3 @@ +/key/swarm/psk/1.0.0/ +/base16/ +278b9a199c43fa84178920bd9f5cbcd69e933ddf02a8f69e47a3ea5a1705513f \ No newline at end of file diff --git a/tests/fixtures/testswarm_mac.key b/tests/fixtures/testswarm_mac.key new file mode 100644 index 00000000..7490ebe9 --- /dev/null +++ b/tests/fixtures/testswarm_mac.key @@ -0,0 +1,3 @@ +/key/swarm/psk/1.0.0/ +/base16/ +e105d6caa191dc76ff553d36d094fafb2ad1c646000a52ebc89b488e17f61f92 \ No newline at end of file diff --git a/tests/fixtures/testswarm_windows.key b/tests/fixtures/testswarm_windows.key new file mode 100644 index 00000000..7490ebe9 --- /dev/null +++ b/tests/fixtures/testswarm_windows.key @@ -0,0 +1,3 @@ +/key/swarm/psk/1.0.0/ +/base16/ +e105d6caa191dc76ff553d36d094fafb2ad1c646000a52ebc89b488e17f61f92 \ No newline at end of file diff --git a/tests/run.py b/tests/run.py index f0d78c0e..67f3705f 100644 --- a/tests/run.py +++ b/tests/run.py @@ -105,12 +105,12 @@ def copy_fixtures_to_build_dir(build_directory): raise FileNotFoundError(f"Copy operation for didimage.png.file failed. Destination file not found: {image_file_dest}") # Copy testswarm.key - swarmkey_src = os.path.join(fixtures_directory, "testswarm.key") - swarmkey_dest = os.path.join(build_directory, "testswarm.key") + swarmkey_src = os.path.join(fixtures_directory, f"testswarm_{build_directory}.key") + swarmkey_dest = os.path.join(build_directory, f"testswarm.key") shutil.copyfile(swarmkey_src, swarmkey_dest) if not os.path.exists(swarmkey_dest): - raise FileNotFoundError(f"Copy operation for testswarm.key failed. Destination file not found: {swarmkey_dest}") + raise FileNotFoundError(f"Copy operation for testswarm_{build_directory}.key failed. Destination file not found: {swarmkey_dest}") print("\nimage.png and swarm key have been added to build directory successfully") From 71b5e4c3db7049980c1f7d1b694dbd67860bb09e Mon Sep 17 00:00:00 2001 From: Arnab Ghose Date: Mon, 20 May 2024 13:27:00 +0530 Subject: [PATCH 58/62] added timestamp for node log artifacts --- .github/workflows/tests.yml | 27 +++++++++++++++++++++------ 1 file changed, 21 insertions(+), 6 deletions(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index cc2a882f..1eacb7ad 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -38,12 +38,16 @@ jobs: if: always() run: | cd tests && python3 -u pack_node_logs.py - + + - name: Set Timestamp for Node Logs + if: always() + run: echo "TIMESTAMP=$(date -u +'%Y-%m-%dT%H-%M-%SZ' | sed 's/:/-/g')" >> $GITHUB_ENV + - name: Uploading Quorum and Non-Quorum node logs as Artifacts if: always() uses: actions/upload-artifact@v4 with: - name: node-logs-linux + name: node-logs-linux-${{ env.TIMESTAMP }} path: tests/node_logs test-macos: @@ -80,12 +84,16 @@ jobs: if: always() run: | cd tests && python3 -u pack_node_logs.py - + + - name: Set Timestamp for Node Logs + if: always() + run: echo "TIMESTAMP=$(date -u +'%Y-%m-%dT%H-%M-%SZ' | sed 's/:/-/g')" >> $GITHUB_ENV + - name: Uploading Quorum and Non-Quorum node logs as Artifacts if: always() uses: actions/upload-artifact@v4 with: - name: node-logs-macos + name: node-logs-macos-${{ env.TIMESTAMP }} path: tests/node_logs test-windows: @@ -119,10 +127,17 @@ jobs: if: always() run: | cd tests && python3 -u pack_node_logs.py - + + - name: Set Timestamp for Node Logs + if: always() + shell: pwsh + run: | + $timestamp = Get-Date -Format "yyyy-MM-ddTHH-mm-ssZ" + echo "TIMESTAMP=$timestamp" >> $env:GITHUB_ENV + - name: Uploading Quorum and Non-Quorum node logs as Artifacts if: always() uses: actions/upload-artifact@v4 with: - name: node-logs-windows + name: node-logs-windows-${{ env.TIMESTAMP }} path: tests/node_logs From 973d5c8184ce1bc4f08810738e465c50bdde19b6 Mon Sep 17 00:00:00 2001 From: Arnab Ghose Date: Mon, 20 May 2024 13:27:27 +0530 Subject: [PATCH 59/62] removed unneeded print statement --- tests/node/actions.py | 1 - 1 file changed, 1 deletion(-) diff --git a/tests/node/actions.py b/tests/node/actions.py index 72dcad05..629e253d 100644 --- a/tests/node/actions.py +++ b/tests/node/actions.py @@ -30,7 +30,6 @@ def quorum_config(node_config: dict, node_did_alias_map: dict, skip_adding_quoru else: for node, config in node_config.items(): did = get_did_by_alias(config, node_did_alias_map[node]) - print("got the didby alias: ", did) quorum_info = { "type": 2, "address": config["peerId"] + "." + did From 746b3f2c68ecf16779298424f55241e626d2affc Mon Sep 17 00:00:00 2001 From: Arnab Ghose Date: Thu, 23 May 2024 14:11:57 +0530 Subject: [PATCH 60/62] bump rubixgoplatform version to 0.0.17 --- command/command.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/command/command.go b/command/command.go index 2e292827..e2d9e850 100644 --- a/command/command.go +++ b/command/command.go @@ -33,7 +33,7 @@ const ( ) const ( - version string = "0.0.16" + version string = "0.0.17" ) const ( VersionCmd string = "-v" From dba88e56ebfd4243d9ddde3d564a33bb03be01f6 Mon Sep 17 00:00:00 2001 From: Arnab Ghose Date: Thu, 23 May 2024 15:01:43 +0530 Subject: [PATCH 61/62] [skip actions] Added `dist/` in `.gitignore` --- .gitignore | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index e4faed3f..d3b2bd43 100644 --- a/.gitignore +++ b/.gitignore @@ -27,6 +27,7 @@ ipfs linux/ mac/ windows/ +dist/ # used for testing purpose -!node_registry.json \ No newline at end of file +!node_registry.json From c5f424cda00e1280702949b2ea77900635d1b4c8 Mon Sep 17 00:00:00 2001 From: Arnab Ghose Date: Thu, 23 May 2024 15:13:36 +0530 Subject: [PATCH 62/62] [skip actions] update --- .gitignore | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index d3b2bd43..9f8b4b91 100644 --- a/.gitignore +++ b/.gitignore @@ -30,4 +30,4 @@ windows/ dist/ # used for testing purpose -!node_registry.json +!node_registry.json \ No newline at end of file