From 53047fa88859bbeffe4a545567c090495cac111e Mon Sep 17 00:00:00 2001 From: gagliardetto Date: Mon, 17 Jul 2023 21:14:10 +0200 Subject: [PATCH] Add blockHeight to schema --- cmd-rpc-server-car-getBlock.go | 44 ++--- cmd-rpc-server-car-getSignaturesForAddress.go | 2 +- cmd-rpc-server-car.go | 5 - cmd-x-index-all.go | 33 +--- go.mod | 5 +- index-sig-to-cid.go | 55 +++---- ipld/ipldbindcode/ledger.ipldsch | 4 +- ipld/ipldbindcode/methods.go | 10 ++ ipld/ipldbindcode/non-generated-types.go | 6 + ipld/ipldbindcode/types.go | 12 +- ipld/ipldsch/ipldsch_satisfaction.go | 150 +++++++++++++++--- ipld/ipldsch/ipldsch_types.go | 5 +- ledger.ipldsch | 2 + 13 files changed, 219 insertions(+), 114 deletions(-) create mode 100644 ipld/ipldbindcode/non-generated-types.go diff --git a/cmd-rpc-server-car-getBlock.go b/cmd-rpc-server-car-getBlock.go index 9af972ab..be4171e7 100644 --- a/cmd-rpc-server-car-getBlock.go +++ b/cmd-rpc-server-car-getBlock.go @@ -167,7 +167,7 @@ func (ser *rpcServer) handleGetBlock(ctx context.Context, conn *requestContext, tim.time("get entries") var allTransactions []GetTransactionResponse - var rewards any // TODO: implement rewards as in solana + var rewards any hasRewards := !block.Rewards.(cidlink.Link).Cid.Equals(DummyCID) if hasRewards { rewardsNode, err := ser.GetRewardsByCid(ctx, block.Rewards.(cidlink.Link).Cid) @@ -333,8 +333,14 @@ func (ser *rpcServer) handleGetBlock(ctx context.Context, conn *requestContext, blockResp.BlockTime = &blocktime blockResp.Blockhash = lastEntryHash.String() blockResp.ParentSlot = uint64(block.Meta.Parent_slot) - blockResp.Rewards = rewards // TODO: implement rewards as in solana - blockResp.BlockHeight = calcBlockHeight(uint64(block.Slot)) // TODO: implement block height + blockResp.Rewards = rewards + + { + blockHeight, ok := block.GetBlockHeight() + if ok { + blockResp.BlockHeight = blockHeight + } + } { // get parent slot parentSlot := uint64(block.Meta.Parent_slot) @@ -352,27 +358,27 @@ func (ser *rpcServer) handleGetBlock(ctx context.Context, conn *requestContext, return } - lastEntryCidOfParent := parentBlock.Entries[len(parentBlock.Entries)-1] - parentEntryNode, err := ser.GetEntryByCid(ctx, lastEntryCidOfParent.(cidlink.Link).Cid) - if err != nil { - klog.Errorf("failed to decode Entry: %v", err) - conn.ReplyWithError( - ctx, - req.ID, - &jsonrpc2.Error{ - Code: jsonrpc2.CodeInternalError, - Message: "Internal error", - }) - return + if len(parentBlock.Entries) > 0 { + lastEntryCidOfParent := parentBlock.Entries[len(parentBlock.Entries)-1] + parentEntryNode, err := ser.GetEntryByCid(ctx, lastEntryCidOfParent.(cidlink.Link).Cid) + if err != nil { + klog.Errorf("failed to decode Entry: %v", err) + conn.ReplyWithError( + ctx, + req.ID, + &jsonrpc2.Error{ + Code: jsonrpc2.CodeInternalError, + Message: "Internal error", + }) + return + } + parentEntryHash := solana.HashFromBytes(parentEntryNode.Hash) + blockResp.PreviousBlockhash = parentEntryHash.String() } - parentEntryHash := solana.HashFromBytes(parentEntryNode.Hash) - blockResp.PreviousBlockhash = parentEntryHash.String() } } tim.time("get parent block") - // TODO: get all the transactions from the block - // reply with the data err = conn.Reply( ctx, req.ID, diff --git a/cmd-rpc-server-car-getSignaturesForAddress.go b/cmd-rpc-server-car-getSignaturesForAddress.go index dca97add..d7f09d2b 100644 --- a/cmd-rpc-server-car-getSignaturesForAddress.go +++ b/cmd-rpc-server-car-getSignaturesForAddress.go @@ -207,7 +207,7 @@ func (ser *rpcServer) handleGetSignaturesForAddress(ctx context.Context, conn *r slot := uint64(transactionNode.Slot) response[ii]["slot"] = slot response[ii]["blockTime"] = getBlockTime(slot) - response[ii]["confirmationStatus"] = "finalized" // TODO: is this correct? + response[ii]["confirmationStatus"] = "finalized" } return nil }) diff --git a/cmd-rpc-server-car.go b/cmd-rpc-server-car.go index e87e6810..35ea17f3 100644 --- a/cmd-rpc-server-car.go +++ b/cmd-rpc-server-car.go @@ -944,8 +944,3 @@ func parseTransactionAndMetaFromNode( } return } - -func calcBlockHeight(slot uint64) uint64 { - // TODO: fix this - return 0 -} diff --git a/cmd-x-index-all.go b/cmd-x-index-all.go index 85aca559..0be896ca 100644 --- a/cmd-x-index-all.go +++ b/cmd-x-index-all.go @@ -12,7 +12,6 @@ import ( "github.com/davecgh/go-spew/spew" "github.com/dustin/go-humanize" - bin "github.com/gagliardetto/binary" "github.com/gagliardetto/solana-go" "github.com/ipfs/go-cid" carv1 "github.com/ipld/go-car" @@ -231,20 +230,10 @@ func createAllIndexes( return nil, fmt.Errorf("failed to decode transaction: %w", err) } - var tx solana.Transaction - txBuffer := new(bytes.Buffer) - txBuffer.Write(txNode.Data.Bytes()) - if total, ok := txNode.Data.GetTotal(); ok && total > 1 { - // TODO: handle this case - klog.Infof("skipping transaction with %d partials", total) - continue - } - if err := bin.UnmarshalBin(&tx, txBuffer.Bytes()); err != nil { - return nil, fmt.Errorf("failed to unmarshal transaction: %w", err) - } else if len(tx.Signatures) == 0 { - panic("no signatures") + sig, err := readFirstSignature(txNode.Data.Bytes()) + if err != nil { + return nil, fmt.Errorf("failed to read signature: %w", err) } - sig := tx.Signatures[0] err = sig_to_cid.Put(sig, _cid) if err != nil { @@ -616,20 +605,10 @@ func verifyAllIndexes( return fmt.Errorf("failed to decode transaction: %w", err) } - var tx solana.Transaction - txBuffer := new(bytes.Buffer) - txBuffer.Write(txNode.Data.Bytes()) - if total, ok := txNode.Data.GetTotal(); ok && total > 1 { - // TODO: handle this case - klog.Infof("skipping transaction with %d partials", total) - continue - } - if err := bin.UnmarshalBin(&tx, txBuffer.Bytes()); err != nil { - return fmt.Errorf("failed to unmarshal transaction: %w", err) - } else if len(tx.Signatures) == 0 { - panic("no signatures") + sig, err := readFirstSignature(txNode.Data.Bytes()) + if err != nil { + return fmt.Errorf("failed to read signature: %w", err) } - sig := tx.Signatures[0] got, err := sig_to_cid.Get(sig) if err != nil { diff --git a/go.mod b/go.mod index 2d29ef15..dc61dee4 100644 --- a/go.mod +++ b/go.mod @@ -59,11 +59,12 @@ require ( require ( github.com/ipld/go-car v0.5.0 + github.com/mr-tron/base58 v1.2.0 github.com/patrickmn/go-cache v2.1.0+incompatible github.com/ronanh/intcomp v1.1.0 github.com/tejzpr/ordered-concurrently/v3 v3.0.1 github.com/valyala/fasthttp v1.47.0 - gopkg.in/yaml.v2 v2.4.0 + gopkg.in/yaml.v3 v3.0.1 k8s.io/klog v1.0.0 ) @@ -155,7 +156,6 @@ require ( github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/reflect2 v1.0.2 // indirect github.com/mostynb/zstdpool-freelist v0.0.0-20201229113212-927304c0c3b1 // indirect - github.com/mr-tron/base58 v1.2.0 // indirect github.com/multiformats/go-base32 v0.1.0 // indirect github.com/multiformats/go-base36 v0.2.0 // indirect github.com/multiformats/go-multiaddr-dns v0.3.1 // indirect @@ -204,7 +204,6 @@ require ( golang.org/x/text v0.8.0 // indirect golang.org/x/tools v0.7.0 // indirect golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 // indirect - gopkg.in/yaml.v3 v3.0.1 // indirect lukechampine.com/blake3 v1.1.7 // indirect nhooyr.io/websocket v1.8.7 // indirect ) diff --git a/index-sig-to-cid.go b/index-sig-to-cid.go index 232ba840..c1e0585d 100644 --- a/index-sig-to-cid.go +++ b/index-sig-to-cid.go @@ -1,7 +1,6 @@ package main import ( - "bytes" "context" "fmt" "os" @@ -82,20 +81,10 @@ func CreateIndex_sig2cid(ctx context.Context, tmpDir string, carPath string, ind ctx, dr, func(c cid.Cid, txNode *ipldbindcode.Transaction) error { - var tx solana.Transaction - txBuffer := new(bytes.Buffer) - txBuffer.Write(txNode.Data.Bytes()) - if total, ok := txNode.Data.GetTotal(); ok && total > 1 { - // TODO: handle this case - klog.Infof("skipping transaction with %d partials", total) - return nil - } - if err := bin.UnmarshalBin(&tx, txBuffer.Bytes()); err != nil { - return fmt.Errorf("failed to unmarshal transaction: %w", err) - } else if len(tx.Signatures) == 0 { - panic("no signatures") + sig, err := readFirstSignature(txNode.Data.Bytes()) + if err != nil { + return fmt.Errorf("failed to read signature: %w", err) } - sig := tx.Signatures[0] var buf [36]byte copy(buf[:], c.Bytes()[:36]) @@ -193,20 +182,10 @@ func VerifyIndex_sig2cid(ctx context.Context, carPath string, indexFilePath stri ctx, dr, func(c cid.Cid, txNode *ipldbindcode.Transaction) error { - var tx solana.Transaction - txBuffer := new(bytes.Buffer) - txBuffer.Write(txNode.Data.Bytes()) - if total, ok := txNode.Data.GetTotal(); ok && total > 1 { - // TODO: handle this case - klog.Infof("skipping transaction with %d partials", total) - return nil - } - if err := bin.UnmarshalBin(&tx, txBuffer.Bytes()); err != nil { - return fmt.Errorf("failed to unmarshal transaction: %w", err) - } else if len(tx.Signatures) == 0 { - panic("no signatures") + sig, err := readFirstSignature(txNode.Data.Bytes()) + if err != nil { + return fmt.Errorf("failed to read signature: %w", err) } - sig := tx.Signatures[0] got, err := findCidFromSignature(c2o, sig) if err != nil { @@ -248,3 +227,25 @@ func findCidFromSignature(db *compactindex36.DB, sig solana.Signature) (cid.Cid, } return c, nil } + +func readFirstSignature(buf []byte) (solana.Signature, error) { + decoder := bin.NewCompactU16Decoder(buf) + numSigs, err := decoder.ReadCompactU16() + if err != nil { + return solana.Signature{}, err + } + if numSigs == 0 { + return solana.Signature{}, fmt.Errorf("no signatures") + } + + // Read the first signature: + var sig solana.Signature + numRead, err := decoder.Read(sig[:]) + if err != nil { + return solana.Signature{}, err + } + if numRead != 64 { + return solana.Signature{}, fmt.Errorf("unexpected signature length %d", numRead) + } + return sig, nil +} diff --git a/ipld/ipldbindcode/ledger.ipldsch b/ipld/ipldbindcode/ledger.ipldsch index 78cb7a13..1350b392 100644 --- a/ipld/ipldbindcode/ledger.ipldsch +++ b/ipld/ipldbindcode/ledger.ipldsch @@ -47,6 +47,8 @@ type SlotMeta struct { parent_slot Int # Block time of this slot. blocktime Int + # Block height of this slot. + block_height nullable optional Int } representation tuple type Shredding struct { @@ -70,7 +72,7 @@ type Transaction struct { metadata DataFrame # The slot number where this transaction was created. slot Int - # The index of this transaction in the the block (0-indexed). + # The index of the position of this transaction in the block (0-indexed). index nullable optional Int } representation tuple diff --git a/ipld/ipldbindcode/methods.go b/ipld/ipldbindcode/methods.go index f1593cc9..ce3a0158 100644 --- a/ipld/ipldbindcode/methods.go +++ b/ipld/ipldbindcode/methods.go @@ -109,3 +109,13 @@ func (n Transaction) GetPositionIndex() (int, bool) { } return **n.Index, true } + +// GetBlockHeight returns the 'block_height' field, which indicates +// the height of the block, and +// a flag indicating whether the field has a value. +func (n Block) GetBlockHeight() (uint64, bool) { + if n.Meta.Block_height == nil || *n.Meta.Block_height == nil { + return 0, false + } + return uint64(**n.Meta.Block_height), true +} diff --git a/ipld/ipldbindcode/non-generated-types.go b/ipld/ipldbindcode/non-generated-types.go new file mode 100644 index 00000000..eb381e0a --- /dev/null +++ b/ipld/ipldbindcode/non-generated-types.go @@ -0,0 +1,6 @@ +package ipldbindcode + +type ( + Hash []uint8 + Buffer []uint8 +) diff --git a/ipld/ipldbindcode/types.go b/ipld/ipldbindcode/types.go index 1f47c1eb..399837e7 100644 --- a/ipld/ipldbindcode/types.go +++ b/ipld/ipldbindcode/types.go @@ -10,7 +10,6 @@ type ( Subsets List__Link } ) - type Subset struct { Kind int First int @@ -28,15 +27,15 @@ type ( Rewards datamodel.Link } ) - type Rewards struct { Kind int Slot int Data DataFrame } type SlotMeta struct { - Parent_slot int - Blocktime int + Parent_slot int + Blocktime int + Block_height **int } type Shredding struct { EntryEndIdx int @@ -63,8 +62,3 @@ type DataFrame struct { Data []uint8 Next **List__Link } - -type ( - Hash []uint8 - Buffer []uint8 -) diff --git a/ipld/ipldsch/ipldsch_satisfaction.go b/ipld/ipldsch/ipldsch_satisfaction.go index bd0f1287..99f84da7 100644 --- a/ipld/ipldsch/ipldsch_satisfaction.go +++ b/ipld/ipldsch/ipldsch_satisfaction.go @@ -8325,6 +8325,9 @@ func (n _SlotMeta) FieldParent_slot() Int { func (n _SlotMeta) FieldBlocktime() Int { return &n.blocktime } +func (n _SlotMeta) FieldBlock_height() MaybeInt { + return &n.block_height +} type _SlotMeta__Maybe struct { m schema.Maybe @@ -8361,8 +8364,9 @@ func (m MaybeSlotMeta) Must() SlotMeta { } var ( - fieldName__SlotMeta_Parent_slot = _String{"parent_slot"} - fieldName__SlotMeta_Blocktime = _String{"blocktime"} + fieldName__SlotMeta_Parent_slot = _String{"parent_slot"} + fieldName__SlotMeta_Blocktime = _String{"blocktime"} + fieldName__SlotMeta_Block_height = _String{"block_height"} ) var _ datamodel.Node = (SlotMeta)(&_SlotMeta{}) var _ schema.TypedNode = (SlotMeta)(&_SlotMeta{}) @@ -8376,6 +8380,14 @@ func (n SlotMeta) LookupByString(key string) (datamodel.Node, error) { return &n.parent_slot, nil case "blocktime": return &n.blocktime, nil + case "block_height": + if n.block_height.m == schema.Maybe_Absent { + return datamodel.Absent, nil + } + if n.block_height.m == schema.Maybe_Null { + return datamodel.Null, nil + } + return &n.block_height.v, nil default: return nil, schema.ErrNoSuchField{Type: nil /*TODO*/, Field: datamodel.PathSegmentOfString(key)} } @@ -8403,7 +8415,7 @@ type _SlotMeta__MapItr struct { } func (itr *_SlotMeta__MapItr) Next() (k datamodel.Node, v datamodel.Node, _ error) { - if itr.idx >= 2 { + if itr.idx >= 3 { return nil, nil, datamodel.ErrIteratorOverread{} } switch itr.idx { @@ -8413,6 +8425,17 @@ func (itr *_SlotMeta__MapItr) Next() (k datamodel.Node, v datamodel.Node, _ erro case 1: k = &fieldName__SlotMeta_Blocktime v = &itr.n.blocktime + case 2: + k = &fieldName__SlotMeta_Block_height + if itr.n.block_height.m == schema.Maybe_Absent { + v = datamodel.Absent + break + } + if itr.n.block_height.m == schema.Maybe_Null { + v = datamodel.Null + break + } + v = &itr.n.block_height.v default: panic("unreachable") } @@ -8420,14 +8443,14 @@ func (itr *_SlotMeta__MapItr) Next() (k datamodel.Node, v datamodel.Node, _ erro return } func (itr *_SlotMeta__MapItr) Done() bool { - return itr.idx >= 2 + return itr.idx >= 3 } func (SlotMeta) ListIterator() datamodel.ListIterator { return nil } func (SlotMeta) Length() int64 { - return 2 + return 3 } func (SlotMeta) IsAbsent() bool { return false @@ -8488,9 +8511,10 @@ type _SlotMeta__Assembler struct { s int f int - cm schema.Maybe - ca_parent_slot _Int__Assembler - ca_blocktime _Int__Assembler + cm schema.Maybe + ca_parent_slot _Int__Assembler + ca_blocktime _Int__Assembler + ca_block_height _Int__Assembler } func (na *_SlotMeta__Assembler) reset() { @@ -8498,12 +8522,14 @@ func (na *_SlotMeta__Assembler) reset() { na.s = 0 na.ca_parent_slot.reset() na.ca_blocktime.reset() + na.ca_block_height.reset() } var ( - fieldBit__SlotMeta_Parent_slot = 1 << 0 - fieldBit__SlotMeta_Blocktime = 1 << 1 - fieldBits__SlotMeta_sufficient = 0 + 1<<0 + 1<<1 + fieldBit__SlotMeta_Parent_slot = 1 << 0 + fieldBit__SlotMeta_Blocktime = 1 << 1 + fieldBit__SlotMeta_Block_height = 1 << 2 + fieldBits__SlotMeta_sufficient = 0 + 1<<0 + 1<<1 ) func (na *_SlotMeta__Assembler) BeginMap(int64) (datamodel.MapAssembler, error) { @@ -8617,6 +8643,17 @@ func (ma *_SlotMeta__Assembler) valueFinishTidy() bool { default: return false } + case 2: + switch ma.w.block_height.m { + case schema.Maybe_Null: + ma.state = maState_initial + return true + case schema.Maybe_Value: + ma.state = maState_initial + return true + default: + return false + } default: panic("unreachable") } @@ -8657,6 +8694,17 @@ func (ma *_SlotMeta__Assembler) AssembleEntry(k string) (datamodel.NodeAssembler ma.ca_blocktime.w = &ma.w.blocktime ma.ca_blocktime.m = &ma.cm return &ma.ca_blocktime, nil + case "block_height": + if ma.s&fieldBit__SlotMeta_Block_height != 0 { + return nil, datamodel.ErrRepeatedMapKey{Key: &fieldName__SlotMeta_Block_height} + } + ma.s += fieldBit__SlotMeta_Block_height + ma.state = maState_midValue + ma.f = 2 + ma.ca_block_height.w = &ma.w.block_height.v + ma.ca_block_height.m = &ma.w.block_height.m + ma.w.block_height.m = allowNull + return &ma.ca_block_height, nil } return nil, schema.ErrInvalidKey{TypeName: "ipldsch.SlotMeta", Key: &_String{k}} } @@ -8701,6 +8749,11 @@ func (ma *_SlotMeta__Assembler) AssembleValue() datamodel.NodeAssembler { ma.ca_blocktime.w = &ma.w.blocktime ma.ca_blocktime.m = &ma.cm return &ma.ca_blocktime + case 2: + ma.ca_block_height.w = &ma.w.block_height.v + ma.ca_block_height.m = &ma.w.block_height.m + ma.w.block_height.m = allowNull + return &ma.ca_block_height default: panic("unreachable") } @@ -8782,6 +8835,14 @@ func (ka *_SlotMeta__KeyAssembler) AssignString(k string) error { ka.state = maState_expectValue ka.f = 1 return nil + case "block_height": + if ka.s&fieldBit__SlotMeta_Block_height != 0 { + return datamodel.ErrRepeatedMapKey{Key: &fieldName__SlotMeta_Block_height} + } + ka.s += fieldBit__SlotMeta_Block_height + ka.state = maState_expectValue + ka.f = 2 + return nil default: return schema.ErrInvalidKey{TypeName: "ipldsch.SlotMeta", Key: &_String{k}} } @@ -8832,6 +8893,14 @@ func (n *_SlotMeta__Repr) LookupByIndex(idx int64) (datamodel.Node, error) { return n.parent_slot.Representation(), nil case 1: return n.blocktime.Representation(), nil + case 2: + if n.block_height.m == schema.Maybe_Absent { + return datamodel.Absent, datamodel.ErrNotExists{Segment: datamodel.PathSegmentOfInt(idx)} + } + if n.block_height.m == schema.Maybe_Null { + return datamodel.Null, nil + } + return n.block_height.v.Representation(), nil default: return nil, schema.ErrNoSuchField{Type: nil /*TODO*/, Field: datamodel.PathSegmentOfInt(idx)} } @@ -8847,16 +8916,24 @@ func (_SlotMeta__Repr) MapIterator() datamodel.MapIterator { return nil } func (n *_SlotMeta__Repr) ListIterator() datamodel.ListIterator { - return &_SlotMeta__ReprListItr{n, 0} + end := 3 + if n.block_height.m == schema.Maybe_Absent { + end = 2 + } else { + goto done + } +done: + return &_SlotMeta__ReprListItr{n, 0, end} } type _SlotMeta__ReprListItr struct { n *_SlotMeta__Repr idx int + end int } func (itr *_SlotMeta__ReprListItr) Next() (idx int64, v datamodel.Node, err error) { - if itr.idx >= 2 { + if itr.idx >= 3 { return -1, nil, datamodel.ErrIteratorOverread{} } switch itr.idx { @@ -8866,6 +8943,16 @@ func (itr *_SlotMeta__ReprListItr) Next() (idx int64, v datamodel.Node, err erro case 1: idx = int64(itr.idx) v = itr.n.blocktime.Representation() + case 2: + idx = int64(itr.idx) + if itr.n.block_height.m == schema.Maybe_Absent { + return -1, nil, datamodel.ErrIteratorOverread{} + } + if itr.n.block_height.m == schema.Maybe_Null { + v = datamodel.Null + break + } + v = itr.n.block_height.v.Representation() default: panic("unreachable") } @@ -8873,11 +8960,14 @@ func (itr *_SlotMeta__ReprListItr) Next() (idx int64, v datamodel.Node, err erro return } func (itr *_SlotMeta__ReprListItr) Done() bool { - return itr.idx >= 2 + return itr.idx >= itr.end } func (rn *_SlotMeta__Repr) Length() int64 { - l := 2 + l := 3 + if rn.block_height.m == schema.Maybe_Absent { + l-- + } return int64(l) } func (_SlotMeta__Repr) IsAbsent() bool { @@ -8938,9 +9028,10 @@ type _SlotMeta__ReprAssembler struct { state laState f int - cm schema.Maybe - ca_parent_slot _Int__ReprAssembler - ca_blocktime _Int__ReprAssembler + cm schema.Maybe + ca_parent_slot _Int__ReprAssembler + ca_blocktime _Int__ReprAssembler + ca_block_height _Int__ReprAssembler } func (na *_SlotMeta__ReprAssembler) reset() { @@ -8948,6 +9039,7 @@ func (na *_SlotMeta__ReprAssembler) reset() { na.f = 0 na.ca_parent_slot.reset() na.ca_blocktime.reset() + na.ca_block_height.reset() } func (_SlotMeta__ReprAssembler) BeginMap(sizeHint int64) (datamodel.MapAssembler, error) { return mixins.ListAssembler{TypeName: "ipldsch.SlotMeta.Repr"}.BeginMap(0) @@ -9057,6 +9149,19 @@ func (la *_SlotMeta__ReprAssembler) valueFinishTidy() bool { default: return false } + case 2: + switch la.w.block_height.m { + case schema.Maybe_Value: + la.state = laState_initial + la.f++ + return true + case schema.Maybe_Null: + la.state = laState_initial + la.f++ + return true + default: + return false + } default: panic("unreachable") } @@ -9072,8 +9177,8 @@ func (la *_SlotMeta__ReprAssembler) AssembleValue() datamodel.NodeAssembler { case laState_finished: panic("invalid state: AssembleValue cannot be called on an assembler that's already finished") } - if la.f >= 2 { - return _ErrorThunkAssembler{schema.ErrNoSuchField{Type: nil /*TODO*/, Field: datamodel.PathSegmentOfInt(2)}} + if la.f >= 3 { + return _ErrorThunkAssembler{schema.ErrNoSuchField{Type: nil /*TODO*/, Field: datamodel.PathSegmentOfInt(3)}} } la.state = laState_midValue switch la.f { @@ -9085,6 +9190,11 @@ func (la *_SlotMeta__ReprAssembler) AssembleValue() datamodel.NodeAssembler { la.ca_blocktime.w = &la.w.blocktime la.ca_blocktime.m = &la.cm return &la.ca_blocktime + case 2: + la.ca_block_height.w = &la.w.block_height.v + la.ca_block_height.m = &la.w.block_height.m + la.w.block_height.m = allowNull + return &la.ca_block_height default: panic("unreachable") } diff --git a/ipld/ipldsch/ipldsch_types.go b/ipld/ipldsch/ipldsch_types.go index 264ef575..ecfa4204 100644 --- a/ipld/ipldsch/ipldsch_types.go +++ b/ipld/ipldsch/ipldsch_types.go @@ -158,8 +158,9 @@ type _Shredding struct { // SlotMeta matches the IPLD Schema type "SlotMeta". It has struct type-kind, and may be interrogated like map kind. type SlotMeta = *_SlotMeta type _SlotMeta struct { - parent_slot _Int - blocktime _Int + parent_slot _Int + blocktime _Int + block_height _Int__Maybe } // String matches the IPLD Schema type "String". It has string kind. diff --git a/ledger.ipldsch b/ledger.ipldsch index 5dc50d4e..1350b392 100644 --- a/ledger.ipldsch +++ b/ledger.ipldsch @@ -47,6 +47,8 @@ type SlotMeta struct { parent_slot Int # Block time of this slot. blocktime Int + # Block height of this slot. + block_height nullable optional Int } representation tuple type Shredding struct {