mirror of
https://github.com/nspcc-dev/neo-go.git
synced 2024-11-29 23:33:37 +00:00
cf4d3b25d7
``` pkg/smartcontract/rpcbinding/binding.go:523:2 exhaustive missing cases in switch of type smartcontract.ParamType: smartcontract .UnknownType pkg/smartcontract/rpcbinding/binding.go:572:2 exhaustive missing cases in switch of type smartcontract.ParamType: smartcontract .UnknownType pkg/smartcontract/rpcbinding/binding.go:862:2 exhaustive missing cases in switch of type smartcontract.ParamType: smartcontract .UnknownType, smartcontract.AnyType, smartcontract.BoolType, smartcontract.IntegerType, smartcontract.ByteArrayType, smartcontract .Hash160Type, smartcontract.Hash256Type, smartcontract.SignatureType, smartcontract.InteropInterfaceType, smartcontract.VoidType pkg/smartcontract/param_type.go:165:2 exhaustive missing cases in switch of type smartcontract.ParamType: smartcontract .UnknownType pkg/smartcontract/manifest/permission.go:103:2 exhaustive missing cases in switch of type manifest.PermissionType: manifest .PermissionWildcard pkg/services/notary/core_test.go:223:4 exhaustive missing cases in switch of type notary.RequestType: notary.Contract pkg/services/notary/core_test.go:292:4 exhaustive missing cases in switch of type notary.RequestType: notary.Contract pkg/services/oracle/jsonpath/jsonpath.go:62:3 exhaustive missing cases in switch of type jsonpath.pathTokenType: jsonpath.pathInvalid, jsonpath.pathRoot, jsonpath.pathRightBracket, jsonpath.pathAsterisk, jsonpath.pathComma, jsonpath.pathColon, jsonpath.pathIdentifier, jsonpath.pathString, jsonpath.pathNumber pkg/services/rpcsrv/server.go:2740:3 exhaustive missing cases in switch of type neorpc.EventID: neorpc.InvalidEventID, neorpc .MissedEventID pkg/services/rpcsrv/server.go:2804:2 exhaustive missing cases in switch of type neorpc.EventID: neorpc.InvalidEventID, neorpc .MissedEventID pkg/services/rpcsrv/server.go:2864:2 exhaustive missing cases in switch of type neorpc.EventID: neorpc.InvalidEventID, neorpc .MissedEventID pkg/vm/contract_checks.go:153:3 exhaustive missing cases in switch of type opcode.Opcode: opcode.PUSHINT8, opcode .PUSHINT16, opcode.PUSHINT32, opcode.PUSHINT64, opcode.PUSHINT128, opcode.PUSHINT256, opcode.PUSHT, opcode.PUSHF, opcode.PUSHNULL, opcode .PUSHDATA1, opcode.PUSHDATA2, opcode.PUSHDATA4, opcode.PUSHM1, opcode .PUSH0, opcode.PUSH1, opcode.PUSH2, opcode.PUSH3, opcode.PUSH4, opcode .PUSH5, opcode.PUSH6, opcode.PUSH7, opcode.PUSH8, opcode.PUSH9, opcode .PUSH10, opcode.PUSH11, opcode.PUSH12, opcode.PUSH13, opcode.PUSH14, opcode.PUSH15, opcode.PUSH16, opcode.NOP, opcode.CALLA, opcode.CALLT, opcode.ABORT, opcode.ASSERT, opcode.THROW, opcode.ENDFINALLY, opcode .RET, opcode.SYSCALL, opcode.DEPTH, opcode.DROP, opcode.NIP, opcode .XDROP, opcode.CLEAR, opcode.DUP, opcode.OVER, opcode.PICK, opcode.TUCK, opcode.SWAP, opcode.ROT, opcode.ROLL, opcode.REVERSE3, opcode.REVERSE4, opcode.REVERSEN, opcode.INITSSLOT, opcode.INITSLOT, opcode.LDSFLD0, opcode.LDSFLD1, opcode.LDSFLD2, opcode.LDSFLD3, opcode.LDSFLD4, opcode .LDSFLD5, opcode.LDSFLD6, opcode.LDSFLD, opcode.STSFLD0, opcode .STSFLD1, opcode.STSFLD2, opcode.STSFLD3, opcode.STSFLD4, opcode .STSFLD5, opcode.STSFLD6, opcode.STSFLD, opcode.LDLOC0, opcode.LDLOC1, opcode.LDLOC2, opcode.LDLOC3, opcode.LDLOC4, opcode.LDLOC5, opcode .LDLOC6, opcode.LDLOC, opcode.STLOC0, opcode.STLOC1, opcode.STLOC2, opcode.STLOC3, opcode.STLOC4, opcode.STLOC5, opcode.STLOC6, opcode .STLOC, opcode.LDARG0, opcode.LDARG1, opcode.LDARG2, opcode.LDARG3, opcode.LDARG4, opcode.LDARG5, opcode.LDARG6, opcode.LDARG, opcode .STARG0, opcode.STARG1, opcode.STARG2, opcode.STARG3, opcode.STARG4, opcode.STARG5, opcode.STARG6, opcode.STARG, opcode.NEWBUFFER, opcode .MEMCPY, opcode.CAT, opcode.SUBSTR, opcode.LEFT, opcode.RIGHT, opcode .INVERT, opcode.AND, opcode.OR, opcode.XOR, opcode.EQUAL, opcode .NOTEQUAL, opcode.SIGN, opcode.ABS, opcode.NEGATE, opcode.INC, opcode .DEC, opcode.ADD, opcode.SUB, opcode.MUL, opcode.DIV, opcode.MOD, opcode.POW, opcode.SQRT, opcode.MODMUL, opcode.MODPOW, opcode.SHL, opcode.SHR, opcode.NOT, opcode.BOOLAND, opcode.BOOLOR, opcode.NZ, opcode.NUMEQUAL, opcode.NUMNOTEQUAL, opcode.LT, opcode.LE, opcode.GT, opcode.GE, opcode.MIN, opcode.MAX, opcode.WITHIN, opcode.PACKMAP, opcode.PACKSTRUCT, opcode.PACK, opcode.UNPACK, opcode.NEWARRAY0, opcode.NEWARRAY, opcode.NEWSTRUCT0, opcode.NEWSTRUCT, opcode.NEWMAP, opcode.SIZE, opcode.HASKEY, opcode.KEYS, opcode.VALUES, opcode .PICKITEM, opcode.APPEND, opcode.SETITEM, opcode.REVERSEITEMS, opcode.REMOVE, opcode.CLEARITEMS, opcode.POPITEM, opcode.ISNULL, opcode.ABORTMSG, opcode.ASSERTMSG pkg/vm/vm.go:912:3 exhaustive missing cases in switch of type opcode.Opcode: opcode.PUSHINT8, opcode .PUSHINT16, opcode.PUSHINT32, opcode.PUSHINT64, opcode.PUSHINT128, opcode.PUSHINT256, opcode.PUSHT, opcode.PUSHF, opcode.PUSHA, opcode .PUSHNULL, opcode.PUSHDATA1, opcode.PUSHDATA2, opcode.PUSHDATA4, opcode .PUSHM1, opcode.PUSH0, opcode.PUSH1, opcode.PUSH2, opcode.PUSH3, opcode .PUSH4, opcode.PUSH5, opcode.PUSH6, opcode.PUSH7, opcode.PUSH8, opcode .PUSH9, opcode.PUSH10, opcode.PUSH11, opcode.PUSH12, opcode.PUSH13, opcode.PUSH14, opcode.PUSH15, opcode.PUSH16, opcode.NOP, opcode.JMP, opcode.JMPL, opcode.JMPIF, opcode.JMPIFL, opcode.JMPIFNOT, opcode .JMPIFNOTL, opcode.JMPEQ, opcode.JMPEQL, opcode.JMPNE, opcode.JMPNEL, opcode.JMPGT, opcode.JMPGTL, opcode.JMPGE, opcode.JMPGEL, opcode.JMPLT, opcode.JMPLTL, opcode.JMPLE, opcode.JMPLEL, opcode.CALL, opcode.CALLL, opcode.CALLA, opcode.CALLT, opcode.ABORT, opcode.ASSERT, opcode.THROW, opcode.TRY, opcode.TRYL, opcode.ENDTRY, opcode.ENDTRYL, opcode .ENDFINALLY, opcode.RET, opcode.SYSCALL, opcode.DEPTH, opcode.DROP, opcode.NIP, opcode.XDROP, opcode.CLEAR, opcode.DUP, opcode.OVER, opcode .PICK, opcode.TUCK, opcode.SWAP, opcode.ROT, opcode.ROLL, opcode .REVERSE3, opcode.INITSSLOT, opcode.INITSLOT, opcode.LDSFLD0, opcode .LDSFLD1, opcode.LDSFLD2, opcode.LDSFLD3, opcode.LDSFLD4, opcode .LDSFLD5, opcode.LDSFLD6, opcode.LDSFLD, opcode.STSFLD0, opcode.STSFLD1, opcode.STSFLD2, opcode.STSFLD3, opcode.STSFLD4, opcode.STSFLD5, opcode .STSFLD6, opcode.STSFLD, opcode.LDLOC0, opcode.LDLOC1, opcode.LDLOC2, opcode.LDLOC3, opcode.LDLOC4, opcode.LDLOC5, opcode.LDLOC6, opcode .LDLOC, opcode.STLOC0, opcode.STLOC1, opcode.STLOC2, opcode.STLOC3, opcode.STLOC4, opcode.STLOC5, opcode.STLOC6, opcode.STLOC, opcode .LDARG0, opcode.LDARG1, opcode.LDARG2, opcode.LDARG3, opcode.LDARG4, opcode.LDARG5, opcode.LDARG6, opcode.LDARG, opcode.STARG0, opcode .STARG1, opcode.STARG2, opcode.STARG3, opcode.STARG4, opcode.STARG5, opcode.STARG6, opcode.STARG, opcode.NEWBUFFER, opcode.MEMCPY, opcode .CAT, opcode.SUBSTR, opcode.LEFT, opcode.RIGHT, opcode.INVERT, opcode .AND, opcode.OR, opcode.XOR, opcode.EQUAL, opcode.NOTEQUAL, opcode .SIGN, opcode.ABS, opcode.NEGATE, opcode.INC, opcode.DEC, opcode.ADD, opcode.SUB, opcode.MUL, opcode.DIV, opcode.MOD, opcode.POW, opcode .SQRT, opcode.MODMUL, opcode.MODPOW, opcode.SHL, opcode.SHR, opcode .NOT, opcode.BOOLAND, opcode.BOOLOR, opcode.NZ, opcode.NUMEQUAL, opcode .NUMNOTEQUAL, opcode.LT, opcode.LE, opcode.GT, opcode.GE, opcode.MIN, opcode.MAX, opcode.WITHIN, opcode.PACKMAP, opcode.PACKSTRUCT, opcode .PACK, opcode.UNPACK, opcode.NEWARRAY0, opcode.NEWARRAY, opcode .NEWARRAYT, opcode.NEWSTRUCT0, opcode.NEWSTRUCT, opcode.NEWMAP, opcode .SIZE, opcode.HASKEY, opcode.KEYS, opcode.VALUES, opcode.PICKITEM, opcode.APPEND, opcode.SETITEM, opcode.REVERSEITEMS, opcode.REMOVE, opcode.CLEARITEMS, opcode.POPITEM, opcode.ISNULL, opcode.ISTYPE, opcode .CONVERT, opcode.ABORTMSG, opcode.ASSERTMSG pkg/vm/vm.go:1116:4 exhaustive missing cases in switch of type opcode.Opcode: opcode.PUSHINT8, opcode .PUSHINT16, opcode.PUSHINT32, opcode.PUSHINT64, opcode.PUSHINT128, opcode.PUSHINT256, opcode.PUSHT, opcode.PUSHF, opcode.PUSHA, opcode .PUSHNULL, opcode.PUSHDATA1, opcode.PUSHDATA2, opcode.PUSHDATA4, opcode .PUSHM1, opcode.PUSH0, opcode.PUSH1, opcode.PUSH2, opcode.PUSH3, opcode .PUSH4, opcode.PUSH5, opcode.PUSH6, opcode.PUSH7, opcode.PUSH8, opcode .PUSH9, opcode.PUSH10, opcode.PUSH11, opcode.PUSH12, opcode.PUSH13, opcode.PUSH14, opcode.PUSH15, opcode.PUSH16, opcode.NOP, opcode.JMP, opcode.JMPL, opcode.JMPIF, opcode.JMPIFL, opcode.JMPIFNOT, opcode .JMPIFNOTL, opcode.JMPEQ, opcode.JMPEQL, opcode.JMPNE, opcode.JMPNEL, opcode.JMPGT, opcode.JMPGTL, opcode.JMPGE, opcode.JMPGEL, opcode.JMPLT, opcode.JMPLTL, opcode.JMPLE, opcode.JMPLEL, opcode.CALL, opcode.CALLL, opcode.CALLA, opcode.CALLT, opcode.ABORT, opcode.ASSERT, opcode.THROW, opcode.TRY, opcode.TRYL, opcode.ENDTRY, opcode.ENDTRYL, opcode .ENDFINALLY, opcode.RET, opcode.SYSCALL, opcode.DEPTH, opcode.DROP, opcode.NIP, opcode.XDROP, opcode.CLEAR, opcode.DUP, opcode.OVER, opcode .PICK, opcode.TUCK, opcode.SWAP, opcode.ROT, opcode.ROLL, opcode .REVERSE3, opcode.REVERSE4, opcode.REVERSEN, opcode.INITSSLOT, opcode .INITSLOT, opcode.LDSFLD0, opcode.LDSFLD1, opcode.LDSFLD2, opcode .LDSFLD3, opcode.LDSFLD4, opcode.LDSFLD5, opcode.LDSFLD6, opcode.LDSFLD, opcode.STSFLD0, opcode.STSFLD1, opcode.STSFLD2, opcode.STSFLD3, opcode .STSFLD4, opcode.STSFLD5, opcode.STSFLD6, opcode.STSFLD, opcode.LDLOC0, opcode.LDLOC1, opcode.LDLOC2, opcode.LDLOC3, opcode.LDLOC4, opcode .LDLOC5, opcode.LDLOC6, opcode.LDLOC, opcode.STLOC0, opcode.STLOC1, opcode.STLOC2, opcode.STLOC3, opcode.STLOC4, opcode.STLOC5, opcode .STLOC6, opcode.STLOC, opcode.LDARG0, opcode.LDARG1, opcode.LDARG2, opcode.LDARG3, opcode.LDARG4, opcode.LDARG5, opcode.LDARG6, opcode .LDARG, opcode.STARG0, opcode.STARG1, opcode.STARG2, opcode.STARG3, opcode.STARG4, opcode.STARG5, opcode.STARG6, opcode.STARG, opcode .NEWBUFFER, opcode.MEMCPY, opcode.CAT, opcode.SUBSTR, opcode.LEFT, opcode.RIGHT, opcode.INVERT, opcode.AND, opcode.OR, opcode.XOR, opcode .EQUAL, opcode.NOTEQUAL, opcode.SIGN, opcode.ABS, opcode.NEGATE, opcode.INC, opcode.DEC, opcode.ADD, opcode.SUB, opcode.MUL, opcode .DIV, opcode.MOD, opcode.POW, opcode.SQRT, opcode.MODMUL, opcode .MODPOW, opcode.SHL, opcode.SHR, opcode.NOT, opcode.BOOLAND, opcode .BOOLOR, opcode.NZ, opcode.NUMEQUAL, opcode.NUMNOTEQUAL, opcode.MIN, opcode.MAX, opcode.WITHIN, opcode.PACKMAP, opcode.PACKSTRUCT, opcode .PACK, opcode.UNPACK, opcode.NEWARRAY0, opcode.NEWARRAY, opcode .NEWARRAYT, opcode.NEWSTRUCT0, opcode.NEWSTRUCT, opcode.NEWMAP, opcode .SIZE, opcode.HASKEY, opcode.KEYS, opcode.VALUES, opcode.PICKITEM, opcode.APPEND, opcode.SETITEM, opcode.REVERSEITEMS, opcode.REMOVE, opcode.CLEARITEMS, opcode.POPITEM, opcode.ISNULL, opcode.ISTYPE, opcode.CONVERT, opcode.ABORTMSG, opcode.ASSERTMSG pkg/compiler/codegen.go:944:5 exhaustive missing cases in switch of type smartcontract.ParamType: smartcontract .UnknownType, smartcontract.AnyType, smartcontract.BoolType, smartcontract.IntegerType, smartcontract.ByteArrayType, smartcontract .StringType, smartcontract.PublicKeyType, smartcontract.SignatureType, smartcontract.ArrayType, smartcontract.MapType, smartcontract .InteropInterfaceType, smartcontract.VoidType pkg/compiler/codegen.go:1221:3 exhaustive missing cases in switch of type token.Token: token.ILLEGAL, token.EOF, token .COMMENT, token.IDENT, token.INT, token.FLOAT, token.IMAG, token.CHAR, token.STRING, token.ADD, token.SUB, token.MUL, token.QUO, token.REM, token.AND, token.OR, token.XOR, token.SHL, token.SHR, token.AND_NOT, token.ADD_ASSIGN, token.SUB_ASSIGN, token.MUL_ASSIGN, token.QUO_ASSIGN, token.REM_ASSIGN, token.AND_ASSIGN, token.OR_ASSIGN, token.XOR_ASSIGN, token.SHL_ASSIGN, token.SHR_ASSIGN, token.AND_NOT_ASSIGN, token.LAND, token.LOR, token.ARROW, token.INC, token.DEC, token.EQL, token.LSS, token.GTR, token.ASSIGN, token.NOT, token.NEQ, token.LEQ, token.GEQ, token.DEFINE, token.ELLIPSIS, token.LPAREN, token.LBRACK, token.LBRACE, token.COMMA, token.PERIOD, token.RPAREN, token.RBRACK, token.RBRACE, token.SEMICOLON, token.COLON, token.CASE, token.CHAN, token.CONST, token .DEFAULT, token.DEFER, token.ELSE, token.FALLTHROUGH, token.FOR, token .FUNC, token.GO, token.GOTO, token.IF, token.IMPORT, token.INTERFACE, token.MAP, token.PACKAGE, token.RANGE, token.RETURN, token.SELECT, token .STRUCT, token.SWITCH, token.TYPE, token.VAR, token.TILDE pkg/compiler/codegen.go:1709:2 exhaustive missing cases in switch of type token.Token: token.ILLEGAL, token.EOF, token .COMMENT, token.IDENT, token.INT, token.FLOAT, token.IMAG, token.CHAR, token.STRING, token.ADD, token.SUB, token.MUL, token.QUO, token.REM, token.AND, token.OR, token.XOR, token.SHL, token.SHR, token.AND_NOT, token.ADD_ASSIGN, token.SUB_ASSIGN, token.MUL_ASSIGN, token.QUO_ASSIGN, token.REM_ASSIGN, token.AND_ASSIGN, token.OR_ASSIGN, token.XOR_ASSIGN, token.SHL_ASSIGN, token.SHR_ASSIGN, token.AND_NOT_ASSIGN, token.LAND, token.LOR, token.ARROW, token.INC, token.DEC, token.ASSIGN, token.NOT, token.DEFINE, token.ELLIPSIS, token.LPAREN, token.LBRACK, token.LBRACE, token.COMMA, token.PERIOD, token.RPAREN, token.RBRACK, token.RBRACE, token.SEMICOLON, token.COLON, token.BREAK, token.CASE, token.CHAN, token .CONST, token.CONTINUE, token.DEFAULT, token.DEFER, token.ELSE, token .FALLTHROUGH, token.FOR, token.FUNC, token.GO, token.GOTO, token.IF, token.IMPORT, token.INTERFACE, token.MAP, token.PACKAGE, token.RANGE, token.RETURN, token.SELECT, token.STRUCT, token.SWITCH, token.TYPE, token.VAR, token.TILDE pkg/compiler/codegen.go:2353:3 exhaustive missing cases in switch of type opcode.Opcode: opcode.PUSHINT8, opcode .PUSHINT16, opcode.PUSHINT32, opcode.PUSHINT64, opcode.PUSHINT128, opcode.PUSHINT256, opcode.PUSHT, opcode.PUSHF, opcode.PUSHNULL, opcode .PUSHDATA1, opcode.PUSHDATA2, opcode.PUSHDATA4, opcode.PUSHM1, opcode .PUSH0, opcode.PUSH1, opcode.PUSH2, opcode.PUSH3, opcode.PUSH4, opcode .PUSH5, opcode.PUSH6, opcode.PUSH7, opcode.PUSH8, opcode.PUSH9, opcode .PUSH10, opcode.PUSH11, opcode.PUSH12, opcode.PUSH13, opcode.PUSH14, opcode.PUSH15, opcode.PUSH16, opcode.NOP, opcode.CALLA, opcode.CALLT, opcode.ABORT, opcode.ASSERT, opcode.THROW, opcode.TRY, opcode.ENDTRY, opcode.ENDFINALLY, opcode.RET, opcode.SYSCALL, opcode.DEPTH, opcode .DROP, opcode.NIP, opcode.XDROP, opcode.CLEAR, opcode.DUP, opcode.OVER, opcode.PICK, opcode.TUCK, opcode.SWAP, opcode.ROT, opcode.ROLL, opcode .REVERSE3, opcode.REVERSE4, opcode.REVERSEN, opcode.INITSSLOT, opcode .LDSFLD0, opcode.LDSFLD1, opcode.LDSFLD2, opcode.LDSFLD3, opcode .LDSFLD4, opcode.LDSFLD5, opcode.LDSFLD6, opcode.LDSFLD, opcode.STSFLD0, opcode.STSFLD1, opcode.STSFLD2, opcode.STSFLD3, opcode.STSFLD4, opcode .STSFLD5, opcode.STSFLD6, opcode.STSFLD, opcode.LDLOC0, opcode.LDLOC1, opcode.LDLOC2, opcode.LDLOC3, opcode.LDLOC4, opcode.LDLOC5, opcode .LDLOC6, opcode.LDLOC, opcode.STLOC0, opcode.STLOC1, opcode.STLOC2, opcode.STLOC3, opcode.STLOC4, opcode.STLOC5, opcode.STLOC6, opcode .STLOC, opcode.LDARG0, opcode.LDARG1, opcode.LDARG2, opcode.LDARG3, opcode.LDARG4, opcode.LDARG5, opcode.LDARG6, opcode.LDARG, opcode .STARG0, opcode.STARG1, opcode.STARG2, opcode.STARG3, opcode.STARG4, opcode.STARG5, opcode.STARG6, opcode.STARG, opcode.NEWBUFFER, opcode .MEMCPY, opcode.CAT, opcode.SUBSTR, opcode.LEFT, opcode.RIGHT, opcode .INVERT, opcode.AND, opcode.OR, opcode.XOR, opcode.EQUAL, opcode .NOTEQUAL, opcode.SIGN, opcode.ABS, opcode.NEGATE, opcode.INC, opcode .DEC, opcode.ADD, opcode.SUB, opcode.MUL, opcode.DIV, opcode.MOD, opcode.POW, opcode.SQRT, opcode.MODMUL, opcode.MODPOW, opcode.SHL, opcode.SHR, opcode.NOT, opcode.BOOLAND, opcode.BOOLOR, opcode.NZ, opcode.NUMEQUAL, opcode.NUMNOTEQUAL, opcode.LT, opcode.LE, opcode.GT, opcode.GE, opcode.MIN, opcode.MAX, opcode.WITHIN, opcode.PACKMAP, opcode.PACKSTRUCT, opcode.PACK, opcode.UNPACK, opcode.NEWARRAY0, opcode .NEWARRAY, opcode.NEWARRAYT, opcode.NEWSTRUCT0, opcode.NEWSTRUCT, opcode.NEWMAP, opcode.SIZE, opcode.HASKEY, opcode.KEYS, opcode.VALUES, opcode.PICKITEM, opcode.APPEND, opcode.SETITEM, opcode.REVERSEITEMS, opcode.REMOVE, opcode.CLEARITEMS, opcode.POPITEM, opcode.ISNULL, opcode .ISTYPE, opcode.CONVERT, opcode.ABORTMSG, opcode.ASSERTMSG pkg/compiler/codegen.go:2474:3 exhaustive missing cases in switch of type opcode.Opcode: opcode.PUSHINT8, opcode .PUSHINT16, opcode.PUSHINT32, opcode.PUSHINT64, opcode.PUSHINT128, opcode.PUSHINT256, opcode.PUSHT, opcode.PUSHF, opcode.PUSHNULL, opcode .PUSHDATA1, opcode.PUSHDATA2, opcode.PUSHDATA4, opcode.PUSHM1, opcode .PUSH0, opcode.PUSH1, opcode.PUSH2, opcode.PUSH3, opcode.PUSH4, opcode .PUSH5, opcode.PUSH6, opcode.PUSH7, opcode.PUSH8, opcode.PUSH9, opcode .PUSH10, opcode.PUSH11, opcode.PUSH12, opcode.PUSH13, opcode.PUSH14, opcode.PUSH15, opcode.PUSH16, opcode.NOP, opcode.CALLA, opcode.CALLT, opcode.ABORT, opcode.ASSERT, opcode.THROW, opcode.ENDFINALLY, opcode .RET, opcode.SYSCALL, opcode.DEPTH, opcode.DROP, opcode.NIP, opcode .XDROP, opcode.CLEAR, opcode.DUP, opcode.OVER, opcode.PICK, opcode.TUCK, opcode.SWAP, opcode.ROT, opcode.ROLL, opcode.REVERSE3, opcode.REVERSE4, opcode.REVERSEN, opcode.INITSSLOT, opcode.INITSLOT, opcode.LDSFLD0, opcode.LDSFLD1, opcode.LDSFLD2, opcode.LDSFLD3, opcode.LDSFLD4, opcode .LDSFLD5, opcode.LDSFLD6, opcode.LDSFLD, opcode.STSFLD0, opcode .STSFLD1, opcode.STSFLD2, opcode.STSFLD3, opcode.STSFLD4, opcode .STSFLD5, opcode.STSFLD6, opcode.STSFLD, opcode.LDLOC0, opcode.LDLOC1, opcode.LDLOC2, opcode.LDLOC3, opcode.LDLOC4, opcode.LDLOC5, opcode .LDLOC6, opcode.LDLOC, opcode.STLOC0, opcode.STLOC1, opcode.STLOC2, opcode.STLOC3, opcode.STLOC4, opcode.STLOC5, opcode.STLOC6, opcode .STLOC, opcode.LDARG0, opcode.LDARG1, opcode.LDARG2, opcode.LDARG3, opcode.LDARG4, opcode.LDARG5, opcode.LDARG6, opcode.LDARG, opcode .STARG0, opcode.STARG1, opcode.STARG2, opcode.STARG3, opcode.STARG4, opcode.STARG5, opcode.STARG6, opcode.STARG, opcode.NEWBUFFER, opcode .MEMCPY, opcode.CAT, opcode.SUBSTR, opcode.LEFT, opcode.RIGHT, opcode .INVERT, opcode.AND, opcode.OR, opcode.XOR, opcode.EQUAL, opcode .NOTEQUAL, opcode.SIGN, opcode.ABS, opcode.NEGATE, opcode.INC, opcode .DEC, opcode.ADD, opcode.SUB, opcode.MUL, opcode.DIV, opcode.MOD, opcode.POW, opcode.SQRT, opcode.MODMUL, opcode.MODPOW, opcode.SHL, opcode.SHR, opcode.NOT, opcode.BOOLAND, opcode.BOOLOR, opcode.NZ, opcode.NUMEQUAL, opcode.NUMNOTEQUAL, opcode.LT, opcode.LE, opcode.GT, opcode.GE, opcode.MIN, opcode.MAX, opcode.WITHIN, opcode.PACKMAP, opcode.PACKSTRUCT, opcode.PACK, opcode.UNPACK, opcode.NEWARRAY0, opcode.NEWARRAY, opcode.NEWARRAYT, opcode.NEWSTRUCT0, opcode .NEWSTRUCT, opcode.NEWMAP, opcode.SIZE, opcode.HASKEY, opcode.KEYS, opcode.VALUES, opcode.PICKITEM, opcode.APPEND, opcode.SETITEM, opcode.REVERSEITEMS, opcode.REMOVE, opcode.CLEARITEMS, opcode .POPITEM, opcode.ISNULL, opcode.ISTYPE, opcode.CONVERT, opcode .ABORTMSG, opcode.ASSERTMSG pkg/compiler/inline_test.go:34:3 exhaustive missing cases in switch of type opcode.Opcode: opcode.PUSHINT8, opcode .PUSHINT16, opcode.PUSHINT32, opcode.PUSHINT64, opcode.PUSHINT128, opcode.PUSHINT256, opcode.PUSHT, opcode.PUSHF, opcode.PUSHA, opcode .PUSHNULL, opcode.PUSHDATA1, opcode.PUSHDATA2, opcode.PUSHDATA4, opcode .PUSHM1, opcode.PUSH0, opcode.PUSH1, opcode.PUSH2, opcode.PUSH3, opcode .PUSH4, opcode.PUSH5, opcode.PUSH6, opcode.PUSH7, opcode.PUSH8, opcode .PUSH9, opcode.PUSH10, opcode.PUSH11, opcode.PUSH12, opcode.PUSH13, opcode.PUSH14, opcode.PUSH15, opcode.PUSH16, opcode.NOP, opcode.JMP, opcode.JMPL, opcode.JMPIF, opcode.JMPIFL, opcode.JMPIFNOT, opcode .JMPIFNOTL, opcode.JMPEQ, opcode.JMPEQL, opcode.JMPNE, opcode.JMPNEL, opcode.JMPGT, opcode.JMPGTL, opcode.JMPGE, opcode.JMPGEL, opcode.JMPLT, opcode.JMPLTL, opcode.JMPLE, opcode.JMPLEL, opcode.CALLA, opcode.CALLT, opcode.ABORT, opcode.ASSERT, opcode.THROW, opcode.TRY, opcode.TRYL, opcode.ENDTRY, opcode.ENDTRYL, opcode.ENDFINALLY, opcode.RET, opcode .SYSCALL, opcode.DEPTH, opcode.DROP, opcode.NIP, opcode.XDROP, opcode .CLEAR, opcode.DUP, opcode.OVER, opcode.PICK, opcode.TUCK, opcode.SWAP, opcode.ROT, opcode.ROLL, opcode.REVERSE3, opcode.REVERSE4, opcode .REVERSEN, opcode.LDSFLD0, opcode.LDSFLD1, opcode.LDSFLD2, opcode .LDSFLD3, opcode.LDSFLD4, opcode.LDSFLD5, opcode.LDSFLD6, opcode.LDSFLD, opcode.STSFLD0, opcode.STSFLD1, opcode.STSFLD2, opcode.STSFLD3, opcode .STSFLD4, opcode.STSFLD5, opcode.STSFLD6, opcode.STSFLD, opcode.LDLOC0, opcode.LDLOC1, opcode.LDLOC2, opcode.LDLOC3, opcode.LDLOC4, opcode .LDLOC5, opcode.LDLOC6, opcode.LDLOC, opcode.STLOC0, opcode.STLOC1, opcode.STLOC2, opcode.STLOC3, opcode.STLOC4, opcode.STLOC5, opcode .STLOC6, opcode.STLOC, opcode.LDARG0, opcode.LDARG1, opcode.LDARG2, opcode.LDARG3, opcode.LDARG4, opcode.LDARG5, opcode.LDARG6, opcode .LDARG, opcode.STARG0, opcode.STARG1, opcode.STARG2, opcode.STARG3, opcode.STARG4, opcode.STARG5, opcode.STARG6, opcode.STARG, opcode .NEWBUFFER, opcode.MEMCPY, opcode.CAT, opcode.SUBSTR, opcode.LEFT, opcode.RIGHT, opcode.INVERT, opcode.AND, opcode.OR, opcode.XOR, opcode .EQUAL, opcode.NOTEQUAL, opcode.SIGN, opcode.ABS, opcode.NEGATE, opcode.INC, opcode.DEC, opcode.ADD, opcode.SUB, opcode.MUL, opcode .DIV, opcode.MOD, opcode.POW, opcode.SQRT, opcode.MODMUL, opcode .MODPOW, opcode.SHL, opcode.SHR, opcode.NOT, opcode.BOOLAND, opcode .BOOLOR, opcode.NZ, opcode.NUMEQUAL, opcode.NUMNOTEQUAL, opcode.LT, opcode.LE, opcode.GT, opcode.GE, opcode.MIN, opcode.MAX, opcode .WITHIN, opcode.PACKMAP, opcode.PACKSTRUCT, opcode.PACK, opcode .UNPACK, opcode.NEWARRAY0, opcode.NEWARRAY, opcode.NEWARRAYT, opcode .NEWSTRUCT0, opcode.NEWSTRUCT, opcode.NEWMAP, opcode.SIZE, opcode .HASKEY, opcode.KEYS, opcode.VALUES, opcode.PICKITEM, opcode.APPEND, opcode.SETITEM, opcode.REVERSEITEMS, opcode.REMOVE, opcode.CLEARITEMS, opcode.POPITEM, opcode.ISNULL, opcode.ISTYPE, opcode.CONVERT, opcode .ABORTMSG, opcode.ASSERTMSG pkg/network/server.go:1395:3 exhaustive missing cases in switch of type network.CommandType: network.CMDNotFound, network.CMDReject, network.CMDFilterLoad, network.CMDFilterAdd, network .CMDFilterClear, network.CMDMerkleBlock, network.CMDAlert pkg/network/server_test.go:532:3 exhaustive missing cases in switch of type network.CommandType: network.CMDVersion, network .CMDVerack, network.CMDGetAddr, network.CMDAddr, network.CMDPing, network.CMDPong, network.CMDGetHeaders, network.CMDHeaders, network .CMDGetBlocks, network.CMDMempool, network.CMDInv, network.CMDGetData, network.CMDGetBlockByIndex, network.CMDGetMPTData, network.CMDMPTData, network.CMDReject, network.CMDFilterLoad, network.CMDFilterAdd, network .CMDFilterClear, network.CMDMerkleBlock, network.CMDAlert pkg/network/server_test.go:817:4 exhaustive missing cases in switch of type network.CommandType: network.CMDVersion, network .CMDVerack, network.CMDGetAddr, network.CMDAddr, network.CMDPing, network.CMDPong, network.CMDGetHeaders, network.CMDHeaders, network .CMDGetBlocks, network.CMDMempool, network.CMDInv, network.CMDGetData, network.CMDGetBlockByIndex, network.CMDNotFound, network.CMDTX, network .CMDBlock, network.CMDExtensible, network.CMDP2PNotaryRequest, network .CMDGetMPTData, network.CMDReject, network.CMDFilterLoad, network .CMDFilterAdd, network.CMDFilterClear, network.CMDMerkleBlock, network .CMDAlert pkg/core/native/designate.go:262:2 exhaustive missing cases in switch of type noderoles.Role: noderoles.NeoFSAlphabet pkg/neorpc/rpcevent/filter.go:36:2 exhaustive missing cases in switch of type neorpc.EventID: neorpc.InvalidEventID, neorpc.MissedEventID pkg/consensus/recovery_message.go:145:2 exhaustive missing cases in switch of type dbft.MessageType: dbft.PreCommitType, dbft .RecoveryRequestType, dbft.RecoveryMessageType cli/cmdargs/parser.go:202:3 exhaustive missing cases in switch of type transaction.WitnessScope: transaction.None, transaction.CalledByEntry, transaction.Rules, transaction.Global ``` Signed-off-by: Ekaterina Pavlova <ekt@morphbits.io>
807 lines
30 KiB
Go
807 lines
30 KiB
Go
package notary_test
|
|
|
|
import (
|
|
"errors"
|
|
"fmt"
|
|
"math/big"
|
|
"math/rand/v2"
|
|
"sync"
|
|
"testing"
|
|
"time"
|
|
|
|
"github.com/nspcc-dev/neo-go/pkg/config"
|
|
"github.com/nspcc-dev/neo-go/pkg/config/netmode"
|
|
"github.com/nspcc-dev/neo-go/pkg/core"
|
|
"github.com/nspcc-dev/neo-go/pkg/core/block"
|
|
"github.com/nspcc-dev/neo-go/pkg/core/mempool"
|
|
"github.com/nspcc-dev/neo-go/pkg/core/native/nativenames"
|
|
"github.com/nspcc-dev/neo-go/pkg/core/native/noderoles"
|
|
"github.com/nspcc-dev/neo-go/pkg/core/transaction"
|
|
"github.com/nspcc-dev/neo-go/pkg/crypto/hash"
|
|
"github.com/nspcc-dev/neo-go/pkg/crypto/keys"
|
|
"github.com/nspcc-dev/neo-go/pkg/io"
|
|
"github.com/nspcc-dev/neo-go/pkg/neotest"
|
|
"github.com/nspcc-dev/neo-go/pkg/neotest/chain"
|
|
"github.com/nspcc-dev/neo-go/pkg/network"
|
|
"github.com/nspcc-dev/neo-go/pkg/network/payload"
|
|
"github.com/nspcc-dev/neo-go/pkg/services/notary"
|
|
"github.com/nspcc-dev/neo-go/pkg/smartcontract"
|
|
"github.com/nspcc-dev/neo-go/pkg/util"
|
|
"github.com/nspcc-dev/neo-go/pkg/vm/opcode"
|
|
"github.com/nspcc-dev/neo-go/pkg/vm/stackitem"
|
|
"github.com/nspcc-dev/neo-go/pkg/wallet"
|
|
"github.com/stretchr/testify/require"
|
|
"go.uber.org/zap/zaptest"
|
|
)
|
|
|
|
func getTestNotary(t *testing.T, bc *core.Blockchain, walletPath, pass string, onTx func(tx *transaction.Transaction) error) (*wallet.Account, *notary.Notary, *mempool.Pool) {
|
|
mainCfg := config.P2PNotary{
|
|
Enabled: true,
|
|
UnlockWallet: config.Wallet{
|
|
Path: walletPath,
|
|
Password: pass,
|
|
},
|
|
}
|
|
cfg := notary.Config{
|
|
MainCfg: mainCfg,
|
|
Chain: bc,
|
|
Log: zaptest.NewLogger(t),
|
|
}
|
|
mp := mempool.New(10, 1, true, nil)
|
|
ntr, err := notary.NewNotary(cfg, netmode.UnitTestNet, mp, onTx)
|
|
require.NoError(t, err)
|
|
|
|
w, err := wallet.NewWalletFromFile(walletPath)
|
|
require.NoError(t, err)
|
|
require.NoError(t, w.Accounts[0].Decrypt(pass, w.Scrypt))
|
|
return w.Accounts[0], ntr, mp
|
|
}
|
|
|
|
// dupNotaryRequest duplicates notary request by serializing/deserializing it. Use
|
|
// it to avoid data races when reusing the same payload. Normal OnNewRequest handler
|
|
// never receives the same (as in the same pointer) payload multiple times, even if
|
|
// the contents is the same it would be a separate buffer.
|
|
func dupNotaryRequest(t *testing.T, p *payload.P2PNotaryRequest) *payload.P2PNotaryRequest {
|
|
b, err := p.Bytes()
|
|
require.NoError(t, err)
|
|
r, err := payload.NewP2PNotaryRequestFromBytes(b)
|
|
require.NoError(t, err)
|
|
return r
|
|
}
|
|
|
|
func TestNotary(t *testing.T) {
|
|
bc, validators, committee := chain.NewMultiWithCustomConfig(t, func(c *config.Blockchain) {
|
|
c.P2PSigExtensions = true
|
|
})
|
|
e := neotest.NewExecutor(t, bc, validators, committee)
|
|
notaryHash := e.NativeHash(t, nativenames.Notary)
|
|
designationSuperInvoker := e.NewInvoker(e.NativeHash(t, nativenames.Designation), validators, committee)
|
|
gasValidatorInvoker := e.ValidatorInvoker(e.NativeHash(t, nativenames.Gas))
|
|
|
|
var (
|
|
nonce uint32
|
|
nvbDiffFallback uint32 = 20
|
|
)
|
|
|
|
mtx := sync.RWMutex{}
|
|
completedTxes := make(map[util.Uint256]*transaction.Transaction)
|
|
var unluckies []*payload.P2PNotaryRequest
|
|
var (
|
|
finalizeWithError bool
|
|
choosy bool
|
|
)
|
|
setFinalizeWithError := func(v bool) {
|
|
mtx.Lock()
|
|
finalizeWithError = v
|
|
mtx.Unlock()
|
|
}
|
|
setChoosy := func(v bool) {
|
|
mtx.Lock()
|
|
choosy = v
|
|
mtx.Unlock()
|
|
}
|
|
onTransaction := func(tx *transaction.Transaction) error {
|
|
mtx.Lock()
|
|
defer mtx.Unlock()
|
|
if !choosy {
|
|
if completedTxes[tx.Hash()] != nil {
|
|
panic("transaction was completed twice")
|
|
}
|
|
if finalizeWithError {
|
|
return errors.New("error while finalizing transaction")
|
|
}
|
|
completedTxes[tx.Hash()] = tx
|
|
return nil
|
|
}
|
|
for _, unl := range unluckies {
|
|
if tx.Hash().Equals(unl.FallbackTransaction.Hash()) {
|
|
return errors.New("error while finalizing transaction")
|
|
}
|
|
}
|
|
completedTxes[tx.Hash()] = tx
|
|
return nil
|
|
}
|
|
getCompletedTx := func(t *testing.T, waitForNonNil bool, h util.Uint256) *transaction.Transaction {
|
|
if !waitForNonNil {
|
|
mtx.RLock()
|
|
defer mtx.RUnlock()
|
|
return completedTxes[h]
|
|
}
|
|
var completedTx *transaction.Transaction
|
|
require.Eventually(t, func() bool {
|
|
mtx.RLock()
|
|
defer mtx.RUnlock()
|
|
completedTx = completedTxes[h]
|
|
return completedTx != nil
|
|
}, time.Second*3, time.Millisecond*50, errors.New("transaction expected to be completed"))
|
|
return completedTx
|
|
}
|
|
|
|
acc1, ntr1, mp1 := getTestNotary(t, bc, "./testdata/notary1.json", "one", onTransaction)
|
|
acc2, _, _ := getTestNotary(t, bc, "./testdata/notary2.json", "two", onTransaction)
|
|
randomAcc, err := keys.NewPrivateKey()
|
|
require.NoError(t, err)
|
|
|
|
bc.SetNotary(ntr1)
|
|
bc.RegisterPostBlock(func(f func(*transaction.Transaction, *mempool.Pool, bool) bool, pool *mempool.Pool, b *block.Block) {
|
|
ntr1.PostPersist()
|
|
})
|
|
|
|
mp1.RunSubscriptions()
|
|
ntr1.Start()
|
|
t.Cleanup(func() {
|
|
ntr1.Shutdown()
|
|
mp1.StopSubscriptions()
|
|
})
|
|
|
|
notaryNodes := []any{acc1.PublicKey().Bytes(), acc2.PrivateKey().PublicKey().Bytes()}
|
|
designationSuperInvoker.Invoke(t, stackitem.Null{}, "designateAsRole",
|
|
int64(noderoles.P2PNotary), notaryNodes)
|
|
|
|
type requester struct {
|
|
accounts []*wallet.Account
|
|
m int
|
|
typ notary.RequestType
|
|
}
|
|
createFallbackTx := func(requester *wallet.Account, mainTx *transaction.Transaction, nvbIncrement ...uint32) *transaction.Transaction {
|
|
fallback := transaction.New([]byte{byte(opcode.RET)}, 2000_0000)
|
|
fallback.Nonce = nonce
|
|
nonce++
|
|
fallback.SystemFee = 1_0000_0000
|
|
fallback.ValidUntilBlock = bc.BlockHeight() + 2*nvbDiffFallback
|
|
fallback.Signers = []transaction.Signer{
|
|
{
|
|
Account: bc.GetNotaryContractScriptHash(),
|
|
Scopes: transaction.None,
|
|
},
|
|
{
|
|
Account: requester.ScriptHash(),
|
|
Scopes: transaction.None,
|
|
},
|
|
}
|
|
nvb := bc.BlockHeight() + nvbDiffFallback
|
|
if len(nvbIncrement) != 0 {
|
|
nvb += nvbIncrement[0]
|
|
}
|
|
fallback.Attributes = []transaction.Attribute{
|
|
{
|
|
Type: transaction.NotaryAssistedT,
|
|
Value: &transaction.NotaryAssisted{NKeys: 0},
|
|
},
|
|
{
|
|
Type: transaction.NotValidBeforeT,
|
|
Value: &transaction.NotValidBefore{Height: nvb},
|
|
},
|
|
{
|
|
Type: transaction.ConflictsT,
|
|
Value: &transaction.Conflicts{Hash: mainTx.Hash()},
|
|
},
|
|
}
|
|
fallback.Scripts = []transaction.Witness{
|
|
{
|
|
InvocationScript: append([]byte{byte(opcode.PUSHDATA1), keys.SignatureLen}, make([]byte, keys.SignatureLen)...),
|
|
VerificationScript: []byte{},
|
|
},
|
|
}
|
|
err = requester.SignTx(netmode.UnitTestNet, fallback)
|
|
require.NoError(t, err)
|
|
return fallback
|
|
}
|
|
createMixedRequest := func(requesters []requester, NVBincrements ...uint32) []*payload.P2PNotaryRequest {
|
|
mainTx := *transaction.New([]byte{byte(opcode.RET)}, 11000000)
|
|
mainTx.Nonce = nonce
|
|
nonce++
|
|
mainTx.SystemFee = 100000000
|
|
mainTx.ValidUntilBlock = bc.BlockHeight() + 2*nvbDiffFallback
|
|
signers := make([]transaction.Signer, len(requesters)+1)
|
|
var (
|
|
nKeys uint8
|
|
verificationScripts [][]byte
|
|
)
|
|
for i := range requesters {
|
|
var script []byte
|
|
switch requesters[i].typ {
|
|
case notary.Signature:
|
|
script = requesters[i].accounts[0].PublicKey().GetVerificationScript()
|
|
nKeys++
|
|
case notary.MultiSignature:
|
|
pubs := make(keys.PublicKeys, len(requesters[i].accounts))
|
|
for j, r := range requesters[i].accounts {
|
|
pubs[j] = r.PublicKey()
|
|
}
|
|
script, err = smartcontract.CreateMultiSigRedeemScript(requesters[i].m, pubs)
|
|
require.NoError(t, err)
|
|
nKeys += uint8(len(requesters[i].accounts))
|
|
default:
|
|
}
|
|
signers[i] = transaction.Signer{
|
|
Account: hash.Hash160(script),
|
|
Scopes: transaction.None,
|
|
}
|
|
verificationScripts = append(verificationScripts, script)
|
|
}
|
|
signers[len(signers)-1] = transaction.Signer{
|
|
Account: bc.GetNotaryContractScriptHash(),
|
|
Scopes: transaction.None,
|
|
}
|
|
mainTx.Signers = signers
|
|
mainTx.Attributes = []transaction.Attribute{
|
|
{
|
|
Type: transaction.NotaryAssistedT,
|
|
Value: &transaction.NotaryAssisted{NKeys: nKeys},
|
|
},
|
|
}
|
|
payloads := make([]*payload.P2PNotaryRequest, nKeys)
|
|
plIndex := 0
|
|
// we'll collect only m signatures out of n (so only m payloads are needed), but let's create payloads for all requesters (for the next tests)
|
|
for i, r := range requesters {
|
|
for _, acc := range r.accounts {
|
|
cp := mainTx
|
|
main := &cp
|
|
main.Scripts = make([]transaction.Witness, len(requesters))
|
|
for j := range main.Scripts {
|
|
main.Scripts[j].VerificationScript = verificationScripts[j]
|
|
if i == j {
|
|
main.Scripts[j].InvocationScript = append([]byte{byte(opcode.PUSHDATA1), keys.SignatureLen}, acc.PrivateKey().SignHashable(uint32(netmode.UnitTestNet), main)...)
|
|
}
|
|
}
|
|
main.Scripts = append(main.Scripts, transaction.Witness{}) // empty Notary witness
|
|
|
|
_ = main.Size() // for size update test
|
|
|
|
var fallback *transaction.Transaction
|
|
if len(NVBincrements) == int(nKeys) {
|
|
fallback = createFallbackTx(acc, main, NVBincrements[plIndex])
|
|
} else {
|
|
fallback = createFallbackTx(acc, main)
|
|
}
|
|
|
|
_ = fallback.Size() // for size update test
|
|
|
|
payloads[plIndex] = &payload.P2PNotaryRequest{
|
|
MainTransaction: main,
|
|
FallbackTransaction: fallback,
|
|
}
|
|
plIndex++
|
|
}
|
|
}
|
|
return payloads
|
|
}
|
|
checkMainTx := func(t *testing.T, requesters []requester, requests []*payload.P2PNotaryRequest, sentCount int, shouldComplete bool) {
|
|
nSigs := 0
|
|
for _, r := range requesters {
|
|
switch r.typ {
|
|
case notary.Signature:
|
|
nSigs++
|
|
case notary.MultiSignature:
|
|
nSigs += r.m
|
|
default:
|
|
}
|
|
}
|
|
nSigners := len(requesters) + 1
|
|
if sentCount >= nSigs && shouldComplete {
|
|
completedTx := getCompletedTx(t, true, requests[0].MainTransaction.Hash())
|
|
require.Equal(t, nSigners, len(completedTx.Signers))
|
|
require.Equal(t, nSigners, len(completedTx.Scripts))
|
|
|
|
// check that tx size was updated
|
|
require.Equal(t, io.GetVarSize(completedTx), completedTx.Size())
|
|
|
|
for i := range len(completedTx.Scripts) - 1 {
|
|
_, err := bc.VerifyWitness(completedTx.Signers[i].Account, completedTx, &completedTx.Scripts[i], -1)
|
|
require.NoError(t, err)
|
|
}
|
|
require.Equal(t, transaction.Witness{
|
|
InvocationScript: append([]byte{byte(opcode.PUSHDATA1), keys.SignatureLen}, acc1.PrivateKey().SignHashable(uint32(netmode.UnitTestNet), requests[0].MainTransaction)...),
|
|
VerificationScript: []byte{},
|
|
}, completedTx.Scripts[len(completedTx.Scripts)-1])
|
|
} else {
|
|
completedTx := getCompletedTx(t, false, requests[0].MainTransaction.Hash())
|
|
require.Nil(t, completedTx, fmt.Errorf("main transaction shouldn't be completed: sent %d out of %d requests", sentCount, nSigs))
|
|
}
|
|
}
|
|
checkFallbackTxs := func(t *testing.T, requests []*payload.P2PNotaryRequest, shouldComplete bool) {
|
|
for i, req := range requests {
|
|
if shouldComplete {
|
|
completedTx := getCompletedTx(t, true, req.FallbackTransaction.Hash())
|
|
require.Equal(t, 2, len(completedTx.Signers))
|
|
require.Equal(t, 2, len(completedTx.Scripts))
|
|
require.Equal(t, transaction.Witness{
|
|
InvocationScript: append([]byte{byte(opcode.PUSHDATA1), keys.SignatureLen}, acc1.PrivateKey().SignHashable(uint32(netmode.UnitTestNet), req.FallbackTransaction)...),
|
|
VerificationScript: []byte{},
|
|
}, completedTx.Scripts[0])
|
|
|
|
// check that tx size was updated
|
|
require.Equal(t, io.GetVarSize(completedTx), completedTx.Size())
|
|
|
|
_, err := bc.VerifyWitness(completedTx.Signers[1].Account, completedTx, &completedTx.Scripts[1], -1)
|
|
require.NoError(t, err)
|
|
} else {
|
|
completedTx := getCompletedTx(t, false, req.FallbackTransaction.Hash())
|
|
require.Nil(t, completedTx, fmt.Errorf("fallback transaction for request #%d shouldn't be completed", i))
|
|
}
|
|
}
|
|
}
|
|
checkCompleteStandardRequest := func(t *testing.T, nKeys int, shouldComplete bool, nvbIncrements ...uint32) ([]*payload.P2PNotaryRequest, []requester) {
|
|
requesters := make([]requester, nKeys)
|
|
for i := range requesters {
|
|
acc, _ := wallet.NewAccount()
|
|
requesters[i] = requester{
|
|
accounts: []*wallet.Account{acc},
|
|
typ: notary.Signature,
|
|
}
|
|
}
|
|
|
|
requests := createMixedRequest(requesters, nvbIncrements...)
|
|
sendOrder := make([]int, nKeys)
|
|
for i := range sendOrder {
|
|
sendOrder[i] = i
|
|
}
|
|
rand.Shuffle(nKeys, func(i, j int) {
|
|
sendOrder[j], sendOrder[i] = sendOrder[i], sendOrder[j]
|
|
})
|
|
for i := range requests {
|
|
ntr1.OnNewRequest(requests[sendOrder[i]])
|
|
checkMainTx(t, requesters, requests, i+1, shouldComplete)
|
|
completedCount := len(completedTxes)
|
|
|
|
// check that the same request won't be processed twice
|
|
ntr1.OnNewRequest(dupNotaryRequest(t, requests[sendOrder[i]]))
|
|
checkMainTx(t, requesters, requests, i+1, shouldComplete)
|
|
require.Equal(t, completedCount, len(completedTxes))
|
|
}
|
|
return requests, requesters
|
|
}
|
|
checkCompleteMultisigRequest := func(t *testing.T, nSigs int, nKeys int, shouldComplete bool) ([]*payload.P2PNotaryRequest, []requester) {
|
|
accounts := make([]*wallet.Account, nKeys)
|
|
for i := range accounts {
|
|
accounts[i], _ = wallet.NewAccount()
|
|
}
|
|
requesters := []requester{
|
|
{
|
|
accounts: accounts,
|
|
m: nSigs,
|
|
typ: notary.MultiSignature,
|
|
},
|
|
}
|
|
requests := createMixedRequest(requesters)
|
|
sendOrder := make([]int, nKeys)
|
|
for i := range sendOrder {
|
|
sendOrder[i] = i
|
|
}
|
|
rand.Shuffle(nKeys, func(i, j int) {
|
|
sendOrder[j], sendOrder[i] = sendOrder[i], sendOrder[j]
|
|
})
|
|
|
|
var submittedRequests []*payload.P2PNotaryRequest
|
|
// sent only nSigs (m out of n) requests - it should be enough to complete min tx
|
|
for i := range nSigs {
|
|
submittedRequests = append(submittedRequests, requests[sendOrder[i]])
|
|
|
|
ntr1.OnNewRequest(requests[sendOrder[i]])
|
|
checkMainTx(t, requesters, submittedRequests, i+1, shouldComplete)
|
|
|
|
// check that the same request won't be processed twice
|
|
ntr1.OnNewRequest(dupNotaryRequest(t, requests[sendOrder[i]]))
|
|
checkMainTx(t, requesters, submittedRequests, i+1, shouldComplete)
|
|
}
|
|
|
|
// sent the rest (n-m) out of n requests: main tx is already collected, so only fallbacks should be applied
|
|
completedCount := len(completedTxes)
|
|
for i := nSigs; i < nKeys; i++ {
|
|
submittedRequests = append(submittedRequests, requests[sendOrder[i]])
|
|
|
|
ntr1.OnNewRequest(requests[sendOrder[i]])
|
|
checkMainTx(t, requesters, submittedRequests, i+1, shouldComplete)
|
|
require.Equal(t, completedCount, len(completedTxes))
|
|
}
|
|
|
|
return submittedRequests, requesters
|
|
}
|
|
|
|
checkCompleteMixedRequest := func(t *testing.T, nSigSigners int, shouldComplete bool) ([]*payload.P2PNotaryRequest, []requester) {
|
|
requesters := make([]requester, nSigSigners)
|
|
for i := range requesters {
|
|
acc, _ := wallet.NewAccount()
|
|
requesters[i] = requester{
|
|
accounts: []*wallet.Account{acc},
|
|
typ: notary.Signature,
|
|
}
|
|
}
|
|
multisigAccounts := make([]*wallet.Account, 3)
|
|
for i := range multisigAccounts {
|
|
multisigAccounts[i], _ = wallet.NewAccount()
|
|
}
|
|
|
|
requesters = append(requesters, requester{
|
|
accounts: multisigAccounts,
|
|
m: 2,
|
|
typ: notary.MultiSignature,
|
|
})
|
|
|
|
requests := createMixedRequest(requesters)
|
|
for i := range requests {
|
|
ntr1.OnNewRequest(requests[i])
|
|
checkMainTx(t, requesters, requests, i+1, shouldComplete)
|
|
completedCount := len(completedTxes)
|
|
|
|
// check that the same request won't be processed twice
|
|
ntr1.OnNewRequest(dupNotaryRequest(t, requests[i]))
|
|
checkMainTx(t, requesters, requests, i+1, shouldComplete)
|
|
require.Equal(t, completedCount, len(completedTxes))
|
|
}
|
|
return requests, requesters
|
|
}
|
|
|
|
// OnNewRequest: missing account
|
|
ntr1.UpdateNotaryNodes(keys.PublicKeys{randomAcc.PublicKey()})
|
|
r, _ := checkCompleteStandardRequest(t, 1, false)
|
|
checkFallbackTxs(t, r, false)
|
|
// set account back for the next tests
|
|
ntr1.UpdateNotaryNodes(keys.PublicKeys{acc1.PublicKey()})
|
|
|
|
// OnNewRequest: signature request
|
|
for _, i := range []int{1, 2, 3, 10} {
|
|
r, _ := checkCompleteStandardRequest(t, i, true)
|
|
checkFallbackTxs(t, r, false)
|
|
}
|
|
|
|
// OnNewRequest: multisignature request
|
|
r, _ = checkCompleteMultisigRequest(t, 1, 1, true)
|
|
checkFallbackTxs(t, r, false)
|
|
r, _ = checkCompleteMultisigRequest(t, 1, 2, true)
|
|
checkFallbackTxs(t, r, false)
|
|
r, _ = checkCompleteMultisigRequest(t, 1, 3, true)
|
|
checkFallbackTxs(t, r, false)
|
|
r, _ = checkCompleteMultisigRequest(t, 3, 3, true)
|
|
checkFallbackTxs(t, r, false)
|
|
r, _ = checkCompleteMultisigRequest(t, 3, 4, true)
|
|
checkFallbackTxs(t, r, false)
|
|
r, _ = checkCompleteMultisigRequest(t, 3, 10, true)
|
|
checkFallbackTxs(t, r, false)
|
|
|
|
// OnNewRequest: mixed request
|
|
r, _ = checkCompleteMixedRequest(t, 1, true)
|
|
checkFallbackTxs(t, r, false)
|
|
r, _ = checkCompleteMixedRequest(t, 2, true)
|
|
checkFallbackTxs(t, r, false)
|
|
r, _ = checkCompleteMixedRequest(t, 3, true)
|
|
checkFallbackTxs(t, r, false)
|
|
// PostPersist: missing account
|
|
setFinalizeWithError(true)
|
|
r, requesters := checkCompleteStandardRequest(t, 1, false)
|
|
checkFallbackTxs(t, r, false)
|
|
ntr1.UpdateNotaryNodes(keys.PublicKeys{randomAcc.PublicKey()})
|
|
setFinalizeWithError(false)
|
|
|
|
e.AddNewBlock(t)
|
|
// Allow a single-block slippage since PostPersist is handled by Notary service via block notification routine.
|
|
e.AddNewBlock(t)
|
|
checkMainTx(t, requesters, r, 1, false)
|
|
checkFallbackTxs(t, r, false)
|
|
// set account back for the next tests
|
|
ntr1.UpdateNotaryNodes(keys.PublicKeys{acc1.PublicKey()})
|
|
|
|
// PostPersist: complete main transaction, signature request
|
|
setFinalizeWithError(true)
|
|
requests, requesters := checkCompleteStandardRequest(t, 3, false)
|
|
// check PostPersist with finalisation error
|
|
setFinalizeWithError(true)
|
|
e.AddNewBlock(t)
|
|
// Allow a single-block slippage since PostPersist is handled by Notary service via block notification routine.
|
|
e.AddNewBlock(t)
|
|
checkMainTx(t, requesters, requests, len(requests), false)
|
|
// check PostPersist without finalisation error
|
|
setFinalizeWithError(false)
|
|
e.AddNewBlock(t)
|
|
// Allow a single-block slippage since PostPersist is handled by Notary service via block notification routine.
|
|
e.AddNewBlock(t)
|
|
checkMainTx(t, requesters, requests, len(requests), true)
|
|
|
|
// PostPersist: complete main transaction, multisignature account
|
|
setFinalizeWithError(true)
|
|
requests, requesters = checkCompleteMultisigRequest(t, 3, 4, false)
|
|
checkFallbackTxs(t, requests, false)
|
|
// check PostPersist with finalisation error
|
|
setFinalizeWithError(true)
|
|
e.AddNewBlock(t)
|
|
// Allow a single-block slippage since PostPersist is handled by Notary service via block notification routine.
|
|
e.AddNewBlock(t)
|
|
checkMainTx(t, requesters, requests, len(requests), false)
|
|
checkFallbackTxs(t, requests, false)
|
|
// check PostPersist without finalisation error
|
|
setFinalizeWithError(false)
|
|
e.AddNewBlock(t)
|
|
// Allow a single-block slippage since PostPersist is handled by Notary service via block notification routine.
|
|
e.AddNewBlock(t)
|
|
checkMainTx(t, requesters, requests, len(requests), true)
|
|
checkFallbackTxs(t, requests, false)
|
|
|
|
// PostPersist: complete fallback, signature request
|
|
setFinalizeWithError(true)
|
|
requests, requesters = checkCompleteStandardRequest(t, 3, false)
|
|
checkFallbackTxs(t, requests, false)
|
|
// make fallbacks valid
|
|
e.GenerateNewBlocks(t, int(nvbDiffFallback+1))
|
|
require.NoError(t, err)
|
|
// check PostPersist for valid fallbacks with finalisation error
|
|
e.AddNewBlock(t)
|
|
// Allow a single-block slippage since PostPersist is handled by Notary service via block notification routine.
|
|
e.AddNewBlock(t)
|
|
checkMainTx(t, requesters, requests, len(requests), false)
|
|
checkFallbackTxs(t, requests, false)
|
|
// check PostPersist for valid fallbacks without finalisation error
|
|
setFinalizeWithError(false)
|
|
e.AddNewBlock(t)
|
|
// Allow a single-block slippage since PostPersist is handled by Notary service via block notification routine.
|
|
e.AddNewBlock(t)
|
|
checkMainTx(t, requesters, requests, len(requests), false)
|
|
checkFallbackTxs(t, requests, true)
|
|
|
|
// PostPersist: complete fallback, multisignature request
|
|
nSigs, nKeys := 3, 5
|
|
// check OnNewRequest with finalization error
|
|
setFinalizeWithError(true)
|
|
requests, requesters = checkCompleteMultisigRequest(t, nSigs, nKeys, false)
|
|
checkFallbackTxs(t, requests, false)
|
|
// make fallbacks valid
|
|
e.GenerateNewBlocks(t, int(nvbDiffFallback+1))
|
|
require.NoError(t, err)
|
|
// check PostPersist for valid fallbacks with finalisation error
|
|
e.AddNewBlock(t)
|
|
// Allow a single-block slippage since PostPersist is handled by Notary service via block notification routine.
|
|
e.AddNewBlock(t)
|
|
checkMainTx(t, requesters, requests, len(requests), false)
|
|
checkFallbackTxs(t, requests, false)
|
|
// check PostPersist for valid fallbacks without finalisation error
|
|
setFinalizeWithError(false)
|
|
e.AddNewBlock(t)
|
|
// Allow a single-block slippage since PostPersist is handled by Notary service via block notification routine.
|
|
e.AddNewBlock(t)
|
|
checkMainTx(t, requesters, requests, len(requests), false)
|
|
checkFallbackTxs(t, requests[:nSigs], true)
|
|
// the rest of fallbacks should also be applied even if the main tx was already constructed by the moment they were sent
|
|
checkFallbackTxs(t, requests[nSigs:], true)
|
|
|
|
// PostPersist: partial fallbacks completion due to finalisation errors
|
|
setFinalizeWithError(true)
|
|
requests, requesters = checkCompleteStandardRequest(t, 5, false)
|
|
checkFallbackTxs(t, requests, false)
|
|
// make fallbacks valid
|
|
e.GenerateNewBlocks(t, int(nvbDiffFallback+1))
|
|
require.NoError(t, err)
|
|
// some of fallbacks should fail finalisation
|
|
unluckies = []*payload.P2PNotaryRequest{requests[0], requests[4]}
|
|
lucky := requests[1:4]
|
|
setChoosy(true)
|
|
// check PostPersist for lucky fallbacks
|
|
e.AddNewBlock(t)
|
|
// Allow a single-block slippage since PostPersist is handled by Notary service via block notification routine.
|
|
e.AddNewBlock(t)
|
|
checkMainTx(t, requesters, requests, len(requests), false)
|
|
checkFallbackTxs(t, lucky, true)
|
|
checkFallbackTxs(t, unluckies, false)
|
|
// reset finalisation function for unlucky fallbacks to finalise without an error
|
|
setChoosy(false)
|
|
setFinalizeWithError(false)
|
|
// check PostPersist for unlucky fallbacks
|
|
e.AddNewBlock(t)
|
|
// Allow a single-block slippage since PostPersist is handled by Notary service via block notification routine.
|
|
e.AddNewBlock(t)
|
|
checkMainTx(t, requesters, requests, len(requests), false)
|
|
checkFallbackTxs(t, lucky, true)
|
|
checkFallbackTxs(t, unluckies, true)
|
|
|
|
// PostPersist: different NVBs
|
|
// check OnNewRequest with finalization error and different NVBs
|
|
setFinalizeWithError(true)
|
|
// Introduce some slippage between first and second fallback NVBs in order to avoid possible race caused by early
|
|
// first fallback transaction acceptance. The rest of fallbacks follow X+4 NVB pattern for testing code shortness.
|
|
requests, requesters = checkCompleteStandardRequest(t, 5, false, 1, 7, 11, 15, 19)
|
|
checkFallbackTxs(t, requests, false)
|
|
// generate blocks to reach the most earlier fallback's NVB
|
|
// Here and below add +1 slippage to ensure that PostPersist for (nvbDiffFallback+1) height is properly handled, i.e.
|
|
// to exclude race condition when main transaction is finalized between `finalizeWithError` disabling and new block addition.
|
|
e.GenerateNewBlocks(t, int((nvbDiffFallback+1)+1))
|
|
require.NoError(t, err)
|
|
// check PostPersist for valid fallbacks without finalisation error
|
|
setFinalizeWithError(false)
|
|
for i := range requests {
|
|
e.AddNewBlock(t)
|
|
e.AddNewBlock(t)
|
|
e.AddNewBlock(t)
|
|
e.AddNewBlock(t)
|
|
|
|
checkMainTx(t, requesters, requests, len(requests), false)
|
|
checkFallbackTxs(t, requests[:i+1], true)
|
|
checkFallbackTxs(t, requests[i+1:], false)
|
|
}
|
|
|
|
// OnRequestRemoval: missing account
|
|
// check OnNewRequest with finalization error
|
|
setFinalizeWithError(true)
|
|
requests, requesters = checkCompleteStandardRequest(t, 4, false)
|
|
checkFallbackTxs(t, requests, false)
|
|
// make fallbacks valid and remove one fallback
|
|
e.GenerateNewBlocks(t, int(nvbDiffFallback+1))
|
|
require.NoError(t, err)
|
|
ntr1.UpdateNotaryNodes(keys.PublicKeys{randomAcc.PublicKey()})
|
|
ntr1.OnRequestRemoval(requests[3])
|
|
// non of the fallbacks should be completed
|
|
setFinalizeWithError(false)
|
|
e.AddNewBlock(t)
|
|
// Allow a single-block slippage since PostPersist is handled by Notary service via block notification routine.
|
|
e.AddNewBlock(t)
|
|
checkMainTx(t, requesters, requests, len(requests), false)
|
|
checkFallbackTxs(t, requests, false)
|
|
// set account back for the next tests
|
|
ntr1.UpdateNotaryNodes(keys.PublicKeys{acc1.PublicKey()})
|
|
|
|
// OnRequestRemoval: signature request, remove one fallback
|
|
// check OnNewRequest with finalization error
|
|
setFinalizeWithError(true)
|
|
requests, requesters = checkCompleteStandardRequest(t, 4, false)
|
|
checkFallbackTxs(t, requests, false)
|
|
// make fallbacks valid and remove one fallback
|
|
e.GenerateNewBlocks(t, int(nvbDiffFallback+1))
|
|
require.NoError(t, err)
|
|
unlucky := requests[3]
|
|
ntr1.OnRequestRemoval(unlucky)
|
|
// rest of the fallbacks should be completed
|
|
setFinalizeWithError(false)
|
|
e.AddNewBlock(t)
|
|
// Allow a single-block slippage since PostPersist is handled by Notary service via block notification routine.
|
|
e.AddNewBlock(t)
|
|
checkMainTx(t, requesters, requests, len(requests), false)
|
|
checkFallbackTxs(t, requests[:3], true)
|
|
require.Nil(t, completedTxes[unlucky.FallbackTransaction.Hash()])
|
|
|
|
// OnRequestRemoval: signature request, remove all fallbacks
|
|
setFinalizeWithError(true)
|
|
requests, requesters = checkCompleteStandardRequest(t, 4, false)
|
|
// remove all fallbacks
|
|
e.GenerateNewBlocks(t, int(nvbDiffFallback+1))
|
|
require.NoError(t, err)
|
|
for i := range requests {
|
|
ntr1.OnRequestRemoval(requests[i])
|
|
}
|
|
// then the whole request should be removed, i.e. there are no completed transactions
|
|
setFinalizeWithError(false)
|
|
e.AddNewBlock(t)
|
|
// Allow a single-block slippage since PostPersist is handled by Notary service via block notification routine.
|
|
e.AddNewBlock(t)
|
|
checkMainTx(t, requesters, requests, len(requests), false)
|
|
checkFallbackTxs(t, requests, false)
|
|
|
|
// OnRequestRemoval: signature request, remove unexisting fallback
|
|
ntr1.OnRequestRemoval(requests[0])
|
|
e.AddNewBlock(t)
|
|
// Allow a single-block slippage since PostPersist is handled by Notary service via block notification routine.
|
|
e.AddNewBlock(t)
|
|
checkMainTx(t, requesters, requests, len(requests), false)
|
|
checkFallbackTxs(t, requests, false)
|
|
|
|
// OnRequestRemoval: multisignature request, remove one fallback
|
|
nSigs, nKeys = 3, 5
|
|
// check OnNewRequest with finalization error
|
|
setFinalizeWithError(true)
|
|
requests, requesters = checkCompleteMultisigRequest(t, nSigs, nKeys, false)
|
|
checkMainTx(t, requesters, requests, len(requests), false)
|
|
checkFallbackTxs(t, requests, false)
|
|
// make fallbacks valid and remove the last fallback
|
|
e.GenerateNewBlocks(t, int(nvbDiffFallback+1))
|
|
require.NoError(t, err)
|
|
unlucky = requests[nSigs-1]
|
|
ntr1.OnRequestRemoval(unlucky)
|
|
// then (m-1) out of n fallbacks should be completed
|
|
setFinalizeWithError(false)
|
|
e.AddNewBlock(t)
|
|
// Allow a single-block slippage since PostPersist is handled by Notary service via block notification routine.
|
|
e.AddNewBlock(t)
|
|
checkMainTx(t, requesters, requests, len(requests), false)
|
|
checkFallbackTxs(t, requests[:nSigs-1], true)
|
|
require.Nil(t, completedTxes[unlucky.FallbackTransaction.Hash()])
|
|
// the rest (n-(m-1)) out of n fallbacks should also be completed even if main tx has been collected by the moment they were sent
|
|
checkFallbackTxs(t, requests[nSigs:], true)
|
|
|
|
// OnRequestRemoval: multisignature request, remove all fallbacks
|
|
setFinalizeWithError(true)
|
|
requests, requesters = checkCompleteMultisigRequest(t, nSigs, nKeys, false)
|
|
// make fallbacks valid and then remove all of them
|
|
e.GenerateNewBlocks(t, int(nvbDiffFallback+1))
|
|
require.NoError(t, err)
|
|
for i := range requests {
|
|
ntr1.OnRequestRemoval(requests[i])
|
|
}
|
|
// then the whole request should be removed, i.e. there are no completed transactions
|
|
setFinalizeWithError(false)
|
|
e.AddNewBlock(t)
|
|
// Allow a single-block slippage since PostPersist is handled by Notary service via block notification routine.
|
|
e.AddNewBlock(t)
|
|
checkMainTx(t, requesters, requests, len(requests), false)
|
|
checkFallbackTxs(t, requests, false)
|
|
|
|
// // OnRequestRemoval: multisignature request, remove unexisting fallbac, i.e. there still shouldn't be any completed transactions after this
|
|
ntr1.OnRequestRemoval(requests[0])
|
|
e.AddNewBlock(t)
|
|
// Allow a single-block slippage since PostPersist is handled by Notary service via block notification routine.
|
|
e.AddNewBlock(t)
|
|
checkMainTx(t, requesters, requests, len(requests), false)
|
|
checkFallbackTxs(t, requests, false)
|
|
|
|
// Subscriptions test
|
|
setFinalizeWithError(false)
|
|
requester1, _ := wallet.NewAccount()
|
|
requester2, _ := wallet.NewAccount()
|
|
amount := int64(100_0000_0000)
|
|
gasValidatorInvoker.Invoke(t, true, "transfer", e.Validator.ScriptHash(), bc.GetNotaryContractScriptHash(), amount, []any{requester1.ScriptHash(), int64(bc.BlockHeight() + 50)})
|
|
e.CheckGASBalance(t, notaryHash, big.NewInt(amount))
|
|
gasValidatorInvoker.Invoke(t, true, "transfer", e.Validator.ScriptHash(), bc.GetNotaryContractScriptHash(), amount, []any{requester2.ScriptHash(), int64(bc.BlockHeight() + 50)})
|
|
e.CheckGASBalance(t, notaryHash, big.NewInt(2*amount))
|
|
|
|
// create request for 2 standard signatures => main tx should be completed after the second request is added to the pool
|
|
requests = createMixedRequest([]requester{
|
|
{
|
|
accounts: []*wallet.Account{requester1},
|
|
typ: notary.Signature,
|
|
},
|
|
{
|
|
accounts: []*wallet.Account{requester2},
|
|
typ: notary.Signature,
|
|
},
|
|
})
|
|
feer := network.NewNotaryFeer(bc)
|
|
require.NoError(t, mp1.Add(requests[0].FallbackTransaction, feer, requests[0]))
|
|
require.NoError(t, mp1.Add(requests[1].FallbackTransaction, feer, requests[1]))
|
|
require.Eventually(t, func() bool {
|
|
mtx.RLock()
|
|
defer mtx.RUnlock()
|
|
return completedTxes[requests[0].MainTransaction.Hash()] != nil
|
|
}, 3*time.Second, 100*time.Millisecond)
|
|
checkFallbackTxs(t, requests, false)
|
|
}
|
|
|
|
func TestNotary_GenesisRoles(t *testing.T) {
|
|
const (
|
|
notaryPath = "./testdata/notary1.json"
|
|
notaryPass = "one"
|
|
)
|
|
|
|
w, err := wallet.NewWalletFromFile(notaryPath)
|
|
require.NoError(t, err)
|
|
require.NoError(t, w.Accounts[0].Decrypt(notaryPass, w.Scrypt))
|
|
acc := w.Accounts[0]
|
|
|
|
bc, _, _ := chain.NewMultiWithCustomConfig(t, func(c *config.Blockchain) {
|
|
c.P2PSigExtensions = true
|
|
c.Genesis.Roles = map[noderoles.Role]keys.PublicKeys{
|
|
noderoles.P2PNotary: {acc.PublicKey()},
|
|
}
|
|
})
|
|
|
|
_, ntr, _ := getTestNotary(t, bc, "./testdata/notary1.json", "one", func(tx *transaction.Transaction) error { return nil })
|
|
require.False(t, ntr.IsAuthorized())
|
|
|
|
bc.SetNotary(ntr)
|
|
require.True(t, ntr.IsAuthorized())
|
|
}
|