Skip to content

Commit

Permalink
Merge pull request #37 from tonindexer/v0.4.1-dev
Browse files Browse the repository at this point in the history
v0.4.1
  • Loading branch information
iam047801 authored May 10, 2024
2 parents a17ca00 + 384bf40 commit b4d7ce6
Show file tree
Hide file tree
Showing 41 changed files with 2,029 additions and 146 deletions.
18 changes: 14 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
# Anton

This project is an open-source tool that extracts and organizes data from the TON blockchain,
efficiently storing it in PostgreSQL and ClickHouse databases.
efficiently storing it in PostgreSQL and ClickHouse databases.

If you have any questions, you can ask them in the [Telegram group](https://t.me/tonindexer_chat).

## Overview

Expand Down Expand Up @@ -157,10 +159,18 @@ docker compose -f docker-compose.yml -f docker-compose.prod.yml up -d
```

To run Anton, you need at least one defined contract interface.
There are some known interfaces in the [abi/known](/abi/known) directory.
You can add them through this command:
You can find some known interfaces in the [abi/known](/abi/known) directory.
These can be added during the initial startup of the indexer:

```shell
docker compose exec rescan sh -c "anton contract addInterfaces /var/anton/known/*.json"
# If you are running the indexer without Docker,
# you need to specify the directory containing the known contracts:
anton indexer --contract-dir /root/anton/abi/known

# If you are running it using Docker,
# there is no need to specify the contracts directory,
# as they are already included in the container:
docker compose up -d indexer
```

### Database schema migration
Expand Down
245 changes: 245 additions & 0 deletions abi/abi.schema.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,245 @@
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "https://tvm.sh/abi.schema.json",
"type": "array",
"items": {
"type": "object",
"properties": {
"interface_name": {
"type": "string",
"pattern": "^([a-z0-9_]+)$"
},
"addresses": {
"type": "array",
"items": {
"type": "string"
}
},
"definitions": {
"type": "object",
"patternProperties": {
"^([a-z0-9_]+)\\.([a-z0-9_]+)\\.([a-z0-9_]+)$": {
"type": "array",
"items": {
"$ref": "#/$defs/tlb_value"
}
}
}
},
"code_boc": {
"type": "string"
},
"get_methods": {
"type": "array",
"items": {
"type": "object",
"properties": {
"name": {
"type": "string"
},
"arguments": {
"type": "array",
"items": {
"$ref": "#/$defs/vm_value"
}
},
"return_values": {
"type": "array",
"items": {
"$ref": "#/$defs/vm_value"
}
}
},
"required": [
"name",
"return_values"
],
"additionalProperties": false
}
},
"in_messages": {
"type": "array",
"items": {
"$ref": "#/$defs/message"
}
},
"out_messages": {
"type": "array",
"items": {
"$ref": "#/$defs/message"
}
}
},
"required": [
"interface_name"
],
"additionalProperties": false
},
"$defs": {
"vm_value": {
"type": "object",
"properties": {
"name": {
"type": "string"
},
"stack_type": {
"enum": [
"int",
"cell",
"slice"
]
},
"format": {
"enum": [
"bigInt",
"uint8",
"uint16",
"uint32",
"uint64",
"int8",
"int16",
"int32",
"int64",
"bool",
"bytes",
"cell",
"slice",
"string",
"addr",
"content",
"struct",
"asset",
"dedustAsset"
]
},
"struct_fields": {
"type": "array",
"items": {
"$ref": "#/$defs/tlb_value"
}
}
},
"required": [
"name",
"stack_type"
]
},
"tlb_value": {
"type": "object",
"properties": {
"name": {
"type": "string",
"pattern": "^[a-z0-9_]+$"
},
"tlb_type": {
"oneOf": [
{
"enum": [
".",
"^",
"bool",
"addr"
]
},
{
"type": "string",
"pattern": "^#[a-f0-9]+$"
},
{
"type": "string",
"pattern": "^\\[[^\\]]+\\]$"
},
{
"type": "string",
"pattern": "^\\$[01]+$"
},
{
"type": "string",
"pattern": "^(##|bits) \\d{1,3}$"
},
{
"type": "string",
"pattern": "^maybe (\\^)$"
},
{
"type": "string",
"pattern": "^either ([\\^.]) ([\\^.])$"
}
]
},
"format": {
"enum": [
"bool",
"int8",
"int16",
"int32",
"int64",
"uint8",
"uint16",
"uint32",
"uint64",
"bigInt",
"coins",
"bytes",
"string",
"addr",
"cell",
"dict",
"tag",
"telemintText",
"asset",
"struct",
"dedustAsset"
]
},
"struct_fields": {
"type": "array",
"items": {
"$ref": "#/$defs/tlb_value"
}
},
"optional": {
"type": "boolean"
}
},
"required": [
"name",
"tlb_type"
],
"additionalProperties": false
},
"message": {
"type": "object",
"properties": {
"op_name": {
"type": "string"
},
"op_code": {
"type": "string",
"pattern": "^0x([0-9a-f]{1,8})$"
},
"type": {
"enum": [
"INTERNAL",
"EXTERNAL_IN",
"EXTERNAL_OUT",
"internal",
"external_in",
"external_out"
]
},
"body": {
"type": "array",
"items": {
"$ref": "#/$defs/tlb_value"
}
}
},
"required": [
"op_name",
"op_code"
],
"additionalProperties": false
}
}
}
20 changes: 15 additions & 5 deletions abi/get.go
Original file line number Diff line number Diff line change
Expand Up @@ -82,10 +82,15 @@ func HasGetMethod(code *cell.Cell, getMethodName string) bool {
return false
}

if dict.GetByIntKey(big.NewInt(hash)) != nil {
return true
s, err := dict.LoadValueByIntKey(big.NewInt(hash))
if err != nil {
return false
}
if _, err := s.ToCell(); err != nil {
return false
}
return false

return true
}

func GetMethodHashes(code *cell.Cell) ([]int32, error) {
Expand All @@ -96,8 +101,13 @@ func GetMethodHashes(code *cell.Cell) ([]int32, error) {
return nil, errors.Wrap(err, "get methods dict")
}

for _, kv := range dict.All() {
i, err := kv.Key.BeginParse().LoadUInt(getMethodsDictKeySz)
dictKV, err := dict.LoadAll()
if err != nil {
return nil, errors.Wrapf(err, "dict load all")
}

for _, kv := range dictKV {
i, err := kv.Key.LoadUInt(getMethodsDictKeySz)
if err != nil {
return nil, errors.Wrap(err, "load uint")
}
Expand Down
27 changes: 24 additions & 3 deletions abi/get_emulator.go
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,13 @@ func vmMakeValueInt(v *VmValue) (ret tlb.VmStackValue, _ error) {
case "int64":
ui, uok := v.Payload.(int64)
bi, ok = big.NewInt(ui), uok
case "bool":
b, uok := v.Payload.(bool)
ui := 0
if b {
ui = 1
}
bi, ok = big.NewInt(int64(ui)), uok
case "bytes":
ui, uok := v.Payload.([]byte)
bi, ok = new(big.Int).SetBytes(ui), uok
Expand Down Expand Up @@ -162,8 +169,16 @@ func vmMakeValueCell(v *VmValue) (tlb.VmStackValue, error) {
var err error
c, err = tutlb.ToCell(v.Payload)
if err != nil {
return tlb.VmStackValue{}, err
return tlb.VmStackValue{}, errors.Wrapf(err, "'%s' argument to cell", v.Name)
}
ok = true
default:
var err error
c, err = tutlb.ToCell(v.Payload)
if err != nil {
return tlb.VmStackValue{}, errors.Wrapf(err, "'%s' argument to cell with '%s' format", v.Name, v.Format)
}
ok = true
}
if !ok {
return tlb.VmStackValue{}, errors.Wrapf(ErrWrongValueFormat, "'%s' type with '%s' format", v.StackType, v.Format)
Expand Down Expand Up @@ -210,9 +225,15 @@ func vmMakeValueSlice(v *VmValue) (tlb.VmStackValue, error) {
case TLBStructCell:
c, err := tutlb.ToCell(v.Payload)
if err != nil {
return tlb.VmStackValue{}, err
return tlb.VmStackValue{}, errors.Wrapf(err, "'%s' argument to cell", v.Name)
}
s, ok = c.BeginParse(), true
default:
c, err := tutlb.ToCell(v.Payload)
if err != nil {
return tlb.VmStackValue{}, errors.Wrapf(err, "'%s' argument to cell with '%s' format", v.Name, v.Format)
}
s = c.BeginParse()
s, ok = c.BeginParse(), true
}
if !ok {
return tlb.VmStackValue{}, errors.Wrapf(ErrWrongValueFormat, "'%s' type with '%s' format", v.StackType, v.Format)
Expand Down
Loading

0 comments on commit b4d7ce6

Please sign in to comment.