diff --git a/snapshot/snapshot_test.go b/snapshot/snapshot_test.go index f0b6e186..ca0d419f 100644 --- a/snapshot/snapshot_test.go +++ b/snapshot/snapshot_test.go @@ -1,10 +1,13 @@ 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" ) @@ -40,12 +43,51 @@ func TestSnapshotRead(t *testing.T) { assert.NoError(t, err) fmt.Println("Section", section.Name, "rows", section.RowCount, "bytes", section.BufferSize) - if section.Name == "contract_tables" { + 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, 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)) + + case "eosio::chain::account_metadata_object": + case "eosio::chain::account_ram_correction_object": + case "eosio::chain::global_property_object": + case "eosio::chain::protocol_state_object": + case "eosio::chain::dynamic_global_property_object": + case "eosio::chain::block_summary_object": + 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) - // dt := make([]byte, 10000) - // _, _ = section.Buffer.Read(dt) - // _ = ioutil.WriteFile("/tmp/test.dat", dt, 0644) + case "eosio::chain::permission_object": + 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") } } fmt.Println("Done") diff --git a/snapshot/types.go b/snapshot/types.go index f7888bda..2ce570f4 100644 --- a/snapshot/types.go +++ b/snapshot/types.go @@ -5,6 +5,7 @@ import ( "encoding/binary" "encoding/hex" "fmt" + "time" "github.com/eoscanada/eos-go" ) @@ -122,3 +123,57 @@ func readContractTables(buf *bufio.Reader) error { // shared_blob value; // }; // } + +type AccountObject struct { + Name eos.AccountName + CreationDate eos.BlockTimestamp + RawABI []byte +} + +func readAccountObjects(buf *bufio.Reader, count uint64) error { + for i := uint64(0); i < count; i++ { + a := AccountObject{} + cnt := make([]byte, 12) + _, err := buf.Read(cnt) + if err != nil { + return err + } + + if err := eos.UnmarshalBinary(cnt[:8], &a.Name); err != nil { + return err + } + + if err := eos.UnmarshalBinary(cnt[8:12], &a.CreationDate); err != nil { + return err + } + + val, err := readByteArray(buf) + if err != nil { + return err + } + + a.RawABI = val + + fmt.Println("Account", a.Name, "created", a.CreationDate.Format(time.RFC3339), "abi length", len(val)) + } + return nil +} + +func readByteArray(buf *bufio.Reader) ([]byte, error) { + valueSize, err := binary.ReadUvarint(buf) + if err != nil { + return nil, err + } + + val := make([]byte, valueSize) + + written, err := buf.Read(val) + if err != nil { + return nil, err + } + if uint64(written) != valueSize { + return nil, fmt.Errorf("inconsistent read, expected %d bytes, read %d", valueSize, written) + } + + return val, nil +}