The core protocol of WoopChain
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
woop/rosetta/services/network_test.go

221 lines
6.4 KiB

Rosetta Implementation - pt2 (Stage 3.2 of Node API Overhaul) (#3312) * [rosetta] Add server stop Signed-off-by: Daniel Van Der Maden <dvandermaden0@berkeley.edu> * [rosetta] Make network naming consistent Signed-off-by: Daniel Van Der Maden <dvandermaden0@berkeley.edu> * [rosetta] Correct common package name & add error enum Signed-off-by: Daniel Van Der Maden <dvandermaden0@berkeley.edu> * [rosetta] Remove needless forward of network info to services * Implement /network/list Signed-off-by: Daniel Van Der Maden <dvandermaden0@berkeley.edu> * [rosetta] Refactor errors & add operation statuses and types Signed-off-by: Daniel Van Der Maden <dvandermaden0@berkeley.edu> * [rosetta] Implement NetworkOptions & update NetworkAPIService * Rename *_service.go files to remove the suffix * Update StartServers to use new operation types Signed-off-by: Daniel Van Der Maden <dvandermaden0@berkeley.edu> * [rosetta] Impl NetworkStatus - Finish init impl of /network endpoint * Fix import structure for rosetta.go Signed-off-by: Daniel Van Der Maden <dvandermaden0@berkeley.edu> * [test] Make explorer run as archival for localnet Signed-off-by: Daniel Van Der Maden <dvandermaden0@berkeley.edu> * [rosetta] Add unit tests * Force errors to remain the same with unit tests * Force operations to remain the same with unit tests * Ensure network checking works for all cases with unit tests Signed-off-by: Daniel Van Der Maden <dvandermaden0@berkeley.edu> * [rosetta] Add InvalidNetworkError and correct error codes Signed-off-by: Daniel Van Der Maden <dvandermaden0@berkeley.edu> * [rosetta] Add UnmarshalFromInterface for SubNetworkMetadata Signed-off-by: Daniel Van Der Maden <dvandermaden0@berkeley.edu> * [rosetta] Add network checking Signed-off-by: Daniel Van Der Maden <dvandermaden0@berkeley.edu> * [rosetta] Nit fixes & add unit test for Peer Info * Make names consistent Signed-off-by: Daniel Van Der Maden <dvandermaden0@berkeley.edu> * [rosetta] Add BlockNotFoundError & TransactionNotFoundError Signed-off-by: Daniel Van Der Maden <dvandermaden0@berkeley.edu> * [rosetta] Implement skeleton for block transactions Signed-off-by: Daniel Van Der Maden <dvandermaden0@berkeley.edu> * [rosetta] Add ReceiptNotFoundError Signed-off-by: Daniel Van Der Maden <dvandermaden0@berkeley.edu> * [rosetta] Add receipt to formatTransaction sig for contract fails Signed-off-by: Daniel Van Der Maden <dvandermaden0@berkeley.edu> * [rosetta] Add currency, ExpendGasOperation, & ContractCreationOperation * Add Error creator Signed-off-by: Daniel Van Der Maden <dvandermaden0@berkeley.edu> * [rosetta] Init impl of plain transaction formatting Signed-off-by: Daniel Van Der Maden <dvandermaden0@berkeley.edu> * [rosetta] Update network.go for new error constructor Signed-off-by: Daniel Van Der Maden <dvandermaden0@berkeley.edu> * [rosetta] Implement stx formatter & refactor BlockTransaction * Updated todo comments & function formatting Signed-off-by: Daniel Van Der Maden <dvandermaden0@berkeley.edu> * [rosetta] Impl Block & make currency non-ptr for easy copy with custom metadata Signed-off-by: Daniel Van Der Maden <dvandermaden0@berkeley.edu> * [rosetta] Fix collect rewards amount on transaction fetch Signed-off-by: Daniel Van Der Maden <dvandermaden0@berkeley.edu> * [rosetta] Fix block look-up edge case & add recovery middleware Signed-off-by: Daniel Van Der Maden <dvandermaden0@berkeley.edu> * [rosetta] Add bocks unit tests Signed-off-by: Daniel Van Der Maden <dvandermaden0@berkeley.edu> * [rosetta] Fix checkPeerID unit test in network_test.go Signed-off-by: Daniel Van Der Maden <dvandermaden0@berkeley.edu> * [rosetta] Fix staking tx amount for tx ops & update inline docs Signed-off-by: Daniel Van Der Maden <dvandermaden0@berkeley.edu> * [rosetta] Fix lint Signed-off-by: Daniel Van Der Maden <dvandermaden0@berkeley.edu> * [rosetta] Refactor getStakingOperations Signed-off-by: Daniel Van Der Maden <dvandermaden0@berkeley.edu> * [rosetta] Fix undelegate value Signed-off-by: Daniel Van Der Maden <dvandermaden0@berkeley.edu> * [rosetta] Nit - fix formatting for network.go Signed-off-by: Daniel Van Der Maden <dvandermaden0@berkeley.edu> * [node] Move genesis allocation to core & remove unused ContractDeployerKey Signed-off-by: Daniel Van Der Maden <dvandermaden0@berkeley.edu> * [rosetta] Fix precision error & add cx receipt hash on blk fetch * Add unit tests for supporting helper functions Signed-off-by: Daniel Van Der Maden <dvandermaden0@berkeley.edu> * [rosetta] Fix fmt Signed-off-by: Daniel Van Der Maden <dvandermaden0@berkeley.edu> * [rosetta] Fix cx receipt hashes for blocks * Print stack trace on panic recovery Signed-off-by: Daniel Van Der Maden <dvandermaden0@berkeley.edu> * [node] Nit - fix comment for StopRosetta Signed-off-by: Daniel Van Der Maden <dvandermaden0@berkeley.edu> * [node] Expose GetMaxPeerHeight Signed-off-by: Daniel Van Der Maden <dvandermaden0@berkeley.edu> * [rosetta] Add SyncStatus enum Signed-off-by: Daniel Van Der Maden <dvandermaden0@berkeley.edu> * [rosetta] Nit - remove redundant 'service' name in services namespace Signed-off-by: Daniel Van Der Maden <dvandermaden0@berkeley.edu>
4 years ago
package services
import (
"fmt"
"reflect"
"sort"
"testing"
"github.com/coinbase/rosetta-sdk-go/types"
"github.com/harmony-one/harmony/rosetta/common"
commonRPC "github.com/harmony-one/harmony/rpc/common"
"github.com/libp2p/go-libp2p-core/peer"
)
func TestErrors(t *testing.T) {
refBaseErrors := []*types.Error{
&common.CatchAllError,
&common.SanityCheckError,
&common.InvalidNetworkError,
&common.TransactionSubmissionError,
&common.BlockNotFoundError,
&common.TransactionNotFoundError,
&common.ReceiptNotFoundError,
}
refBeaconErrors := []*types.Error{
&common.StakingTransactionSubmissionError,
}
if !reflect.DeepEqual(refBaseErrors, getErrors()) {
t.Errorf("Expected errors to be: %v", refBaseErrors)
}
if !reflect.DeepEqual(refBeaconErrors, getBeaconErrors()) {
t.Errorf("Expected errors to be: %v", refBeaconErrors)
}
}
func TestOperationStatus(t *testing.T) {
refBaseOperations := []*types.OperationStatus{
common.SuccessOperationStatus,
common.FailureOperationStatus,
common.ContractFailureOperationStatus,
}
refBeaconOperations := []*types.OperationStatus{}
if !reflect.DeepEqual(refBaseOperations, getOperationStatuses()) {
t.Errorf("Expected operation status to be: %v", refBaseOperations)
}
if !reflect.DeepEqual(refBeaconOperations, getBeaconOperationStatuses()) {
t.Errorf("Expected operation status to be: %v", refBeaconOperations)
}
}
// Note that this assumes TestErrors & TestOperationStatus passes
func TestAllow(t *testing.T) {
refBaseAllow := &types.Allow{
OperationStatuses: getOperationStatuses(),
OperationTypes: common.PlainOperationTypes,
Errors: getErrors(),
HistoricalBalanceLookup: false,
}
refBeaconAllow := &types.Allow{
OperationStatuses: append(getOperationStatuses(), getBeaconOperationStatuses()...),
OperationTypes: append(common.PlainOperationTypes, common.StakingOperationTypes...),
Errors: append(getErrors(), getBeaconErrors()...),
HistoricalBalanceLookup: false,
}
if !reflect.DeepEqual(refBaseAllow, getAllow(false)) {
t.Errorf("Expected allow to be: %v", refBaseAllow)
}
if !reflect.DeepEqual(refBeaconAllow, getBeaconAllow(false)) {
t.Errorf("Expected allow to be: %v", refBeaconAllow)
}
}
func TestValidAssertValidNetworkIdentifier(t *testing.T) {
testNetworkID, err := common.GetNetwork(0)
if err != nil {
t.Fatal(err.Error())
}
if err := assertValidNetworkIdentifier(testNetworkID, 0); err != nil {
t.Error(err)
}
}
func TestInvalidAssertValidNetworkIdentifier(t *testing.T) {
testNetworkID, err := common.GetNetwork(0)
if err != nil {
t.Fatal(err.Error())
}
if err := assertValidNetworkIdentifier(testNetworkID, 0); err != nil {
t.Fatal(err)
}
testNetworkID.Blockchain = "Bad"
rosettaError := assertValidNetworkIdentifier(testNetworkID, 0)
if rosettaError == nil {
t.Error("Expected error for bad blockchain for network ID")
} else if rosettaError.Code != common.InvalidNetworkError.Code {
t.Errorf("Expected returned error code to be %v", common.InvalidNetworkError.Code)
}
testNetworkID, _ = common.GetNetwork(0)
testNetworkID.Network = "not a network"
rosettaError = assertValidNetworkIdentifier(testNetworkID, 0)
if rosettaError == nil {
t.Error("Expected error for bad network for network ID")
} else if rosettaError.Code != common.InvalidNetworkError.Code {
t.Errorf("Expected returned error code to be %v", common.InvalidNetworkError.Code)
}
testNetworkID, _ = common.GetNetwork(0)
testNetworkID.SubNetworkIdentifier.Network = "not a shard"
rosettaError = assertValidNetworkIdentifier(testNetworkID, 0)
if rosettaError == nil {
t.Error("Expected error for bad subnetwork for network ID")
} else if rosettaError.Code != common.InvalidNetworkError.Code {
t.Errorf("Expected returned error code to be %v", common.InvalidNetworkError.Code)
}
testNetworkID, _ = common.GetNetwork(0)
testNetworkID.SubNetworkIdentifier.Metadata = map[string]interface{}{"blah": "blah"}
rosettaError = assertValidNetworkIdentifier(testNetworkID, 0)
if rosettaError == nil {
t.Error("Expected error for bad subnetwork metadata for network ID")
} else if rosettaError.Code != common.InvalidNetworkError.Code {
t.Errorf("Expected returned error code to be %v", common.InvalidNetworkError.Code)
}
testNetworkID, _ = common.GetNetwork(0)
isBeacon, ok := testNetworkID.SubNetworkIdentifier.Metadata["is_beacon"].(bool)
if !ok {
t.Fatal("Could not get `is_beacon` subnetwork metadata from reference network ID")
}
testNetworkID.SubNetworkIdentifier.Metadata["is_beacon"] = !isBeacon
rosettaError = assertValidNetworkIdentifier(testNetworkID, 0)
if rosettaError == nil {
t.Error("Expected error for bad subnetwork metadata for network ID")
} else if rosettaError.Code != common.InvalidNetworkError.Code {
t.Errorf("Expected returned error code to be %v", common.InvalidNetworkError.Code)
}
}
func TestGetPeersFromNodePeerInfo(t *testing.T) {
testNodePeerInfo := generateTestNodePeerInfoList()
peers, err := getPeersFromNodePeerInfo(testNodePeerInfo)
if err != nil {
t.Fatal(err)
}
found := map[string]bool{}
for _, p := range peers {
found[p.PeerID] = true
var refTopics []string
switch p.PeerID {
case peer.ID("jim").String():
refTopics = []string{"test1", "test2"}
case peer.ID("bob").String():
refTopics = []string{"test1"}
case peer.ID("alice").String():
refTopics = []string{"test3"}
case peer.ID("mary").String():
refTopics = []string{"test3"}
default:
t.Fatalf("unknown peerID %v", p.PeerID)
}
if err := checkPeerID(p, refTopics); err != nil {
t.Errorf(err.Error())
}
}
if len(found) != 4 {
t.Errorf("Did not find peerIDs for all 4 peers: %v", found)
}
}
func generateTestNodePeerInfoList() commonRPC.NodePeerInfo {
return commonRPC.NodePeerInfo{
PeerID: "test",
BlockedPeers: []peer.ID{},
P: []commonRPC.P{
{
Topic: "test1",
Peers: []peer.ID{
"jim",
"bob",
},
},
{
Topic: "test2",
Peers: []peer.ID{
"jim",
},
},
{
Topic: "test3",
Peers: []peer.ID{
"alice",
"mary",
},
},
},
}
}
func checkPeerID(p *types.Peer, refTopics []string) error {
topics, ok := p.Metadata["topics"].([]string)
if !ok {
return fmt.Errorf("expected topics in metadata of %v to be a slice of string", p)
}
sort.Strings(topics)
sort.Strings(refTopics)
if !reflect.DeepEqual(topics, refTopics) {
return fmt.Errorf("topics %v does not match reference topics %v", topics, refTopics)
}
return nil
}