Anna Shaleva
e31f4ca331
interop: add interop API for MODMUL, MODPOW opcodes
2022-05-12 14:31:24 +03:00
Anna Shaleva
5123b88c36
core: extend native Neo interop API
...
Add GetAllCandidates and GetCandidateVote methods.
2022-05-06 13:43:12 +03:00
Elizaveta Chichindaeva
28908aa3cf
[ #2442 ] English Check
...
Signed-off-by: Elizaveta Chichindaeva <elizaveta@nspcc.ru>
2022-05-04 19:48:27 +03:00
Anna Shaleva
aa886f67ce
core: use dao-binded cache for native contracts
...
All native cached values are binded to DAO, so that it's possible
to properly handle historic calls.
2022-04-29 16:10:04 +03:00
Anna Shaleva
8ca8a825ef
compiler: add compatibility test for GetTransactionSigners interop API
2022-04-29 11:34:22 +03:00
Anna Shaleva
d942940a82
core: support System.Runtime.GetAddressVersion syscall
2022-04-21 19:26:16 +03:00
Anna Shaleva
544f2c2cb2
core: use proper storage price within the whole interop context
...
We shouldn't use StoragePrice from Blockchain because its dao doesn't
contain the whole set of changes from previouse transactions in the
current block. Instead, we should use an updated storage price for
each transaction and retrieve the price from cached DAO.
2022-04-08 12:50:56 +03:00
Anna Shaleva
91a4bc5beb
core: use proper DAO to get ExecFeeFactor
...
The usage of the Blockchain's one leads to the same ExecFeeFactor within
a single block. What we need is to update ExecFeeFactor after each
transaction invocation, thus, cached DAO should be used as it contains
all relevant changes.
2022-04-08 12:50:50 +03:00
Roman Khimov
6ff11baa1b
Merge pull request #2427 from nspcc-dev/add-hash-to-debug-info
...
Add hash to debug info and use absolute path
2022-04-06 16:11:47 +03:00
Roman Khimov
f5d5019b70
compiler: use absolute paths for debug data
...
It's not a perfect thing, but neo-debugger just doesn't work at all with
relative pathes. Notice that `saveSequencePoint` still used absolute ones
leading to invalid debug.json data, but fixing it there doesn't help,
neo-debugger can't load source code using relatives.
2022-04-06 15:46:54 +03:00
Roman Khimov
e390981747
compiler: add hash field to debug info
...
New debugger won't work without it.
2022-04-06 15:27:01 +03:00
Anna Shaleva
72ec354039
compiler: add test for murmur32 interop API
2022-04-05 10:51:12 +03:00
Anna Shaleva
0e8bf83dda
compiler: add tests for GetTransactionVMState
2022-04-05 10:46:52 +03:00
Roman Khimov
be7527409c
compiler: fix panic in notification check
...
Options is a pointer, so it can be nil:
--- FAIL: TestCompiler (0.23s)
--- FAIL: TestCompiler/TestCompile (0.21s)
panic: runtime error: invalid memory address or nil pointer dereference [recovered]
panic: runtime error: invalid memory address or nil pointer dereference
[signal SIGSEGV: segmentation violation code=0x1 addr=0x40 pc=0x960374]
goroutine 8861 [running]:
testing.tRunner.func1.2({0xa604c0, 0x112c230})
/usr/lib64/go/1.18/src/testing/testing.go:1389 +0x24e
testing.tRunner.func1()
/usr/lib64/go/1.18/src/testing/testing.go:1392 +0x39f
panic({0xa604c0, 0x112c230})
/usr/lib64/go/1.18/src/runtime/panic.go:838 +0x207
github.com/nspcc-dev/neo-go/pkg/compiler.(*codegen).processNotify(0xc0000eba40, 0xc000233ae0?, {0xc00044ae90, 0x1, 0x1})
/home/rik/dev/neo-go/pkg/compiler/inline.go:134 +0xd4
github.com/nspcc-dev/neo-go/pkg/compiler.(*codegen).processStdlibCall(0xc0000eba40?, 0xc000233ae0, {0xc00044ae90, 0x1, 0x1})
/home/rik/dev/neo-go/pkg/compiler/inline.go:124 +0xda
github.com/nspcc-dev/neo-go/pkg/compiler.(*codegen).inlineCall(0xc0000eba40, 0xc000233ae0, 0xc0001fe5c0)
/home/rik/dev/neo-go/pkg/compiler/inline.go:35 +0x1fa
github.com/nspcc-dev/neo-go/pkg/compiler.(*codegen).Visit(0xc0000eba40, {0xd36bf8?, 0xc0001fe5c0?})
/home/rik/dev/neo-go/pkg/compiler/codegen.go:932 +0x152c
go/ast.Walk({0xd348e0?, 0xc0000eba40?}, {0xd36bf8?, 0xc0001fe5c0?})
/usr/lib64/go/1.18/src/go/ast/walk.go:52 +0x62
go/ast.Walk({0xd348e0?, 0xc0000eba40?}, {0xd36db0?, 0xc00044aeb0?})
/usr/lib64/go/1.18/src/go/ast/walk.go:207 +0x1154
github.com/nspcc-dev/neo-go/pkg/compiler.(*codegen).Visit(0xc0000eba40, {0xd36ba8?, 0xc0001cce70?})
/home/rik/dev/neo-go/pkg/compiler/codegen.go:1155 +0x54cd
go/ast.Walk({0xd348e0?, 0xc0000eba40?}, {0xd36ba8?, 0xc0001cce70?})
/usr/lib64/go/1.18/src/go/ast/walk.go:52 +0x62
github.com/nspcc-dev/neo-go/pkg/compiler.(*codegen).Visit(0xc0000eba40, {0xd36f68?, 0xc0001fe600?})
/home/rik/dev/neo-go/pkg/compiler/codegen.go:733 +0x2e30
go/ast.Walk({0xd348e0?, 0xc0000eba40?}, {0xd36f68?, 0xc0001fe600?})
/usr/lib64/go/1.18/src/go/ast/walk.go:52 +0x62
github.com/nspcc-dev/neo-go/pkg/compiler.(*codegen).Visit(0xc0000eba40, {0xd36ba8?, 0xc0001ccea0?})
/home/rik/dev/neo-go/pkg/compiler/codegen.go:1155 +0x54cd
go/ast.Walk({0xd348e0?, 0xc0000eba40?}, {0xd36ba8?, 0xc0001ccea0?})
/usr/lib64/go/1.18/src/go/ast/walk.go:52 +0x62
github.com/nspcc-dev/neo-go/pkg/compiler.(*codegen).convertFuncDecl(0xc0000eba40, {0xd36e28, 0xc000256700}, 0xc0001cced0, 0xc00041b68c?)
/home/rik/dev/neo-go/pkg/compiler/codegen.go:502 +0x97d
github.com/nspcc-dev/neo-go/pkg/compiler.(*codegen).compile.func2(0xc000256700, 0xc0001c64b0)
/home/rik/dev/neo-go/pkg/compiler/codegen.go:2129 +0x1f9
github.com/nspcc-dev/neo-go/pkg/compiler.(*codegen).ForEachFile.func1(0xc000254a00)
/home/rik/dev/neo-go/pkg/compiler/compiler.go:102 +0x96
github.com/nspcc-dev/neo-go/pkg/compiler.(*codegen).ForEachPackage(0xc0000eba40, 0xc0002f3c68)
/home/rik/dev/neo-go/pkg/compiler/compiler.go:93 +0xdb
github.com/nspcc-dev/neo-go/pkg/compiler.(*codegen).ForEachFile(0xa1f700?, 0xc000448f90?)
/home/rik/dev/neo-go/pkg/compiler/compiler.go:99 +0x4d
github.com/nspcc-dev/neo-go/pkg/compiler.(*codegen).compile(0xc0000eba40, 0xc00022c390, 0x1?)
/home/rik/dev/neo-go/pkg/compiler/codegen.go:2116 +0x3d6
github.com/nspcc-dev/neo-go/pkg/compiler.codeGen(0xc00022c390)
/home/rik/dev/neo-go/pkg/compiler/codegen.go:2167 +0x373
github.com/nspcc-dev/neo-go/pkg/compiler.CompileWithOptions({0xc000c525a0?, 0x16?}, {0x0?, 0x0?}, 0x0)
/home/rik/dev/neo-go/pkg/compiler/compiler.go:218 +0x7d
github.com/nspcc-dev/neo-go/pkg/compiler.Compile({0xc000c525a0?, 0xc000304340?}, {0x0?, 0x0?})
/home/rik/dev/neo-go/pkg/compiler/compiler.go:203 +0x34
github.com/nspcc-dev/neo-go/pkg/compiler_test.compileFile(...)
/home/rik/dev/neo-go/pkg/compiler/compiler_test.go:89
github.com/nspcc-dev/neo-go/pkg/compiler_test.TestCompiler.func2(0x6a2a89?)
/home/rik/dev/neo-go/pkg/compiler/compiler_test.go:61 +0x133
testing.tRunner(0xc000304340, 0xc7f5b0)
/usr/lib64/go/1.18/src/testing/testing.go:1439 +0x102
created by testing.(*T).Run
/usr/lib64/go/1.18/src/testing/testing.go:1486 +0x35f
2022-03-24 16:34:18 +03:00
AnnaShaleva
a4d402da86
compiler: revert a part of ad65d1fa1f
...
Close #2335 .
2022-03-17 19:39:18 +03:00
Anna Shaleva
2096ad6e81
*: remove io/ioutil uses
...
Close #1764 .
2022-03-17 19:39:18 +03:00
Roman Khimov
96cd415384
Merge pull request #2382 from nspcc-dev/compiler-optimize
...
compiler: optimize tests
2022-03-04 18:55:40 +03:00
Evgeniy Stratonikov
0e86073a77
compiler: group small tests in a single file
...
Signed-off-by: Evgeniy Stratonikov <evgeniy@nspcc.ru>
2022-03-04 17:55:33 +03:00
AnnaShaleva
3996b3abb7
interop: extend native Notary interop API
2022-03-01 19:08:22 +03:00
Evgeniy Stratonikov
a2cef15932
compiler: emit bindings configuration
...
Signed-off-by: Evgeniy Stratonikov <evgeniy@nspcc.ru>
2022-02-28 15:36:14 +03:00
Roman Khimov
aefb26255a
dao: drop DAO interface
...
It's a remnant from the days when we had Simple and Cached DAO
implementations, now it makes zero sense.
2022-02-16 18:24:20 +03:00
Anna Shaleva
0de4c0fc17
compiler: use full paths for debug info files if relative can't be constructed
...
Firstly introduced in 9871dc8f5a
. It's OK
if relative path can't be constructed e.g. for interop dependencies. Otherwice
leads to failing tests on Windows with the following error:
```
2022-02-09T09:39:31.3307626Z panic: Rel: can't make D:\a\neo-go\neo-go\pkg\interop\neogointernal\syscall.go relative to C:\Users\RUNNER~1\AppData\Local\Temp\TestContractInitAndCompile1998984267\001\testcontract [recovered]
2022-02-09T09:39:31.3308830Z panic: Rel: can't make D:\a\neo-go\neo-go\pkg\interop\neogointernal\syscall.go relative to C:\Users\RUNNER~1\AppData\Local\Temp\TestContractInitAndCompile1998984267\001\testcontract
2022-02-09T09:39:31.3309285Z
2022-02-09T09:39:31.3309390Z goroutine 302 [running]:
2022-02-09T09:39:31.3309725Z testing.tRunner.func1.2({0x14dbfe0, 0xc00051bdb0})
2022-02-09T09:39:31.3310187Z C:/hostedtoolcache/windows/go/1.17.6/x64/src/testing/testing.go:1209 +0x36c
2022-02-09T09:39:31.3310538Z testing.tRunner.func1()
2022-02-09T09:39:31.3310937Z C:/hostedtoolcache/windows/go/1.17.6/x64/src/testing/testing.go:1212 +0x3b6
2022-02-09T09:39:31.3311285Z panic({0x14dbfe0, 0xc00051bdb0})
2022-02-09T09:39:31.3311689Z C:/hostedtoolcache/windows/go/1.17.6/x64/src/runtime/panic.go:1047 +0x266
2022-02-09T09:39:31.3312319Z github.com/nspcc-dev/neo-go/pkg/compiler.(*codegen).fillDocumentInfo.func1(0xc0002d0b40)
2022-02-09T09:39:31.3312885Z D:/a/neo-go/neo-go/pkg/compiler/analysis.go:240 +0x34d
2022-02-09T09:39:31.3313397Z go/token.(*FileSet).Iterate(0xc0000a69c0, 0xc0004898b0)
2022-02-09T09:39:31.3313839Z C:/hostedtoolcache/windows/go/1.17.6/x64/src/go/token/position.go:463 +0xde
2022-02-09T09:39:31.3314404Z github.com/nspcc-dev/neo-go/pkg/compiler.(*codegen).fillDocumentInfo(0xc0002e4d20)
2022-02-09T09:39:31.3314947Z D:/a/neo-go/neo-go/pkg/compiler/analysis.go:236 +0x97
2022-02-09T09:39:31.3315530Z github.com/nspcc-dev/neo-go/pkg/compiler.(*codegen).compile(0xc0002e4d20, 0xc00009a690, 0xc000101540)
2022-02-09T09:39:31.3316064Z D:/a/neo-go/neo-go/pkg/compiler/codegen.go:2088 +0x192
2022-02-09T09:39:31.3316563Z github.com/nspcc-dev/neo-go/pkg/compiler.codeGen(0xc00009a690)
2022-02-09T09:39:31.3317066Z D:/a/neo-go/neo-go/pkg/compiler/codegen.go:2167 +0x7cd
2022-02-09T09:39:31.3317679Z github.com/nspcc-dev/neo-go/pkg/compiler.CompileWithOptions({0xc0000435e0, 0x62}, {0x0, 0x0}, 0xc0004bcf70)
2022-02-09T09:39:31.3318233Z D:/a/neo-go/neo-go/pkg/compiler/compiler.go:225 +0xde
2022-02-09T09:39:31.3318804Z github.com/nspcc-dev/neo-go/pkg/compiler.CompileAndSave({0xc0000435e0, 0x62}, 0xc0004bcf70)
2022-02-09T09:39:31.3319353Z D:/a/neo-go/neo-go/pkg/compiler/compiler.go:241 +0x3a5
2022-02-09T09:39:31.3319889Z github.com/nspcc-dev/neo-go/cli/smartcontract.contractCompile(0xc0004e42c0)
2022-02-09T09:39:31.3320456Z D:/a/neo-go/neo-go/cli/smartcontract/smart_contract.go:520 +0xc2d
2022-02-09T09:39:31.3320873Z github.com/urfave/cli.HandleAction({0x14b6fa0, 0x17b8d60}, 0x7)
2022-02-09T09:39:31.3321344Z C:/Users/runneradmin/go/pkg/mod/github.com/urfave/cli@v1.22.5/app.go:524 +0xf4
2022-02-09T09:39:31.3321931Z github.com/urfave/cli.Command.Run({{0x16460d2, 0x7}, {0x0, 0x0}, {0x0, 0x0, 0x0}, {0x166fe9e, 0x27}, {0x0, ...}, ...}, ...)
2022-02-09T09:39:31.3322443Z C:/Users/runneradmin/go/pkg/mod/github.com/urfave/cli@v1.22.5/command.go:173 +0xc09
2022-02-09T09:39:31.3322894Z github.com/urfave/cli.(*App).RunAsSubcommand(0xc0000b7340, 0xc0004e4000)
2022-02-09T09:39:31.3323375Z C:/Users/runneradmin/go/pkg/mod/github.com/urfave/cli@v1.22.5/app.go:405 +0x106c
2022-02-09T09:39:31.3323852Z github.com/urfave/cli.Command.startApp({{0x1647536, 0x8}, {0x0, 0x0}, {0x0, 0x0, 0x0}, {0x1671070, 0x28}, {0x0, ...}, ...}, ...)
2022-02-09T09:39:31.3324365Z C:/Users/runneradmin/go/pkg/mod/github.com/urfave/cli@v1.22.5/command.go:372 +0x108c
2022-02-09T09:39:31.3324838Z github.com/urfave/cli.Command.Run({{0x1647536, 0x8}, {0x0, 0x0}, {0x0, 0x0, 0x0}, {0x1671070, 0x28}, {0x0, ...}, ...}, ...)
2022-02-09T09:39:31.3325327Z C:/Users/runneradmin/go/pkg/mod/github.com/urfave/cli@v1.22.5/command.go:102 +0xe8c
2022-02-09T09:39:31.3325744Z github.com/urfave/cli.(*App).Run(0xc000323880, {0xc0004237a0, 0xb, 0x12})
2022-02-09T09:39:31.3326198Z C:/Users/runneradmin/go/pkg/mod/github.com/urfave/cli@v1.22.5/app.go:277 +0xa8c
2022-02-09T09:39:31.3326770Z github.com/nspcc-dev/neo-go/cli.(*executor).run(0xc0000709c0, {0xc0004237a0, 0xb, 0x12})
2022-02-09T09:39:31.3327275Z D:/a/neo-go/neo-go/cli/executor_test.go:273 +0x3a5
2022-02-09T09:39:31.3327812Z github.com/nspcc-dev/neo-go/cli.(*executor).Run(0x14aa020, 0xc000493950, {0xc0004237a0, 0xb, 0x12})
2022-02-09T09:39:31.3328324Z D:/a/neo-go/neo-go/cli/executor_test.go:263 +0x10f
2022-02-09T09:39:31.3328844Z github.com/nspcc-dev/neo-go/cli.TestContractInitAndCompile(0xc0001d69c0)
2022-02-09T09:39:31.3329377Z D:/a/neo-go/neo-go/cli/contract_test.go:155 +0x147f
2022-02-09T09:39:31.3329694Z testing.tRunner(0xc0001d69c0, 0x17b8be8)
2022-02-09T09:39:31.3330123Z C:/hostedtoolcache/windows/go/1.17.6/x64/src/testing/testing.go:1259 +0x230
2022-02-09T09:39:31.3330470Z created by testing.(*T).Run
2022-02-09T09:39:31.3330862Z C:/hostedtoolcache/windows/go/1.17.6/x64/src/testing/testing.go:1306 +0x727
2022-02-09T09:39:31.3331325Z FAIL github.com/nspcc-dev/neo-go/cli 5.552s
```
2022-02-10 18:58:44 +03:00
Evgeniy Stratonikov
b5afe24090
compiler: properly process defer
in conditional statements
...
Signed-off-by: Evgeniy Stratonikov <evgeniy@nspcc.ru>
2022-02-04 11:04:03 +03:00
Evgeniy Stratonikov
ed43b75631
compiler: do not traverse defer
function literals twice
...
Signed-off-by: Evgeniy Stratonikov <evgeniy@nspcc.ru>
2022-02-02 16:52:15 +03:00
Anna Shaleva
9c2e92d7d9
compiler: check overloaded methods for safeness one more time
...
It's possible that overloaded method is marked as `safe` in manifest, so
that it must have `save` field set to true after its name was
overwritten.
2022-01-21 18:03:04 +03:00
Evgeniy Stratonikov
ad65d1fa1f
compiler: implement custom logic for go1.15
...
For some reason `foo.go` is interpreted as an http URL, and even if we
replace it with `./foo.go` there is an errors with file missing on disk.
Because `CompileWithOptions` should be able to compile file under any
circumstances, we allocate temporary directory base on version used to
compile a binary.
Signed-off-by: Evgeniy Stratonikov <evgeniy@nspcc.ru>
2022-01-21 17:43:28 +03:00
Evgeniy Stratonikov
970769e5b2
compiler: allow to use _
in constants
...
When `_` is unused it can be omitted from constant values mapping.
Catched when compiling `netmap` contract from nspcc-dev/neofs-contract.
Signed-off-by: Evgeniy Stratonikov <evgeniy@nspcc.ru>
2022-01-20 13:52:58 +03:00
Evgeniy Stratonikov
548a6a06f1
compiler: speed up boolean expression short-circuit test
...
The amount of tests done is comparable to all other tests in compiler
package (~2k). After we moved to a new x/tools package this became a
bottleneck. In this commit we reduce the amount of compiled files by
combining multiple tests in a single file.
Signed-off-by: Evgeniy Stratonikov <evgeniy@nspcc.ru>
2022-01-20 13:21:26 +03:00
Evgeniy Stratonikov
9871dc8f5a
compiler: update x/tools package
...
Signed-off-by: Evgeniy Stratonikov <evgeniy@nspcc.ru>
2022-01-20 13:21:26 +03:00
Evgeniy Stratonikov
e7a0ecb349
compiler: provide .go
filename to Compile
...
First argument contains filename, thus we use '.go' suffix to
distinguish between directories and files.
Contract name should be provided in options.
Signed-off-by: Evgeniy Stratonikov <evgeniy@nspcc.ru>
2022-01-20 13:21:24 +03:00
Evgeniy Stratonikov
8af9c870b1
compiler: remove CompileWithDebugInfo
...
It is a simple wrapper over `CompileWithOptions` which we don't really
need. Custom options can be specified explicitly instead of using some
random default. This default was introduced in 1578904da
, however tests
written there use `CompileWithOptions` and all other tests
pass on that commit even without this default.
Signed-off-by: Evgeniy Stratonikov <evgeniy@nspcc.ru>
2022-01-20 13:15:48 +03:00
Evgeniy Stratonikov
46f623a48f
compiler/test: use public functions in tests
...
`CompileWithOptions` does exactly the thing we need.
Signed-off-by: Evgeniy Stratonikov <evgeniy@nspcc.ru>
2022-01-20 13:15:48 +03:00
Roman Khimov
299a7ea614
compiler: use CALLT for native contract calls, fix #2257
2021-12-10 11:58:50 +03:00
Roman Khimov
01d15ff473
Merge pull request #2270 from nspcc-dev/vm-invoked-contracts
...
Add invoked contract tracing
2021-12-01 11:27:27 +03:00
Roman Khimov
dbe184a335
Merge pull request #2280 from nspcc-dev/compiler-struct-cast
...
compiler: allow to slice struct field
2021-11-30 18:14:56 +03:00
Roman Khimov
f12f871432
compiler: use new defer stack for inlined functions, fix #2281
...
Inlined functions shouldn't care about outer scope defer statements, they
can't.
2021-11-30 18:04:02 +03:00
Roman Khimov
cddd5e1f6d
compiler: add a panic on internal lambda inconsistency
...
It's a bit better than behavior observer in #2281 (which is very cryptic).
2021-11-30 18:02:38 +03:00
Evgeniy Stratonikov
66a4245bef
compiler: allow to slice struct field
...
It makes no sense to restrict to identifiers.
2021-11-30 15:48:46 +03:00
AnnaShaleva
aefb6f9fee
*: fix tests failing due to path.Join usage
...
Solution:
Use `file/filepath` package to construct expected path. This package is OS-aware, see https://github.com/golang/go/issues/30616 .
2021-11-29 11:11:09 +03:00
Roman Khimov
b0a8f54776
vm: drop LoadArgs method, it's a Legacy remnant
2021-11-20 21:57:41 +03:00
Roman Khimov
765235eca3
vm: omit context parameter from Call()
...
It's not used and should not be used to switch from contract to contract.
2021-11-20 21:57:41 +03:00
Roman Khimov
a577d40de9
vm: move Jump method to the Context
...
Because it's only relevant for execution context itself.
2021-11-20 21:57:35 +03:00
Roman Khimov
7fa58a4dc8
Merge pull request #2255 from nspcc-dev/compiler-noreturn-defers
...
compiler: correctly handle defer in functions without return values
2021-11-15 10:43:00 +03:00
Roman Khimov
db99368e96
compiler: optimize GAS cost of type conversion
...
CONVERT call base price is 8192. DUP, ISTYPE and JMPIF all cost 2. So we add
0.07% overhead in the worst case and save 99.93% otherwise.
At the same time, old code was just two bytes and new one is seven, but I
think it's tolerable considering how much GAS it can potentially save.
Fix #2250 .
2021-11-12 19:58:21 +03:00
Roman Khimov
a91581fa16
compiler: correctly handle defer in functions without return values
...
Fix #2253 .
2021-11-12 19:36:59 +03:00
Roman Khimov
410aabe7a1
compiler: drop some useless NOPs
...
They're all obsolete and not needed.
2021-11-12 17:19:59 +03:00
Roman Khimov
0d50730382
compiler: optimize map initialization with PACKMAP
2021-11-12 17:19:59 +03:00
Roman Khimov
a8befeea33
compiler: optimize new empty struct creation with PACKSTRUCT
2021-11-12 17:19:59 +03:00
Roman Khimov
909ea477f4
compiler: create arrays/structs more effectively
...
Use PACK/PACKSTRUCT.
2021-11-12 17:19:59 +03:00
Evgeniy Stratonikov
7758378d28
compiler: allow to overload methods in manifest
...
Signed-off-by: Evgeniy Stratonikov <evgeniy@nspcc.ru>
2021-10-29 20:15:21 +03:00