github.com/igggame/nebulas-go@v2.1.0+incompatible/core/access_test.go (about)

     1  // Copyright (C) 2018 go-nebulas authors
     2  //
     3  // This file is part of the go-nebulas library.
     4  //
     5  // the go-nebulas library is free software: you can redistribute it and/or modify
     6  // it under the terms of the GNU General Public License as published by
     7  // the Free Software Foundation, either version 3 of the License, or
     8  // (at your option) any later version.
     9  //
    10  // the go-nebulas library is distributed in the hope that it will be useful,
    11  // but WITHOUT ANY WARRANTY; without even the implied warranty of
    12  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    13  // GNU General Public License for more details.
    14  //
    15  // You should have received a copy of the GNU General Public License
    16  // along with the go-nebulas library.  If not, see <http://www.gnu.org/licenses/>.
    17  //
    18  
    19  package core
    20  
    21  import (
    22  	"strings"
    23  	"testing"
    24  
    25  	"github.com/nebulasio/go-nebulas/core/pb"
    26  	"github.com/stretchr/testify/assert"
    27  )
    28  
    29  func TestNewAccess(t *testing.T) {
    30  	tests := []struct {
    31  		name    string
    32  		path    string
    33  		wantErr bool
    34  	}{
    35  		{
    36  			name:    "no path",
    37  			path:    "",
    38  			wantErr: false,
    39  		},
    40  		{
    41  			name:    "invalid path",
    42  			path:    "invalid path",
    43  			wantErr: true,
    44  		},
    45  	}
    46  	for _, tt := range tests {
    47  		t.Run(tt.name, func(t *testing.T) {
    48  			access, err := NewAccess(tt.path)
    49  			assert.Equal(t, tt.wantErr, err != nil)
    50  			if err == nil {
    51  				assert.NotNil(t, access)
    52  			}
    53  		})
    54  	}
    55  }
    56  
    57  func TestAccess_CheckTransaction(t *testing.T) {
    58  	access := &Access{
    59  		access: &corepb.Access{
    60  			Blacklist: &corepb.Blacklist{
    61  				From: []string{
    62  					"n1FF1nz6tarkDVwWQkMnnwFPuPKUaQTdptE",
    63  					"n1GmkKH6nBMw4rrjt16RrJ9WcgvKUtAZP1s",
    64  					"n1H4MYms9F55ehcvygwWE71J8tJC4CRr2so",
    65  				},
    66  				To: []string{
    67  					"n1JAy4X6KKLCNiTd7MWMRsVBjgdVq5WCCpf",
    68  					"n1LkDi2gGMqPrjYcczUiweyP4RxTB6Go1qS",
    69  					"n1LmP9K8pFF33fgdgHZonFEMsqZinJ4EUqk",
    70  				},
    71  				Contracts: []*corepb.Contract{
    72  					{
    73  						Address: "n1UM7z6MqnGyKEPvUpwrfxZpM1eB7UpzmLJ",
    74  						Functions: []string{
    75  							"transferEvent",
    76  							"approveEvent",
    77  						},
    78  						Keywords: []string{
    79  							"random",
    80  						},
    81  					},
    82  				},
    83  			},
    84  		},
    85  	}
    86  
    87  	tests := []struct {
    88  		name     string
    89  		from     string
    90  		to       string
    91  		function string
    92  		contract string
    93  		err      error
    94  	}{
    95  		{
    96  			name: "normal",
    97  			from: mockAddress().String(),
    98  			to:   mockAddress().String(),
    99  			err:  nil,
   100  		},
   101  		{
   102  			name: "from in blacklist",
   103  			from: "n1FF1nz6tarkDVwWQkMnnwFPuPKUaQTdptE",
   104  			to:   mockAddress().String(),
   105  			err:  ErrRestrictedFromAddress,
   106  		},
   107  		{
   108  			name: "to in blacklist",
   109  			from: mockAddress().String(),
   110  			to:   "n1JAy4X6KKLCNiTd7MWMRsVBjgdVq5WCCpf",
   111  			err:  ErrRestrictedToAddress,
   112  		},
   113  		{
   114  			name:     "func in blacklist but address not in",
   115  			from:     mockAddress().String(),
   116  			to:       mockAddress().String(),
   117  			function: "transferEvent",
   118  			err:      nil,
   119  		},
   120  		{
   121  			name:     "func and from address in blacklist",
   122  			from:     "n1UM7z6MqnGyKEPvUpwrfxZpM1eB7UpzmLJ",
   123  			to:       mockAddress().String(),
   124  			function: "transferEvent",
   125  			err:      nil,
   126  		},
   127  		{
   128  			name:     "func and to address in blacklist",
   129  			from:     mockAddress().String(),
   130  			to:       "n1UM7z6MqnGyKEPvUpwrfxZpM1eB7UpzmLJ",
   131  			function: "transferEvent",
   132  			err:      ErrUnsupportedFunction,
   133  		},
   134  		{
   135  			name:     "address in blacklist but func not in",
   136  			from:     mockAddress().String(),
   137  			to:       "n1UM7z6MqnGyKEPvUpwrfxZpM1eB7UpzmLJ",
   138  			function: "transferEventTest",
   139  			err:      nil,
   140  		},
   141  		{
   142  			name:     "keyword in blacklist",
   143  			from:     mockAddress().String(),
   144  			to:       mockAddress().String(),
   145  			contract: "random",
   146  			err:      ErrUnsupportedKeyword,
   147  		},
   148  		{
   149  			name:     "keyword not in blacklist",
   150  			from:     mockAddress().String(),
   151  			to:       mockAddress().String(),
   152  			contract: "ran",
   153  			err:      nil,
   154  		},
   155  	}
   156  
   157  	for _, tt := range tests {
   158  		t.Run(tt.name, func(t *testing.T) {
   159  			payloadType := TxPayloadBinaryType
   160  			payloadBytes := []byte{}
   161  			if tt.function != "" {
   162  				payloadType = TxPayloadCallType
   163  				payload, _ := NewCallPayload(tt.function, "")
   164  				payloadBytes, _ = payload.ToBytes()
   165  			}
   166  			if tt.contract != "" {
   167  				payloadType = TxPayloadDeployType
   168  				payload, _ := NewDeployPayload(tt.contract, "js", "")
   169  				payloadBytes, _ = payload.ToBytes()
   170  			}
   171  			tx := mockTransaction(100, 1, payloadType, payloadBytes)
   172  			tx.from, _ = AddressParse(tt.from)
   173  			tx.to, _ = AddressParse(tt.to)
   174  
   175  			err := access.CheckTransaction(tx)
   176  			if tt.err != ErrUnsupportedKeyword {
   177  				assert.Equal(t, tt.err, err, tt.name)
   178  			} else {
   179  				assert.True(t, strings.HasPrefix(err.Error(), tt.err.Error()))
   180  			}
   181  		})
   182  	}
   183  
   184  }
   185  
   186  func TestAccess_CheckNRC20Transaction(t *testing.T) {
   187  	nrc20Contract := "n1qGqcvPWE45VGYZYNPd9VgA1KAAV1sRqfo"
   188  	access := &Access{
   189  		access: &corepb.Access{
   190  			Nrc20List: &corepb.Nrc20List{
   191  				Contracts: []string{nrc20Contract},
   192  			},
   193  		},
   194  	}
   195  
   196  	tests := []struct {
   197  		name     string
   198  		to       string
   199  		function string
   200  		args     string
   201  		err      error
   202  	}{
   203  		{
   204  			name: "normal not nrc20",
   205  			to:   mockAddress().String(),
   206  			err:  nil,
   207  		},
   208  		{
   209  			name:     "nrc20 func not check",
   210  			to:       nrc20Contract,
   211  			function: "balanceOf",
   212  			err:      nil,
   213  		},
   214  		{
   215  			name:     "transfer args err",
   216  			to:       nrc20Contract,
   217  			function: NRC20FuncTransfer,
   218  			args:     "[\"n1qGqcvPWE45VGYZYNPd9VgA1KAAV1sRqfo\",0]",
   219  			err:      ErrNrc20ArgsCheckFailed,
   220  		},
   221  		{
   222  			name:     "transfer addr err",
   223  			to:       nrc20Contract,
   224  			function: NRC20FuncTransfer,
   225  			args:     "[\"1\",\"0\"]",
   226  			err:      ErrNrc20AddressCheckFailed,
   227  		},
   228  		{
   229  			name:     "transfer value err",
   230  			to:       nrc20Contract,
   231  			function: NRC20FuncTransfer,
   232  			args:     "[\"n1qGqcvPWE45VGYZYNPd9VgA1KAAV1sRqfo\",\"0.1\"]",
   233  			err:      ErrNrc20ValueCheckFailed,
   234  		},
   235  		{
   236  			name:     "transfer value err",
   237  			to:       nrc20Contract,
   238  			function: NRC20FuncTransfer,
   239  			args:     "[\"n1qGqcvPWE45VGYZYNPd9VgA1KAAV1sRqfo\",\"-1\"]",
   240  			err:      ErrNrc20ValueCheckFailed,
   241  		},
   242  		{
   243  			name:     "transfer value err",
   244  			to:       nrc20Contract,
   245  			function: NRC20FuncTransfer,
   246  			args:     "[\"n1qGqcvPWE45VGYZYNPd9VgA1KAAV1sRqfo\",\"1e2\"]",
   247  			err:      ErrNrc20ValueCheckFailed,
   248  		},
   249  		{
   250  			name:     "transfer success",
   251  			to:       nrc20Contract,
   252  			function: NRC20FuncTransfer,
   253  			args:     "[\"n1qGqcvPWE45VGYZYNPd9VgA1KAAV1sRqfo\",\"1\"]",
   254  			err:      nil,
   255  		},
   256  		{
   257  			name:     "transferFrom addr err",
   258  			to:       nrc20Contract,
   259  			function: NRC20FuncTransferFrom,
   260  			args:     "[\"1\",\"0\",\"0\"]",
   261  			err:      ErrNrc20AddressCheckFailed,
   262  		},
   263  		{
   264  			name:     "transferFrom value err",
   265  			to:       nrc20Contract,
   266  			function: NRC20FuncTransferFrom,
   267  			args:     "[\"n1qGqcvPWE45VGYZYNPd9VgA1KAAV1sRqfo\",\"0\",\"0.1\"]",
   268  			err:      ErrNrc20ValueCheckFailed,
   269  		},
   270  		{
   271  			name:     "transferFrom value err",
   272  			to:       nrc20Contract,
   273  			function: NRC20FuncTransferFrom,
   274  			args:     "[\"n1qGqcvPWE45VGYZYNPd9VgA1KAAV1sRqfo\",\"0\",\"-1\"]",
   275  			err:      ErrNrc20ValueCheckFailed,
   276  		},
   277  		{
   278  			name:     "transferFrom value err",
   279  			to:       nrc20Contract,
   280  			function: NRC20FuncTransferFrom,
   281  			args:     "[\"n1qGqcvPWE45VGYZYNPd9VgA1KAAV1sRqfo\",\"0\",\"1e2\"]",
   282  			err:      ErrNrc20ValueCheckFailed,
   283  		},
   284  		{
   285  			name:     "transferFrom success",
   286  			to:       nrc20Contract,
   287  			function: NRC20FuncTransferFrom,
   288  			args:     "[\"n1qGqcvPWE45VGYZYNPd9VgA1KAAV1sRqfo\",\"0\",\"0\"]",
   289  			err:      nil,
   290  		},
   291  		{
   292  			name:     "approve value err",
   293  			to:       nrc20Contract,
   294  			function: NRC20FuncApprove,
   295  			args:     "[\"n1qGqcvPWE45VGYZYNPd9VgA1KAAV1sRqfo\",\"0\",\"1e2\"]",
   296  			err:      ErrNrc20ValueCheckFailed,
   297  		},
   298  		{
   299  			name:     "approve",
   300  			to:       nrc20Contract,
   301  			function: NRC20FuncApprove,
   302  			args:     "[\"n1qGqcvPWE45VGYZYNPd9VgA1KAAV1sRqfo\",\"0\",\"0\"]",
   303  			err:      nil,
   304  		},
   305  	}
   306  
   307  	for _, tt := range tests {
   308  		t.Run(tt.name, func(t *testing.T) {
   309  			payloadType := TxPayloadBinaryType
   310  			payloadBytes := []byte{}
   311  			if tt.function != "" {
   312  				payloadType = TxPayloadCallType
   313  				payload, _ := NewCallPayload(tt.function, tt.args)
   314  				payloadBytes, _ = payload.ToBytes()
   315  			}
   316  			tx := mockTransaction(100, 1, payloadType, payloadBytes)
   317  			tx.to, _ = AddressParse(tt.to)
   318  
   319  			err := access.CheckTransaction(tx)
   320  			assert.Equal(t, tt.err, err, tt.name)
   321  		})
   322  	}
   323  
   324  }