Skip to content

Commit

Permalink
fixed transfer of rbt between DIDs when either is present on a Quorum…
Browse files Browse the repository at this point in the history
… node
  • Loading branch information
arnabghose997 committed Aug 12, 2024
1 parent 369c383 commit f15c8f0
Show file tree
Hide file tree
Showing 5 changed files with 207 additions and 32 deletions.
45 changes: 34 additions & 11 deletions core/ping.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"net/http"
"strconv"
"time"
"strings"

"github.com/rubixchain/rubixgoplatform/core/ipfsport"
"github.com/rubixchain/rubixgoplatform/core/model"
Expand Down Expand Up @@ -99,7 +100,10 @@ func (c *Core) CheckQuorumStatusResponse(req *ensweb.Request) *ensweb.Result { /
func (c *Core) CheckQuorumStatus(peerID string, did string) (string, bool, error) { //
q := make(map[string]string)
if peerID == "" {
peerID = c.qm.GetPeerID(did)
peerID = c.qm.GetPeerID(did, c.peerID)
}
if peerID == "" {
return "Quorum Connection Error", false, fmt.Errorf("unable to find Quorum DID info and peer for %v", did)
}
p, err := c.pm.OpenPeerConn(peerID, "", c.getCoreAppName(peerID))
if err != nil {
Expand Down Expand Up @@ -202,20 +206,39 @@ func (c *Core) GetPeerInfoResponse(req *ensweb.Request) *ensweb.Result { //PingR

pInfo.PeerID = c.w.GetPeerID(peerDID)
if pInfo.PeerID == "" {
c.log.Error("sender does not have prev pledged quorum in DIDPeerTable", peerDID)
resp.Message = "Couldn't fetch peer id for did: " + peerDID
resp.Status = false
return c.l.RenderJSON(req, &resp, http.StatusOK)
_, err := c.w.GetDID(peerDID)
if err != nil {
c.log.Error("sender does not have prev pledged quorum in DIDPeerTable", peerDID)
resp.Message = "Couldn't fetch peer id for did: " + peerDID
resp.Status = false
return c.l.RenderJSON(req, &resp, http.StatusOK)
} else {
pInfo.PeerID = c.peerID
}
}

qDidType, err := c.w.GetPeerDIDType(peerDID)
if err != nil || qDidType == -1 {
c.log.Error("could not fetch did type for quorum:", peerDID, "error", err)
pInfo.DIDType = nil
resp.PeerInfo = pInfo
resp.Status = true
resp.Message = "could not fetch did type, only sharing peerId"
return c.l.RenderJSON(req, &resp, http.StatusOK)
if strings.Contains(err.Error(), "no records found") {
didInfo, err := c.w.GetDID(peerDID)
if err != nil {
c.log.Error("unable to find DID in DIDTable, could not fetch did type for quorum:", peerDID, "error", err)
pInfo.DIDType = nil
resp.PeerInfo = pInfo
resp.Status = true
resp.Message = "could not fetch did type, only sharing peerId"
return c.l.RenderJSON(req, &resp, http.StatusOK)
} else {
pInfo.DIDType = &didInfo.Type
}
} else {
c.log.Error("could not fetch did type for quorum:", peerDID, "error", err)
pInfo.DIDType = nil
resp.PeerInfo = pInfo
resp.Status = true
resp.Message = "could not fetch did type, only sharing peerId"
return c.l.RenderJSON(req, &resp, http.StatusOK)
}
} else {
pInfo.DIDType = &qDidType
}
Expand Down
20 changes: 14 additions & 6 deletions core/quorum.go
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ func NewQuorumManager(s storage.Storage, log logger.Logger) (*QuorumManager, err
}

// GetQuorum will get the configured or available quorum
func (qm *QuorumManager) GetQuorum(t int, lastChar string) []string {
func (qm *QuorumManager) GetQuorum(t int, lastChar string, selfPeer string) []string {
//QuorumTypeOne is to select quorums from the public pool of quorums instead of a private subnet.
//Once a new node is created, it will create a DID. Using the command "registerdid", the peerID and DID will be
//published in the network, and all the nodes listening to the subscription will have the DID added on the DIDPeerTable
Expand Down Expand Up @@ -130,7 +130,7 @@ func (qm *QuorumManager) GetQuorum(t int, lastChar string) []string {
var quorumAddrList []string
quorumAddrCount := 0
for _, q := range qm.ql {
peerID := qm.GetPeerID(q)
peerID := qm.GetPeerID(q, selfPeer)
addr := string(peerID + "." + q)
quorumAddrList = append(quorumAddrList, addr)
quorumAddrCount = quorumAddrCount + 1
Expand Down Expand Up @@ -165,11 +165,19 @@ func (qm *QuorumManager) RemoveAllQuorum(t int) error {
return err
}

func (qm *QuorumManager) GetPeerID(did string) string {
func (qm *QuorumManager) GetPeerID(did string, selfPeer string) string {
var dm QuorumDIDPeerMap
err := qm.s.Read(wallet.DIDPeerStorage, &dm, "did=?", did)
if err != nil {
return ""
if err != nil && strings.Contains(err.Error(), "no records found") {
// Check if the Quorum DID is part of the same node by looking in DIDTable
var dt wallet.DIDType
err2 := qm.s.Read(wallet.DIDStorage, &dt, "did=?", did)
if err2 != nil {
return ""
} else {
return selfPeer
}
} else {
return dm.PeerID
}
return dm.PeerID
}
25 changes: 21 additions & 4 deletions core/quorum_initiator.go
Original file line number Diff line number Diff line change
Expand Up @@ -252,7 +252,7 @@ func (c *Core) SetupQuorum(didStr string, pwd string, pvtKeyPwd string) error {
}

func (c *Core) GetAllQuorum() []string {
return c.qm.GetQuorum(QuorumTypeTwo, "")
return c.qm.GetQuorum(QuorumTypeTwo, "", c.peerID)
}

func (c *Core) AddQuorum(ql []QuorumData) error {
Expand Down Expand Up @@ -347,7 +347,7 @@ func (c *Core) initiateConsensus(cr *ConensusRequest, sc *contract.Contract, dc
lastCharTID := string(tid[len(tid)-1])
cr.TransactionID = tid

ql := c.qm.GetQuorum(cr.Type, lastCharTID) //passing lastCharTID as a parameter. Made changes in GetQuorum function to take 2 arguments
ql := c.qm.GetQuorum(cr.Type, lastCharTID, c.peerID) //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")
return nil, nil, fmt.Errorf("failed to get required quorums")
Expand Down Expand Up @@ -474,12 +474,30 @@ func (c *Core) initiateConsensus(cr *ConensusRequest, sc *contract.Contract, dc
if qpid == "" {
qpid = c.w.GetPeerID(qdid)
}
// Initiatitor is part of Quorum Node
if qpid == "" {
_, err := c.w.GetDID(qdid)
if err != nil {
return nil, nil, fmt.Errorf("unable to fetch peerID for quorum DID: %v which fetching quorum information", qdid)
} else {
qpid = c.peerID
}
}

var qrmInfo QuorumDIDPeerMap
//fetch did type of the quorum
qDidType, err := c.w.GetPeerDIDType(qdid)
if err != nil {
c.log.Error("could not fetch did type for quorum:", qdid, "error", err)
if strings.Contains(err.Error(), "no records found") {
didInfo, err := c.w.GetDID(qdid)
if err != nil {
return nil, nil, err
} else {
qDidType = didInfo.Type
}
} else {
c.log.Error(fmt.Sprintf("could not fetch did type for quorum: %v while gathering quorum information, err: %v", qdid, err))
}
}
if qDidType == -1 {
c.log.Info("did type is empty for quorum:", qdid, "connecting & fetching from quorum")
Expand Down Expand Up @@ -1268,7 +1286,6 @@ func (c *Core) finishConsensus(id string, qt int, p *ipfsport.Peer, status bool,
}

func (c *Core) connectQuorum(cr *ConensusRequest, addr string, qt int, sc *contract.Contract) {
defer c.w.ReleaseAllLockedTokens()
c.startConsensus(cr.ReqID, qt)
var p *ipfsport.Peer
var err error
Expand Down
26 changes: 20 additions & 6 deletions core/quorum_recv.go
Original file line number Diff line number Diff line change
Expand Up @@ -906,12 +906,26 @@ func (c *Core) updatePledgeToken(req *ensweb.Request) *ensweb.Result {

ctcb := make(map[string]*block.Block)
tsb := make([]block.TransTokens, 0)
for _, t := range tks {
err = c.w.AddTokenBlock(t, b)
if err != nil {
c.log.Error("Failed to add token block", "token", t)
crep.Message = "Failed to add token block"
return c.l.RenderJSON(req, &crep, http.StatusOK)
// Generally, addition of a token block happens on Sender, Receiver
// and Quorum's end.
//
// If both sender and receiver happen to be on a Non-Quorum server, this is
// not an issue since we skip TokensTable and Token chain update, if the reciever
// and sender peer as seem. Thus, multiple update of same block to the Token's tokenchain
// is avoided
//
// However in case both sender and receiver happen to be a Quorum server, even though the above
// scenario is covered, but since the token block is also added on Quorum's end, we end up in a
// situation where update of same block happens twice. Hence the following check ensures that we
// skip the addition of block here, if sender and receiver happen to be on a Quoeum node.
if !c.w.IsDIDExist(b.GetReceiverDID()) && !c.w.IsDIDExist(b.GetSenderDID()) {
for _, t := range tks {
err = c.w.AddTokenBlock(t, b)
if err != nil {
c.log.Error("Failed to add token block", "token", t)
crep.Message = "Failed to add token block"
return c.l.RenderJSON(req, &crep, http.StatusOK)
}
}
}
for _, t := range ur.PledgedTokens {
Expand Down
123 changes: 118 additions & 5 deletions tests/scenarios/rbt_transfer.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,27 @@ def setup():

config_A = node_config["node9"]
config_B = node_config["node10"]

config_quorum = get_quorum_config()
config_quorum_node4 = config_quorum["node4"]
config_quorum_node5 = config_quorum["node5"]

create_and_register_did(config_A, "did_a", register_did=False)

# Sender and Receiver on same Non-Quorum server Scenario
create_and_register_did(config_A, "did_a1", register_did=False)
create_and_register_did(config_A, "did_a2", register_did=False)

# Sender and Receiver on same Quorum server Scenario
create_and_register_did(config_quorum_node4, "did_quorum_a1_node4", register_did=False)
create_and_register_did(config_quorum_node4, "did_quorum_a2_node4", register_did=False)
create_and_register_did(config_quorum_node5, "did_quorum_a1_node5", register_did=False)
create_and_register_did(config_A, "did_nonquorum_a1_node9", register_did=False)

create_and_register_did(config_B, "did_b", register_did=False)

save_to_config_file(__node_config_path, node_config)
save_to_config_file("./quorum_config.json", config_quorum)

run_quorum_nodes(False, False, "quorum2", "./quorum_config2.json", "quorumlist2.json")

Expand Down Expand Up @@ -49,31 +63,130 @@ def run(skip_setup: bool = False):

shuttle_transfer(node_config)
did_on_same_server_transfer(node_config)
did_on_same_quorum_server_transfer(node_config)
insufficient_balance_transfer(node_config)
max_decimal_place_transfer(node_config)

print("\n-------------- Tests Completed -------------------\n")

def did_on_same_server_transfer(config):
node_A_info = config["node9"]

server_port_A, grpc_port_A = node_A_info["server"], node_A_info["grpcPort"]
did_A1, did_A2 = get_did_by_alias(node_A_info, "did_a1"), get_did_by_alias(node_A_info, "did_a2")

print("------ Test Case (PASS): Transfer between DID's on same server ------\n")

print("\n1. Generating 2 whole RBT for A")
print("\n1. Generating 2 whole RBT for A1")
expect_success(fund_did_with_rbt)(node_A_info, did_A1, 2)
print("Funded node A with 2 RBT")

print("\n2. Transferring 1 RBT from A to B (both present on same node)....")
print("\n2. Transferring 0.5 RBT from A1 to A2....")
expect_success(rbt_transfer)(did_A1, did_A2, 0.5, server_port_A, grpc_port_A)
print("Transfer Complete")

print("\n3. Transferring 1.499 RBT from A1 to A2....")
expect_success(rbt_transfer)(did_A1, did_A2, 1.499, server_port_A, grpc_port_A)
print("Transfer Complete")

print("\n4. Transferring 0.25 RBT from A2 to A1....")
expect_success(rbt_transfer)(did_A2, did_A1, 0.25, server_port_A, grpc_port_A)
print("Transfer Complete")

print("\n5. Transferring 0.25 RBT from A2 to A1....")
expect_success(rbt_transfer)(did_A2, did_A1, 0.25, server_port_A, grpc_port_A)
print("Transfer Complete")

print("\n6. Transferring 0.25 RBT from A2 to A1....")
expect_success(rbt_transfer)(did_A2, did_A1, 0.25, server_port_A, grpc_port_A)
print("Transfer Complete")

print("\n7. Transferring 0.25 RBT from A2 to A1....")
expect_success(rbt_transfer)(did_A2, did_A1, 0.25, server_port_A, grpc_port_A)
print("Transfer Complete")

print("\n8. Transferring 1 RBT from A1 to A2....")
expect_success(rbt_transfer)(did_A1, did_A2, 1, server_port_A, grpc_port_A)
print("Transfer Complete")

print("\n9. Generating 2 whole RBT for A1")
expect_success(fund_did_with_rbt)(node_A_info, did_A1, 2)
print("Transfer Complete")

print("\n10. Transferring 2 RBT from A1 to A2....")
expect_success(rbt_transfer)(did_A1, did_A2, 2, server_port_A, grpc_port_A)
print("Transfer Complete")

print("\n11. Transferring 0.001 RBT from A1 to A2....")
expect_success(rbt_transfer)(did_A1, did_A2, 0.001, server_port_A, grpc_port_A)
print("Transfer Complete")

print("\n------ Test Case (PASS): Transfer between DID's on same server completed ------\n")

def did_on_same_quorum_server_transfer(config):
quorum_config = get_quorum_config()

node_4_info = quorum_config["node4"]
node_5_info = quorum_config["node5"]
node_9_info = config["node9"]

server_port_4, grpc_port_4 = node_4_info["server"], node_4_info["grpcPort"]
did_4_A, did_4_B = get_did_by_alias(node_4_info, "did_quorum_a1_node4"), get_did_by_alias(node_4_info, "did_quorum_a2_node4")

server_port_5, grpc_port_5 = node_5_info["server"], node_5_info["grpcPort"]
did_5_A = get_did_by_alias(node_5_info, "did_quorum_a1_node5")

server_port_9, grpc_port_9 = node_9_info["server"], node_9_info["grpcPort"]
did_9_A = get_did_by_alias(node_9_info, "did_nonquorum_a1_node9")

for _, val in quorum_config.items():
add_peer_details(val["peerId"], val["dids"]["did_quorum"], 4, server_port_4, grpc_port_4)
add_peer_details(val["peerId"], val["dids"]["did_quorum"], 4, server_port_5, grpc_port_5)
add_peer_details(val["peerId"], val["dids"]["did_quorum"], 4, server_port_9, grpc_port_9)

print("------ Test Case (PASS): Transfer between DID's where either the Sender or Receiver are on a Quorum node ------\n")

print("\n1. Generating 2 whole RBT for A on node4 (node4 is a Quorum node)")
expect_success(fund_did_with_rbt)(node_4_info, did_4_A, 2)
print("Funded node A with 2 RBT")

print("\n2. Transferring 1 RBT from A to B on node4 (node4 is a Quorum node)")
expect_success(rbt_transfer)(did_4_A, did_4_B, 1, server_port_4, grpc_port_4)
print("Transferred 1 RBT from A to B")

print("\n3. Transferring 1 RBT from B to A (both present on same node)....")
expect_success(rbt_transfer)(did_A2, did_A1, 1, server_port_A, grpc_port_A)
print("\n3. Transferring 1 RBT from B to A on node4 (node4 is a Quorum node)")
expect_success(rbt_transfer)(did_4_B, did_4_A, 1, server_port_4, grpc_port_4)
print("Transferred 1 RBT from A to B")

print("\n------ Test Case (PASS): Transfer between DID's on same server completed ------\n")
print("\n4. Transferring 0.555 RBT from A to B on node4 (node4 is a Quorum node)")
expect_success(rbt_transfer)(did_4_A, did_4_B, 0.555, server_port_4, grpc_port_4)
print("Transferred 1 RBT from A to B")

print("\n5. Transferring 0.555 RBT from B to A on node4 (node4 is a Quorum node)")
expect_success(rbt_transfer)(did_4_B, did_4_B, 0.555, server_port_4, grpc_port_4)
print("Transferred 1 RBT from A to B")

print("\n6. Transferring 0.445 RBT from A of node4 to A of node5 (node4 and node5 are Quorum nodes)")
add_peer_details(node_5_info["peerId"], did_5_A, 4, server_port_4, grpc_port_4)
expect_success(rbt_transfer)(did_4_A, did_5_A, 0.445, server_port_4, grpc_port_4)
print("Transferred 1 RBT from A to B")

print("\n7. Transferring 0.445 RBT from A of node5 to A of node4 (node4 and node5 are Quorum nodes)")
add_peer_details(node_4_info["peerId"], did_4_A, 4, server_port_5, grpc_port_5)
expect_success(rbt_transfer)(did_5_A, did_4_A, 0.445, server_port_5, grpc_port_5)
print("Transferred 1 RBT from A to B")

print("\n8. Transferring 1 RBT from A of node4 to A of node9 (node4 is a Quorum node, node9 is a Non-Quorum node)")
add_peer_details(node_9_info["peerId"], did_9_A, 4, server_port_4, grpc_port_4)
expect_success(rbt_transfer)(did_4_A, did_9_A, 1, server_port_4, grpc_port_4)
print("Transferred 1 RBT from A to B")

print("\n9. Transferring 1 RBT from A of node9 to A of node4 (node4 is a Quorum node, node9 is a Non-Quorum node)")
add_peer_details(node_4_info["peerId"], did_4_A, 4, server_port_9, grpc_port_9)
expect_success(rbt_transfer)(did_9_A, did_4_A, 1, server_port_9, grpc_port_9)
print("Transferred 1 RBT from A to B")

print("------ Test Case (PASS): Transfer between DID's where either the Sender or Receiver are on a Quorum node completed------\n")

def max_decimal_place_transfer(config):
node_A_info, node_B_info = config["node9"], config["node10"]
Expand Down

0 comments on commit f15c8f0

Please sign in to comment.