Skip to content

Commit

Permalink
Now support a bunch of other snapshot sections. Better support for
Browse files Browse the repository at this point in the history
the different index types in contract tables.

Not yet exported, but can be done shortly!

Export `LastPos()` on a `Decoder`, to aid in going through a large blob
of packed content.
  • Loading branch information
abourget committed Jul 20, 2020
1 parent 48d4609 commit 55261c7
Show file tree
Hide file tree
Showing 9 changed files with 667 additions and 226 deletions.
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Unpacking binary `TransactionReceipt` type will now correctly set the inner `TransactionWithID.ID` field correctly.
- Unpacking binary `BlockState` now correctly works but is restricted to EOSIO 2.0.x version.

### Deprecated
- Renamed `JSONFloat64` to `Float64`, to follow the same convention that was changed years ago with `Uint64`, etc. Type alias left for backwards compatibility.

### Changed
- **BREAKING**: Fixed binary unpacking of `BlockState`, `TransactionTrace`, `SignedTransaction`, `Action` (and some inner types). This required changing a few struct fields to better fit with EOSIO definition, here the full list:
- `MerkleRoot.ActiveNodes` is now a `[]Checksum256`, was previously `[]string`
Expand Down
22 changes: 17 additions & 5 deletions decoder.go
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,10 @@ type optionalFieldType bool

const OptionalField optionalFieldType = true

func (d *Decoder) LastPos() int {
return d.pos
}

func (d *Decoder) Decode(v interface{}, options ...DecodeOption) (err error) {
optionalField := false
for _, option := range options {
Expand All @@ -162,10 +166,13 @@ func (d *Decoder) Decode(v interface{}, options ...DecodeOption) (err error) {
}

if optionalField {
isPresent, e := d.ReadByte()
if e != nil {
err = fmt.Errorf("decode: %t isPresent, %s", v, e)
return
var isPresent byte
if d.hasRemaining() {
isPresent, err = d.ReadByte()
if err != nil {
err = fmt.Errorf("decode: %t isPresent, %s", v, err)
return
}
}

if isPresent == 0 {
Expand Down Expand Up @@ -277,7 +284,7 @@ func (d *Decoder) Decode(v interface{}, options ...DecodeOption) (err error) {
n, err = d.ReadUint64()
rv.SetUint(uint64(n))
return
case *JSONFloat64:
case *Float64:
var n float64
n, err = d.ReadFloat64()
rv.SetFloat(n)
Expand Down Expand Up @@ -357,6 +364,11 @@ func (d *Decoder) Decode(v interface{}, options ...DecodeOption) (err error) {
ts, err = d.ReadTstamp()
rv.Set(reflect.ValueOf(ts))
return
case *TimePoint:
var tp TimePoint
tp, err = d.ReadTimePoint()
rv.Set(reflect.ValueOf(tp))
return
case *BlockTimestamp:
var bt BlockTimestamp
bt, err = d.ReadBlockTimestamp()
Expand Down
16 changes: 8 additions & 8 deletions responses.go
Original file line number Diff line number Diff line change
Expand Up @@ -407,14 +407,14 @@ type Global struct {
}

type Producer struct {
Owner string `json:"owner"`
TotalVotes float64 `json:"total_votes,string"`
ProducerKey string `json:"producer_key"`
IsActive int `json:"is_active"`
URL string `json:"url"`
UnpaidBlocks int `json:"unpaid_blocks"`
LastClaimTime JSONFloat64 `json:"last_claim_time"`
Location int `json:"location"`
Owner string `json:"owner"`
TotalVotes float64 `json:"total_votes,string"`
ProducerKey string `json:"producer_key"`
IsActive int `json:"is_active"`
URL string `json:"url"`
UnpaidBlocks int `json:"unpaid_blocks"`
LastClaimTime Float64 `json:"last_claim_time"`
Location int `json:"location"`
}
type ProducersResp struct {
Producers []Producer `json:"producers"`
Expand Down
54 changes: 26 additions & 28 deletions snapshot/snapshot_test.go
Original file line number Diff line number Diff line change
@@ -1,13 +1,10 @@
package snapshot

import (
"encoding/json"
"fmt"
"io"
"io/ioutil"
"testing"

"github.com/eoscanada/eos-go"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
Expand All @@ -27,7 +24,8 @@ func TestSnapshotRead(t *testing.T) {

for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
filename := "/tmp/0125111385-07750c59b24ed52d2dbf2048b67b58e9c9bd53ff5cc4550277718c1d5d800f73-snapshot.bin"
filename := "/tmp/0125111385-07750c59b24ed52d2dbf2048b67b58e9c9bd53ff5cc4550277718c1d5d800f73-snapshot.bin" // mainnet
//filename := "/tmp/0003212331-0031042b02b2cf711fee6e1e24da94101fa6c1ea9ece568d5f13232473429db1-snapshot.bin" // kylin
r, err := NewReader(filename)
fmt.Println("Filename", filename)
defer r.Close()
Expand All @@ -45,49 +43,49 @@ func TestSnapshotRead(t *testing.T) {

switch section.Name {
case "eosio::chain::chain_snapshot_header":
case "eosio::chain::block_state":
cnt := make([]byte, section.BufferSize)
_, err := section.Buffer.Read(cnt)
//fmt.Println(hex.EncodeToString(cnt))
require.NoError(t, err)
var state eos.BlockState
assert.NoError(t, eos.UnmarshalBinary(cnt, &state))
cnt, _ = json.MarshalIndent(state, " ", " ")
fmt.Println(string(cnt))

case "eosio::chain::account_object":
require.NoError(t, readAccountObjects(section.Buffer, section.RowCount))
cnt := make([]byte, section.BufferSize)
_, err := section.Buffer.Read(cnt)
require.NoError(t, err)
require.NoError(t, readChainSnapshotHeader(section))
case "eosio::chain::genesis_state":
// // THIS SEEMS TO EXIST ONLY IN VERSION 2 OF THE SNAPSHOT FILE FORMAT.
// // FOR NOW, WE ARE CONCENTRATING ON VERSION 3 (latest)
// cnt := make([]byte, section.BufferSize)
// _, err := section.Buffer.Read(cnt)
// require.NoError(t, err)

require.NoError(t, ioutil.WriteFile("/tmp/test.dat", cnt, 0664))

var accounts []AccountObject
assert.NoError(t, eos.UnmarshalBinary(cnt, &accounts))
cnt, _ = json.MarshalIndent(accounts, " ", " ")
fmt.Println(string(cnt))
// var state GenesisState
// assert.NoError(t, eos.UnmarshalBinary(cnt, &state))
// cnt, _ = json.MarshalIndent(state, " ", " ")
// fmt.Println(string(cnt))

case "eosio::chain::block_state":
// require.NoError(t, readBlockState(section))
case "eosio::chain::account_object":
// require.NoError(t, readAccountObjects(section))
case "eosio::chain::account_metadata_object":
//require.NoError(t, readAccountMetadataObjects(section))
case "eosio::chain::account_ram_correction_object":
//require.NoError(t, readAccountRAMCorrectionObject(section))
case "eosio::chain::global_property_object":
//require.NoError(t, readGlobalPropertyObject(section))
case "eosio::chain::protocol_state_object":
//require.NoError(t, readProtocolStateObject(section))
case "eosio::chain::dynamic_global_property_object":
// require.NoError(t, readDynamicGlobalPropertyObject(section))
case "eosio::chain::block_summary_object":
//require.NoError(t, readBlockSummary(section))
case "eosio::chain::transaction_object":
case "eosio::chain::generated_transaction_object":
case "eosio::chain::code_object":
case "contract_tables":
err := readContractTables(section.Buffer)
require.NoError(t, err)
require.NoError(t, readContractTables(section))
case "eosio::chain::permission_object":
//require.NoError(t, readPermissionObject(section))
case "eosio::chain::permission_link_object":
case "eosio::chain::resource_limits::resource_limits_object":
case "eosio::chain::resource_limits::resource_usage_object":
case "eosio::chain::resource_limits::resource_limits_state_object":
case "eosio::chain::resource_limits::resource_limits_config_object":
default:
panic("unsupported section")
panic("unsupported section: " + section.Name)
}
}
fmt.Println("Done")
Expand Down
179 changes: 0 additions & 179 deletions snapshot/types.go

This file was deleted.

34 changes: 34 additions & 0 deletions snapshot/typesv2.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package snapshot

import (
"github.com/eoscanada/eos-go"
"github.com/eoscanada/eos-go/ecc"
)

type GenesisState struct {
//InitialConfiguration ChainConfig //eos.ChainConfig
InitialTimestamp eos.TimePoint
InitialKey ecc.PublicKey
}

type ChainConfig struct {
MaxBlockNetUsage eos.Uint64 ///< the maxiumum net usage in instructions for a block
TargetBlockNetUsagePct uint32 ///< the target percent (1% == 100, 100%= 10,000) of maximum net usage; exceeding this triggers congestion handling
MaxTransactionNetUsage uint32 ///< the maximum objectively measured net usage that the chain will allow regardless of account limits
BasePerTransactionNetUsage uint32 ///< the base amount of net usage billed for a transaction to cover incidentals
NetUsageLeeway uint32
ContextFreeDiscountNetUsageNum uint32 ///< the numerator for the discount on net usage of context-free data
ContextFreeDiscountNetUsageDen uint32 ///< the denominator for the discount on net usage of context-free data

MaxBlockCpuUsage uint32 ///< the maxiumum billable cpu usage (in microseconds) for a block
TargetBlockCpuUsagePct uint32 ///< the target percent (1% == 100, 100%= 10,000) of maximum cpu usage; exceeding this triggers congestion handling
MaxTransactionCpuUsage uint32 ///< the maximum billable cpu usage (in microseconds) that the chain will allow regardless of account limits
MinTransactionCpuUsage uint32 ///< the minimum billable cpu usage (in microseconds) that the chain requires

MaxTransactionLifetime uint32 ///< the maximum number of seconds that an input transaction's expiration can be ahead of the time of the block in which it is first included
DeferredTrxExpirationWindow uint32 ///< the number of seconds after the time a deferred transaction can first execute until it expires
MaxTransactionDelay uint32 ///< the maximum number of seconds that can be imposed as a delay requirement by authorization checks
MaxInlineActionSize uint32 ///< maximum allowed size (in bytes) of an inline action
MaxInlineActionDepth uint16 ///< recursion depth limit on sending inline actions
MaxAuthorityDepth uint16 ///< recursion depth limit for checking if an authority is satisfied
}
Loading

0 comments on commit 55261c7

Please sign in to comment.