package actor import ( "errors" "testing" "github.com/nspcc-dev/neo-go/pkg/core/transaction" "github.com/nspcc-dev/neo-go/pkg/neorpc/result" "github.com/nspcc-dev/neo-go/pkg/util" "github.com/stretchr/testify/require" ) func TestCalculateValidUntilBlock(t *testing.T) { client, acc := testRPCAndAccount(t) a, err := NewSimple(client, acc) require.NoError(t, err) client.err = errors.New("error") _, err = a.CalculateValidUntilBlock() require.Error(t, err) client.err = nil client.bCount.Store(42) vub, err := a.CalculateValidUntilBlock() require.NoError(t, err) require.Equal(t, uint32(42+7+1), vub) client.version.Protocol.ValidatorsHistory = map[uint32]uint32{ 0: 7, 40: 4, 80: 10, } a, err = NewSimple(client, acc) require.NoError(t, err) vub, err = a.CalculateValidUntilBlock() require.NoError(t, err) require.Equal(t, uint32(42+4+1), vub) client.bCount.Store(101) vub, err = a.CalculateValidUntilBlock() require.NoError(t, err) require.Equal(t, uint32(101+10+1), vub) } func TestMakeUnsigned(t *testing.T) { client, acc := testRPCAndAccount(t) a, err := NewSimple(client, acc) require.NoError(t, err) // Bad parameters. script := []byte{1, 2, 3} _, err = a.MakeUnsignedUncheckedRun(script, -1, nil) require.Error(t, err) _, err = a.MakeUnsignedUncheckedRun([]byte{}, 1, nil) require.Error(t, err) _, err = a.MakeUnsignedUncheckedRun(nil, 1, nil) require.Error(t, err) // RPC error. client.err = errors.New("err") _, err = a.MakeUnsignedUncheckedRun(script, 1, nil) require.Error(t, err) // Good unchecked. client.netFee = 42 client.bCount.Store(100500) client.err = nil tx, err := a.MakeUnsignedUncheckedRun(script, 1, nil) require.NoError(t, err) require.Equal(t, script, tx.Script) require.Equal(t, 1, len(tx.Signers)) require.Equal(t, acc.Contract.ScriptHash(), tx.Signers[0].Account) require.Equal(t, 1, len(tx.Scripts)) require.Equal(t, acc.Contract.Script, tx.Scripts[0].VerificationScript) require.Nil(t, tx.Scripts[0].InvocationScript) // Bad run. client.err = errors.New("") _, err = a.MakeUnsignedRun(script, nil) require.Error(t, err) // Faulted run. client.invRes = &result.Invoke{State: "FAULT", GasConsumed: 3, Script: script} client.err = nil _, err = a.MakeUnsignedRun(script, nil) require.Error(t, err) // Good run. client.invRes = &result.Invoke{State: "HALT", GasConsumed: 3, Script: script} _, err = a.MakeUnsignedRun(script, nil) require.NoError(t, err) // Tuned. opts := Options{ Attributes: []transaction.Attribute{{Type: transaction.HighPriority}}, } a, err = NewTuned(client, a.signers, opts) require.NoError(t, err) tx, err = a.MakeUnsignedRun(script, nil) require.NoError(t, err) require.True(t, tx.HasAttribute(transaction.HighPriority)) } func TestMakeSigned(t *testing.T) { client, acc := testRPCAndAccount(t) a, err := NewSimple(client, acc) require.NoError(t, err) // Bad script. _, err = a.MakeUncheckedRun(nil, 0, nil, nil) require.Error(t, err) // Good, no hook. script := []byte{1, 2, 3} _, err = a.MakeUncheckedRun(script, 0, nil, nil) require.NoError(t, err) // Bad, can't sign because of a hook. _, err = a.MakeUncheckedRun(script, 0, nil, func(t *transaction.Transaction) error { t.Signers = append(t.Signers, transaction.Signer{}) return nil }) require.Error(t, err) // Bad, hook returns an error. _, err = a.MakeUncheckedRun(script, 0, nil, func(t *transaction.Transaction) error { return errors.New("") }) require.Error(t, err) // Good with a hook. tx, err := a.MakeUncheckedRun(script, 0, nil, func(t *transaction.Transaction) error { t.ValidUntilBlock = 777 return nil }) require.NoError(t, err) require.Equal(t, uint32(777), tx.ValidUntilBlock) // Tuned. opts := Options{ Modifier: func(t *transaction.Transaction) error { t.ValidUntilBlock = 888 return nil }, } at, err := NewTuned(client, a.signers, opts) require.NoError(t, err) tx, err = at.MakeUncheckedRun(script, 0, nil, nil) require.NoError(t, err) require.Equal(t, uint32(888), tx.ValidUntilBlock) // Checked // Bad, invocation fails. client.err = errors.New("") _, err = a.MakeTunedRun(script, nil, func(r *result.Invoke, t *transaction.Transaction) error { return nil }) require.Error(t, err) // Bad, hook returns an error. client.err = nil client.invRes = &result.Invoke{State: "HALT", GasConsumed: 3, Script: script} _, err = a.MakeTunedRun(script, nil, func(r *result.Invoke, t *transaction.Transaction) error { return errors.New("") }) require.Error(t, err) // Good, no hook. _, err = a.MakeTunedRun(script, []transaction.Attribute{{Type: transaction.HighPriority}}, nil) require.NoError(t, err) _, err = a.MakeRun(script) require.NoError(t, err) // Bad, invocation returns FAULT. client.invRes = &result.Invoke{State: "FAULT", GasConsumed: 3, Script: script} _, err = a.MakeTunedRun(script, nil, nil) require.Error(t, err) // Good, invocation returns FAULT, but callback ignores it. _, err = a.MakeTunedRun(script, nil, func(r *result.Invoke, t *transaction.Transaction) error { return nil }) require.NoError(t, err) // Good, via call and with a callback. _, err = a.MakeTunedCall(util.Uint160{}, "something", []transaction.Attribute{{Type: transaction.HighPriority}}, func(r *result.Invoke, t *transaction.Transaction) error { return nil }, "param", 1) require.NoError(t, err) // Bad, it still is a FAULT. _, err = a.MakeCall(util.Uint160{}, "method") require.Error(t, err) // Good. client.invRes = &result.Invoke{State: "HALT", GasConsumed: 3, Script: script} _, err = a.MakeCall(util.Uint160{}, "method", 1) require.NoError(t, err) // Tuned. opts = Options{ CheckerModifier: func(r *result.Invoke, t *transaction.Transaction) error { t.ValidUntilBlock = 888 return nil }, } at, err = NewTuned(client, a.signers, opts) require.NoError(t, err) tx, err = at.MakeRun(script) require.NoError(t, err) require.Equal(t, uint32(888), tx.ValidUntilBlock) }