From 22345cb1030d1e5775756232acdf5bcf14dbdda5 Mon Sep 17 00:00:00 2001 From: Uday Patil Date: Wed, 5 Oct 2022 14:02:12 -0700 Subject: [PATCH 1/2] [app] refactored graph into acl module --- app/app.go | 53 +------- app/graph.go | 321 ---------------------------------------------- app/graph_test.go | 257 ------------------------------------- go.mod | 6 +- go.sum | 2 - 5 files changed, 10 insertions(+), 629 deletions(-) delete mode 100644 app/graph.go delete mode 100644 app/graph_test.go diff --git a/app/app.go b/app/app.go index c4bdcb2a97..7429271ad3 100644 --- a/app/app.go +++ b/app/app.go @@ -13,7 +13,6 @@ import ( "time" storetypes "github.com/cosmos/cosmos-sdk/store/types" - graph "github.com/yourbasic/graph" appparams "github.com/sei-protocol/sei-chain/app/params" "github.com/sei-protocol/sei-chain/utils" @@ -879,44 +878,6 @@ func (app *App) ProcessProposalHandler(ctx sdk.Context, req *abci.RequestProcess }, nil } -func isGovMessage(msg sdk.Msg) bool { - switch msg.(type) { - case *govtypes.MsgVoteWeighted, *govtypes.MsgVote, *govtypes.MsgSubmitProposal, *govtypes.MsgDeposit: - return true - default: - return false - } -} - -func (app *App) BuildDependencyDag(ctx sdk.Context, txs [][]byte) (*Dag, error) { - defer metrics.MeasureBuildDagDuration(time.Now(), "BuildDependencyDag") - // contains the latest msg index for a specific Access Operation - dependencyDag := NewDag() - for txIndex, txBytes := range txs { - tx, err := app.txDecoder(txBytes) // TODO: results in repetitive decoding for txs with runtx decode (potential optimization) - if err != nil { - return nil, err - } - msgs := tx.GetMsgs() - for messageIndex, msg := range msgs { - if isGovMessage(msg) { - return nil, ErrGovMsgInBlock - } - msgDependencies := app.AccessControlKeeper.GetResourceDependencyMapping(ctx, acltypes.GenerateMessageKey(msg)) - for _, accessOp := range msgDependencies.GetAccessOps() { - // make a new node in the dependency dag - dependencyDag.AddNodeBuildDependency(messageIndex, txIndex, accessOp) - } - } - - } - - if !graph.Acyclic(&dependencyDag) { - return nil, ErrCycleInDAG - } - return &dependencyDag, nil -} - func (app *App) FinalizeBlocker(ctx sdk.Context, req *abci.RequestFinalizeBlock) (*abci.ResponseFinalizeBlock, error) { startTime := time.Now() defer func() { @@ -972,7 +933,7 @@ func (app *App) ProcessBlockSynchronous(ctx sdk.Context, txs [][]byte) []*abci.E } // Returns a mapping of the accessOperation to the channels -func getChannelsFromSignalMapping(signalMapping MessageCompletionSignalMapping) sdkacltypes.MessageAccessOpsChannelMapping { +func getChannelsFromSignalMapping(signalMapping acltypes.MessageCompletionSignalMapping) sdkacltypes.MessageAccessOpsChannelMapping { channelsMapping := make(sdkacltypes.MessageAccessOpsChannelMapping) for messageIndex, accessOperationsToSignal := range signalMapping { for accessOperation, completionSignals := range accessOperationsToSignal { @@ -998,8 +959,8 @@ func (app *App) ProcessTxConcurrent( txBytes []byte, wg *sync.WaitGroup, resultChan chan<- ChannelResult, - txCompletionSignalingMap MessageCompletionSignalMapping, - txBlockingSignalsMap MessageCompletionSignalMapping, + txCompletionSignalingMap acltypes.MessageCompletionSignalMapping, + txBlockingSignalsMap acltypes.MessageCompletionSignalMapping, ) { defer wg.Done() // Store the Channels in the Context Object for each transaction @@ -1014,8 +975,8 @@ func (app *App) ProcessTxConcurrent( func (app *App) ProcessBlockConcurrent( ctx sdk.Context, txs [][]byte, - completionSignalingMap map[int]MessageCompletionSignalMapping, - blockingSignalsMap map[int]MessageCompletionSignalMapping, + completionSignalingMap map[int]acltypes.MessageCompletionSignalMapping, + blockingSignalsMap map[int]acltypes.MessageCompletionSignalMapping, ) []*abci.ExecTxResult { var waitGroup sync.WaitGroup resultChan := make(chan ChannelResult) @@ -1104,14 +1065,14 @@ func (app *App) ProcessBlock(ctx sdk.Context, txs [][]byte, req BlockProcessRequ // } // app.batchVerifier.VerifyTxs(ctx, typedTxs) - dependencyDag, err := app.BuildDependencyDag(ctx, txs) + dependencyDag, err := app.AccessControlKeeper.BuildDependencyDag(ctx, app.txDecoder, txs) var txResults []*abci.ExecTxResult switch err { case nil: // Only run concurrently if no error txResults = app.ProcessBlockConcurrent(ctx, txs, dependencyDag.CompletionSignalingMap, dependencyDag.BlockingSignalsMap) - case ErrGovMsgInBlock: + case acltypes.ErrGovMsgInBlock: ctx.Logger().Info(fmt.Sprintf("Gov msg found while building DAG, processing synchronously: %s", err)) txResults = app.ProcessBlockSynchronous(ctx, txs) diff --git a/app/graph.go b/app/graph.go deleted file mode 100644 index 1b211bc61f..0000000000 --- a/app/graph.go +++ /dev/null @@ -1,321 +0,0 @@ -package app - -import ( - "fmt" - - acltypes "github.com/cosmos/cosmos-sdk/types/accesscontrol" - mapset "github.com/deckarep/golang-set" -) - -type DagNodeID int - -// Alias for mapping resource identifier to dag node IDs -type ResourceIdentifierNodeIDMapping = map[string][]DagNodeID - -type ResourceAccess struct { - ResourceType acltypes.ResourceType - AccessType acltypes.AccessType -} - -type DagNode struct { - NodeID DagNodeID - MessageIndex int - TxIndex int - AccessOperation acltypes.AccessOperation -} - -type DagEdge struct { - FromNodeID DagNodeID - ToNodeID DagNodeID -} - -type Dag struct { - NodeMap map[DagNodeID]DagNode - EdgesMap map[DagNodeID][]DagEdge // maps node Id (from node) and contains edge info - ResourceAccessMap map[ResourceAccess]ResourceIdentifierNodeIDMapping // maps resource type and access type to identifiers + node IDs - TxIndexMap map[int]DagNodeID // tracks latest node ID for a tx index - NextID DagNodeID - CompletionSignalingMap map[int]MessageCompletionSignalMapping // keys on tx index - BlockingSignalsMap map[int]MessageCompletionSignalMapping // keys on tx index -} - -// Alias for mapping MessageIndexId -> AccessOperations -> CompletionSignals -type MessageCompletionSignalMapping = map[int]map[acltypes.AccessOperation][]CompletionSignal - -type CompletionSignal struct { - FromNodeID DagNodeID - ToNodeID DagNodeID - CompletionAccessOperation acltypes.AccessOperation // this is the access operation that must complete in order to send the signal - BlockedAccessOperation acltypes.AccessOperation // this is the access operation that is blocked by the completion access operation - Channel chan interface{} -} - -func (dag *Dag) GetCompletionSignal(edge DagEdge) *CompletionSignal { - // only if tx indexes are different - fromNode := dag.NodeMap[edge.FromNodeID] - toNode := dag.NodeMap[edge.ToNodeID] - if fromNode.TxIndex == toNode.TxIndex { - // TODO: we may be able to remove this now since we don't created edges within a tx now - return nil - } - return &CompletionSignal{ - FromNodeID: fromNode.NodeID, - ToNodeID: toNode.NodeID, - CompletionAccessOperation: fromNode.AccessOperation, - BlockedAccessOperation: toNode.AccessOperation, - // channel used for signalling - Channel: make(chan interface{}), - } -} - -// Order returns the number of vertices in a graph. -func (dag Dag) Order() int { - return len(dag.NodeMap) -} - -// Visit calls the do function for each neighbor w of vertex v, used by the graph acyclic validator -func (dag Dag) Visit(v int, do func(w int, c int64) (skip bool)) (aborted bool) { - for _, edge := range dag.EdgesMap[DagNodeID(v)] { - // just have cost as zero because we only need for acyclic validation purposes - if do(int(edge.ToNodeID), 0) { - return true - } - } - return false -} - -func NewDag() Dag { - return Dag{ - NodeMap: make(map[DagNodeID]DagNode), - EdgesMap: make(map[DagNodeID][]DagEdge), - ResourceAccessMap: make(map[ResourceAccess]ResourceIdentifierNodeIDMapping), - TxIndexMap: make(map[int]DagNodeID), - NextID: 0, - CompletionSignalingMap: make(map[int]MessageCompletionSignalMapping), - BlockingSignalsMap: make(map[int]MessageCompletionSignalMapping), - } -} - -func GetResourceAccess(accessOp acltypes.AccessOperation) ResourceAccess { - return ResourceAccess{ - accessOp.ResourceType, - accessOp.AccessType, - } -} - -func (dag *Dag) AddNode(messageIndex int, txIndex int, accessOp acltypes.AccessOperation) DagNode { - dagNode := DagNode{ - NodeID: dag.NextID, - MessageIndex: messageIndex, - TxIndex: txIndex, - AccessOperation: accessOp, - } - dag.NodeMap[dag.NextID] = dagNode - dag.NextID++ - return dagNode -} - -func (dag *Dag) AddEdge(fromIndex DagNodeID, toIndex DagNodeID) *DagEdge { - // no-ops if the from or to node doesn't exist - if _, ok := dag.NodeMap[fromIndex]; !ok { - return nil - } - if _, ok := dag.NodeMap[toIndex]; !ok { - return nil - } - newEdge := DagEdge{fromIndex, toIndex} - dag.EdgesMap[fromIndex] = append(dag.EdgesMap[fromIndex], newEdge) - return &newEdge -} - -// This function is a helper used to build the dependency graph one access operation at a time. -// It will first add a node corresponding to the tx index and access operation (linking it to the previous most recent node for that tx if applicable) -// and then will build edges from any access operations on which the new node is dependent. -// -// This will be accomplished using the AccessOpsMap in dag which keeps track of which nodes access which resources. -// It will then create an edge between the relevant node upon which it is dependent, and this edge can later be used to build the completion signals -// that will allow the dependent goroutines to cordinate execution safely. -// -// It will also register the new node with AccessOpsMap so that future nodes that amy be dependent on this one can properly identify the dependency. -func (dag *Dag) AddNodeBuildDependency(messageIndex int, txIndex int, accessOp acltypes.AccessOperation) { - dagNode := dag.AddNode(messageIndex, txIndex, accessOp) - // update tx index map - dag.TxIndexMap[txIndex] = dagNode.NodeID - - nodeDependencies := dag.GetNodeDependencies(dagNode) - // build edges for each of the dependencies - for _, nodeDependency := range nodeDependencies { - edge := dag.AddEdge(nodeDependency, dagNode.NodeID) - // also add completion signal corresponding to the edge - if edge != nil { - maybeCompletionSignal := dag.GetCompletionSignal(*edge) - if maybeCompletionSignal != nil { - completionSignal := *maybeCompletionSignal - dag.AddCompletionSignal(completionSignal) - } - } - } - - // update access ops map with the latest node id using a specific access op - resourceAccess := GetResourceAccess(accessOp) - if _, exists := dag.ResourceAccessMap[resourceAccess]; !exists { - dag.ResourceAccessMap[resourceAccess] = make(ResourceIdentifierNodeIDMapping) - } - dag.ResourceAccessMap[resourceAccess][accessOp.IdentifierTemplate] = append(dag.ResourceAccessMap[resourceAccess][accessOp.IdentifierTemplate], dagNode.NodeID) -} - -func getAllNodeIDsFromIdentifierMapping(mapping ResourceIdentifierNodeIDMapping) (allNodeIDs []DagNodeID) { - for _, nodeIDs := range mapping { - allNodeIDs = append(allNodeIDs, nodeIDs...) - } - return -} - -func (dag *Dag) getDependencyWrites(node DagNode, dependentResource acltypes.ResourceType) mapset.Set { - nodeIDs := mapset.NewSet() - writeResourceAccess := ResourceAccess{ - dependentResource, - acltypes.AccessType_WRITE, - } - if identifierNodeMapping, ok := dag.ResourceAccessMap[writeResourceAccess]; ok { - var nodeIDsMaybeDependency []DagNodeID - if dependentResource != node.AccessOperation.ResourceType { - // we can add all node IDs as dependencies if applicable - nodeIDsMaybeDependency = getAllNodeIDsFromIdentifierMapping(identifierNodeMapping) - } else { - // TODO: otherwise we need to have partial filtering on identifiers - // for now, lets just perform exact matching on identifiers - nodeIDsMaybeDependency = identifierNodeMapping[node.AccessOperation.IdentifierTemplate] - } - for _, wn := range nodeIDsMaybeDependency { - writeNode := dag.NodeMap[wn] - // if accessOp exists already (and from a previous transaction), we need to define a dependency on the previous message (and make a edge between the two) - // if from a previous transaction, we need to create an edge - if writeNode.TxIndex < node.TxIndex { - // this should be the COMMIT access op for the tx - lastTxNode := dag.NodeMap[dag.TxIndexMap[writeNode.TxIndex]] - nodeIDs.Add(lastTxNode.NodeID) - } - } - } - return nodeIDs -} - -func (dag *Dag) getDependencyUnknowns(node DagNode, dependentResource acltypes.ResourceType) mapset.Set { - nodeIDs := mapset.NewSet() - unknownResourceAccess := ResourceAccess{ - dependentResource, - acltypes.AccessType_UNKNOWN, - } - if identifierNodeMapping, ok := dag.ResourceAccessMap[unknownResourceAccess]; ok { - var nodeIDsMaybeDependency []DagNodeID - if dependentResource != node.AccessOperation.ResourceType { - // we can add all node IDs as dependencies if applicable - nodeIDsMaybeDependency = getAllNodeIDsFromIdentifierMapping(identifierNodeMapping) - } else { - // TODO: otherwise we need to have partial filtering on identifiers - // for now, lets just perform exact matching on identifiers - nodeIDsMaybeDependency = identifierNodeMapping[node.AccessOperation.IdentifierTemplate] - } - for _, un := range nodeIDsMaybeDependency { - uNode := dag.NodeMap[un] - // if accessOp exists already (and from a previous transaction), we need to define a dependency on the previous message (and make a edge between the two) - // if from a previous transaction, we need to create an edge - if uNode.TxIndex < node.TxIndex { - // this should be the COMMIT access op for the tx - lastTxNode := dag.NodeMap[dag.TxIndexMap[uNode.TxIndex]] - nodeIDs.Add(lastTxNode.NodeID) - } - } - } - return nodeIDs -} - -func (dag *Dag) getDependencyReads(node DagNode, dependentResource acltypes.ResourceType) mapset.Set { - nodeIDs := mapset.NewSet() - readResourceAccess := ResourceAccess{ - dependentResource, - acltypes.AccessType_READ, - } - if identifierNodeMapping, ok := dag.ResourceAccessMap[readResourceAccess]; ok { - var nodeIDsMaybeDependency []DagNodeID - if dependentResource != node.AccessOperation.ResourceType { - // we can add all node IDs as dependencies if applicable - nodeIDsMaybeDependency = getAllNodeIDsFromIdentifierMapping(identifierNodeMapping) - } else { - // TODO: otherwise we need to have partial filtering on identifiers - // for now, lets just perform exact matching on identifiers - nodeIDsMaybeDependency = identifierNodeMapping[node.AccessOperation.IdentifierTemplate] - } - for _, rn := range nodeIDsMaybeDependency { - readNode := dag.NodeMap[rn] - // if from a previous transaction, we need to create an edge - if readNode.TxIndex < node.TxIndex { - nodeIDs.Add(readNode.NodeID) - } - } - } - return nodeIDs -} - -// given a node, and a dependent Resource, generate a set of nodes that are dependencies -func (dag *Dag) getNodeDependenciesForResource(node DagNode, dependentResource acltypes.ResourceType) mapset.Set { - nodeIDs := mapset.NewSet() - switch node.AccessOperation.AccessType { - case acltypes.AccessType_READ: - // for a read, we are blocked on prior writes and unknown - nodeIDs = nodeIDs.Union(dag.getDependencyWrites(node, dependentResource)) - nodeIDs = nodeIDs.Union(dag.getDependencyUnknowns(node, dependentResource)) - case acltypes.AccessType_WRITE, acltypes.AccessType_UNKNOWN: - // for write / unknown, we're blocked on prior writes, reads, and unknowns - nodeIDs = nodeIDs.Union(dag.getDependencyWrites(node, dependentResource)) - nodeIDs = nodeIDs.Union(dag.getDependencyUnknowns(node, dependentResource)) - nodeIDs = nodeIDs.Union(dag.getDependencyReads(node, dependentResource)) - } - return nodeIDs -} - -// This helper will identify nodes that are dependencies for the current node, and can then be used for creating edges between then for future completion signals -func (dag *Dag) GetNodeDependencies(node DagNode) []DagNodeID { - accessOp := node.AccessOperation - // get all parent resource types, we'll need to create edges for any of these - parentResources := accessOp.ResourceType.GetResourceDependencies() - nodeIDSet := mapset.NewSet() - for _, resource := range parentResources { - nodeIDSet = nodeIDSet.Union(dag.getNodeDependenciesForResource(node, resource)) - } - nodeDependencies := make([]DagNodeID, nodeIDSet.Cardinality()) - for i, x := range nodeIDSet.ToSlice() { - nodeDependencies[i] = x.(DagNodeID) - } - return nodeDependencies -} - -func (dag *Dag) AddCompletionSignal(completionSignal CompletionSignal) { - toNode := dag.NodeMap[completionSignal.ToNodeID] - if _, exists := dag.BlockingSignalsMap[toNode.TxIndex]; !exists { - dag.BlockingSignalsMap[toNode.TxIndex] = make(MessageCompletionSignalMapping) - } - if _, exists := dag.BlockingSignalsMap[toNode.TxIndex][toNode.MessageIndex]; !exists { - dag.BlockingSignalsMap[toNode.TxIndex][toNode.MessageIndex] = make(map[acltypes.AccessOperation][]CompletionSignal) - } - // add it to the right blocking signal in the right txindex - prevBlockSignalMapping := dag.BlockingSignalsMap[toNode.TxIndex][toNode.MessageIndex][completionSignal.BlockedAccessOperation] - dag.BlockingSignalsMap[toNode.TxIndex][toNode.MessageIndex][completionSignal.BlockedAccessOperation] = append(prevBlockSignalMapping, completionSignal) - - fromNode := dag.NodeMap[completionSignal.FromNodeID] - if _, exists := dag.CompletionSignalingMap[fromNode.TxIndex]; !exists { - dag.CompletionSignalingMap[fromNode.TxIndex] = make(MessageCompletionSignalMapping) - } - if _, exists := dag.CompletionSignalingMap[fromNode.TxIndex][fromNode.MessageIndex]; !exists { - dag.CompletionSignalingMap[fromNode.TxIndex][fromNode.MessageIndex] = make(map[acltypes.AccessOperation][]CompletionSignal) - } - // add it to the completion signal for the tx index - prevCompletionSignalMapping := dag.CompletionSignalingMap[fromNode.TxIndex][fromNode.MessageIndex][completionSignal.CompletionAccessOperation] - dag.CompletionSignalingMap[fromNode.TxIndex][fromNode.MessageIndex][completionSignal.CompletionAccessOperation] = append(prevCompletionSignalMapping, completionSignal) -} - -var ( - ErrCycleInDAG = fmt.Errorf("cycle detected in DAG") - ErrGovMsgInBlock = fmt.Errorf("gov msg in block") -) diff --git a/app/graph_test.go b/app/graph_test.go deleted file mode 100644 index dea4c6c682..0000000000 --- a/app/graph_test.go +++ /dev/null @@ -1,257 +0,0 @@ -package app_test - -import ( - "sort" - "testing" - - acltypes "github.com/cosmos/cosmos-sdk/types/accesscontrol" - "github.com/sei-protocol/sei-chain/app" - "github.com/stretchr/testify/require" - "github.com/yourbasic/graph" -) - -func TestCreateGraph(t *testing.T) { - dag := app.NewDag() - /** - tx1: write to A, read B, commit 1 - tx2: read A, read B, commit 2 - tx3: read A, read B, commit 3 - tx4: write B, commit 4 - expected dag - 1wA -> 1rB -> 1c =>v 2rA -> 2rB ----=\---> 2c - 3rB -------------> 3rA -> 3c V - \-----------------------------------=> 4wB -> 4c - **/ - - commitAccessOp := acltypes.AccessOperation{ - AccessType: acltypes.AccessType_COMMIT, - ResourceType: acltypes.ResourceType_ANY, - IdentifierTemplate: "*", - } - writeAccessA := acltypes.AccessOperation{ - AccessType: acltypes.AccessType_WRITE, - ResourceType: acltypes.ResourceType_KV, - IdentifierTemplate: "ResourceA", - } - readAccessA := acltypes.AccessOperation{ - AccessType: acltypes.AccessType_READ, - ResourceType: acltypes.ResourceType_KV, - IdentifierTemplate: "ResourceA", - } - writeAccessB := acltypes.AccessOperation{ - AccessType: acltypes.AccessType_WRITE, - ResourceType: acltypes.ResourceType_KV, - IdentifierTemplate: "ResourceB", - } - readAccessB := acltypes.AccessOperation{ - AccessType: acltypes.AccessType_READ, - ResourceType: acltypes.ResourceType_KV, - IdentifierTemplate: "ResourceB", - } - - dag.AddNodeBuildDependency(0, 0, writeAccessA) // node id 0 - dag.AddNodeBuildDependency(0, 0, readAccessB) // node id 1 - dag.AddNodeBuildDependency(0, 0, commitAccessOp) // node id 2 - dag.AddNodeBuildDependency(0, 1, readAccessA) // node id 3 - dag.AddNodeBuildDependency(0, 1, readAccessB) // node id 4 - dag.AddNodeBuildDependency(0, 1, commitAccessOp) // node id 5 - dag.AddNodeBuildDependency(0, 2, readAccessB) // node id 6 - dag.AddNodeBuildDependency(0, 2, readAccessA) // node id 7 - dag.AddNodeBuildDependency(0, 2, commitAccessOp) // node id 8 - dag.AddNodeBuildDependency(0, 3, writeAccessB) // node id 9 - dag.AddNodeBuildDependency(0, 3, commitAccessOp) // node id 10 - - require.Equal(t, []app.DagEdge(nil), dag.EdgesMap[0]) - require.Equal( - t, - []app.DagEdge{{1, 9}}, - dag.EdgesMap[1], - ) - require.Equal( - t, - []app.DagEdge{{2, 3}, {2, 7}}, - dag.EdgesMap[2], - ) - require.Equal(t, []app.DagEdge(nil), dag.EdgesMap[3]) - require.Equal( - t, - []app.DagEdge{{4, 9}}, - dag.EdgesMap[4], - ) - require.Equal(t, []app.DagEdge(nil), dag.EdgesMap[5]) - require.Equal( - t, - []app.DagEdge{{6, 9}}, - dag.EdgesMap[6], - ) - require.Equal(t, []app.DagEdge(nil), dag.EdgesMap[7]) - require.Equal(t, []app.DagEdge(nil), dag.EdgesMap[8]) - require.Equal(t, []app.DagEdge(nil), dag.EdgesMap[9]) - require.Equal(t, []app.DagEdge(nil), dag.EdgesMap[10]) - - // assert dag is acyclic - acyclic := graph.Acyclic(dag) - require.True(t, acyclic) - - // test completion signals - completionSignalsMap, blockingSignalsMap := dag.CompletionSignalingMap, dag.BlockingSignalsMap - - channel0 := completionSignalsMap[0][0][commitAccessOp][0].Channel - channel1 := completionSignalsMap[0][0][commitAccessOp][1].Channel - channel2 := completionSignalsMap[1][0][readAccessB][0].Channel - channel3 := completionSignalsMap[0][0][readAccessB][0].Channel - channel4 := completionSignalsMap[2][0][readAccessB][0].Channel - - signal0 := app.CompletionSignal{2, 3, commitAccessOp, readAccessA, channel0} - signal1 := app.CompletionSignal{2, 7, commitAccessOp, readAccessA, channel1} - signal2 := app.CompletionSignal{4, 9, readAccessB, writeAccessB, channel2} - signal3 := app.CompletionSignal{1, 9, readAccessB, writeAccessB, channel3} - signal4 := app.CompletionSignal{6, 9, readAccessB, writeAccessB, channel4} - - require.Equal( - t, - []app.CompletionSignal{signal0, signal1}, - completionSignalsMap[0][0][commitAccessOp], - ) - require.Equal( - t, - []app.CompletionSignal{signal0}, - blockingSignalsMap[1][0][readAccessA], - ) - require.Equal( - t, - []app.CompletionSignal{signal1}, - blockingSignalsMap[2][0][readAccessA], - ) - - require.Equal( - t, - []app.CompletionSignal{signal2}, - completionSignalsMap[1][0][readAccessB], - ) - require.Equal( - t, - []app.CompletionSignal{signal3}, - completionSignalsMap[0][0][readAccessB], - ) - require.Equal( - t, - []app.CompletionSignal{signal4}, - completionSignalsMap[2][0][readAccessB], - ) - slice := blockingSignalsMap[3][0][writeAccessB] - sort.SliceStable(slice, func(p, q int) bool { - return slice[p].FromNodeID < slice[q].FromNodeID - }) - require.Equal( - t, - []app.CompletionSignal{signal3, signal2, signal4}, - slice, - ) -} - -func TestHierarchyDag(t *testing.T) { - dag := app.NewDag() - /** - tx1: write to A, commit 1 - tx2: read ALL, commit 2 - tx3: write B dexmem, commit 3 - tx4: read A, commit 4 - expected dag - 1wA -> 1c => 2rALL -> 2c - \ \=> 3wB c3 - \---=> 4rA c4 - **/ - - commit := acltypes.AccessOperation{ - AccessType: acltypes.AccessType_COMMIT, - ResourceType: acltypes.ResourceType_ANY, - IdentifierTemplate: "*", - } - writeA := acltypes.AccessOperation{ - AccessType: acltypes.AccessType_WRITE, - ResourceType: acltypes.ResourceType_KV, - IdentifierTemplate: "ResourceA", - } - readA := acltypes.AccessOperation{ - AccessType: acltypes.AccessType_READ, - ResourceType: acltypes.ResourceType_KV, - IdentifierTemplate: "ResourceA", - } - writeB := acltypes.AccessOperation{ - AccessType: acltypes.AccessType_WRITE, - ResourceType: acltypes.ResourceType_DexMem, - IdentifierTemplate: "ResourceB", - } - readAll := acltypes.AccessOperation{ - AccessType: acltypes.AccessType_READ, - ResourceType: acltypes.ResourceType_ANY, - IdentifierTemplate: "*", - } - - dag.AddNodeBuildDependency(0, 0, writeA) // node id 0 - dag.AddNodeBuildDependency(0, 0, commit) // node id 1 - dag.AddNodeBuildDependency(0, 1, readAll) // node id 2 - dag.AddNodeBuildDependency(0, 1, commit) // node id 3 - dag.AddNodeBuildDependency(0, 2, writeB) // node id 4 - dag.AddNodeBuildDependency(0, 2, commit) // node id 5 - dag.AddNodeBuildDependency(0, 3, readA) // node id 6 - dag.AddNodeBuildDependency(0, 3, commit) // node id 7 - - // assert dag is acyclic - acyclic := graph.Acyclic(dag) - require.True(t, acyclic) - - require.Equal(t, []app.DagEdge(nil), dag.EdgesMap[0]) - require.Equal( - t, - []app.DagEdge{{1, 2}, {1, 6}}, - dag.EdgesMap[1], - ) - require.Equal( - t, - []app.DagEdge{{2, 4}}, - dag.EdgesMap[2], - ) - require.Equal(t, []app.DagEdge(nil), dag.EdgesMap[3]) - require.Equal(t, []app.DagEdge(nil), dag.EdgesMap[4]) - require.Equal(t, []app.DagEdge(nil), dag.EdgesMap[5]) - require.Equal(t, []app.DagEdge(nil), dag.EdgesMap[6]) - - // test completion signals - completionSignalsMap, blockingSignalsMap := dag.CompletionSignalingMap, dag.BlockingSignalsMap - - channel0 := completionSignalsMap[0][0][commit][0].Channel - channel1 := completionSignalsMap[0][0][commit][1].Channel - channel2 := completionSignalsMap[1][0][readAll][0].Channel - - signal0 := app.CompletionSignal{1, 2, commit, readAll, channel0} - signal1 := app.CompletionSignal{1, 6, commit, readA, channel1} - signal2 := app.CompletionSignal{2, 4, readAll, writeB, channel2} - - require.Equal( - t, - []app.CompletionSignal{signal0, signal1}, - completionSignalsMap[0][0][commit], - ) - require.Equal( - t, - []app.CompletionSignal{signal0}, - blockingSignalsMap[1][0][readAll], - ) - require.Equal( - t, - []app.CompletionSignal{signal1}, - blockingSignalsMap[3][0][readA], - ) - require.Equal( - t, - []app.CompletionSignal{signal2}, - completionSignalsMap[1][0][readAll], - ) - require.Equal( - t, - []app.CompletionSignal{signal2}, - blockingSignalsMap[2][0][writeB], - ) -} diff --git a/go.mod b/go.mod index 3362781b78..fddb10e333 100644 --- a/go.mod +++ b/go.mod @@ -9,7 +9,6 @@ require ( github.com/cosmos/cosmos-sdk v0.45.4 github.com/cosmos/go-bip39 v1.0.0 github.com/cosmos/ibc-go/v3 v3.0.0 - github.com/deckarep/golang-set v1.8.0 github.com/gogo/protobuf v1.3.3 github.com/golang/protobuf v1.5.2 github.com/gorilla/mux v1.8.0 @@ -21,7 +20,6 @@ require ( github.com/stretchr/testify v1.8.0 github.com/tendermint/tendermint v0.37.0-dev github.com/tendermint/tm-db v0.6.8-0.20220519162814-e24b96538a12 - github.com/yourbasic/graph v0.0.0-20210606180040-8ecfec1c2869 go.opentelemetry.io/otel v1.9.0 go.opentelemetry.io/otel/exporters/jaeger v1.9.0 go.opentelemetry.io/otel/sdk v1.9.0 @@ -50,6 +48,7 @@ require ( github.com/creachadair/taskgroup v0.3.2 // indirect github.com/danieljoos/wincred v1.0.2 // indirect github.com/davecgh/go-spew v1.1.1 // indirect + github.com/deckarep/golang-set v1.8.0 // indirect github.com/desertbit/timer v0.0.0-20180107155436-c41aec40b27f // indirect github.com/dgraph-io/badger/v3 v3.2103.2 // indirect github.com/dgraph-io/ristretto v0.1.0 // indirect @@ -116,6 +115,7 @@ require ( github.com/tendermint/btcd v0.1.1 // indirect github.com/tendermint/crypto v0.0.0-20191022145703-50d29ede1e15 // indirect github.com/tendermint/go-amino v0.16.0 // indirect + github.com/yourbasic/graph v0.0.0-20210606180040-8ecfec1c2869 // indirect github.com/zondax/hid v0.9.0 // indirect go.etcd.io/bbolt v1.3.6 // indirect go.opencensus.io v0.23.0 // indirect @@ -131,7 +131,7 @@ require ( ) replace ( - github.com/cosmos/cosmos-sdk => github.com/sei-protocol/sei-cosmos v0.1.78 + github.com/cosmos/cosmos-sdk => ../sei-cosmos //github.com/sei-protocol/sei-cosmos v0.1.78 github.com/gogo/protobuf => github.com/regen-network/protobuf v1.3.3-alpha.regen.1 github.com/keybase/go-keychain => github.com/99designs/go-keychain v0.0.0-20191008050251-8e49817e8af4 github.com/tendermint/tendermint => github.com/sei-protocol/sei-tendermint v0.1.56 diff --git a/go.sum b/go.sum index 5bc72bd4ac..bb989fc924 100644 --- a/go.sum +++ b/go.sum @@ -1097,8 +1097,6 @@ github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg github.com/seccomp/libseccomp-golang v0.9.1/go.mod h1:GbW5+tmTXfcxTToHLXlScSlAvWlF4P2Ca7zGrPiEpWo= github.com/securego/gosec/v2 v2.11.0/go.mod h1:SX8bptShuG8reGC0XS09+a4H2BoWSJi+fscA+Pulbpo= github.com/segmentio/fasthash v1.0.3/go.mod h1:waKX8l2N8yckOgmSsXJi7x1ZfdKZ4x7KRMzBtS3oedY= -github.com/sei-protocol/sei-cosmos v0.1.78 h1:cPIp/vsmI7KFyP4fC7iyEQL77KXKIe4xUqIBk2XaJCo= -github.com/sei-protocol/sei-cosmos v0.1.78/go.mod h1:Oaj7toqHCkwEEb+sDIWxtfTkPZxOpMXBXDMvIIqUjpw= github.com/sei-protocol/sei-tendermint v0.1.56 h1:iRVhiIetj+GSwpBzaR9lqgvmgcOqmShfACS6x3tuBIw= github.com/sei-protocol/sei-tendermint v0.1.56/go.mod h1:Olwbjyagrpoxj5DAUhHxMTWDVEfQ3FYdpypaJ3+6Hs8= github.com/sergi/go-diff v1.1.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM= From 0e5124366c90acf07e543108114f21e402ccec44 Mon Sep 17 00:00:00 2001 From: Uday Patil Date: Wed, 5 Oct 2022 18:40:30 -0700 Subject: [PATCH 2/2] go mod tidy --- go.mod | 2 +- go.sum | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/go.mod b/go.mod index fddb10e333..4fdde5b8ff 100644 --- a/go.mod +++ b/go.mod @@ -131,7 +131,7 @@ require ( ) replace ( - github.com/cosmos/cosmos-sdk => ../sei-cosmos //github.com/sei-protocol/sei-cosmos v0.1.78 + github.com/cosmos/cosmos-sdk => github.com/sei-protocol/sei-cosmos v0.1.82 github.com/gogo/protobuf => github.com/regen-network/protobuf v1.3.3-alpha.regen.1 github.com/keybase/go-keychain => github.com/99designs/go-keychain v0.0.0-20191008050251-8e49817e8af4 github.com/tendermint/tendermint => github.com/sei-protocol/sei-tendermint v0.1.56 diff --git a/go.sum b/go.sum index bb989fc924..b206a5e179 100644 --- a/go.sum +++ b/go.sum @@ -1097,6 +1097,8 @@ github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg github.com/seccomp/libseccomp-golang v0.9.1/go.mod h1:GbW5+tmTXfcxTToHLXlScSlAvWlF4P2Ca7zGrPiEpWo= github.com/securego/gosec/v2 v2.11.0/go.mod h1:SX8bptShuG8reGC0XS09+a4H2BoWSJi+fscA+Pulbpo= github.com/segmentio/fasthash v1.0.3/go.mod h1:waKX8l2N8yckOgmSsXJi7x1ZfdKZ4x7KRMzBtS3oedY= +github.com/sei-protocol/sei-cosmos v0.1.82 h1:vGsbp35KOZzP3YQoJ8T0MuWpLuC8Ea+6+F5QvHy9a5c= +github.com/sei-protocol/sei-cosmos v0.1.82/go.mod h1:L4fVgFVReigFZAe+43UNhaCf3DQzUZvpN6LlBsWkub4= github.com/sei-protocol/sei-tendermint v0.1.56 h1:iRVhiIetj+GSwpBzaR9lqgvmgcOqmShfACS6x3tuBIw= github.com/sei-protocol/sei-tendermint v0.1.56/go.mod h1:Olwbjyagrpoxj5DAUhHxMTWDVEfQ3FYdpypaJ3+6Hs8= github.com/sergi/go-diff v1.1.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM=