Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Chore: Remove one allocate per hash by using generics. #5829

Merged
merged 3 commits into from
Nov 17, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions cmd/goal/application.go
Original file line number Diff line number Diff line change
Expand Up @@ -488,7 +488,7 @@ var createAppCmd = &cobra.Command{
reportErrorf(errorBroadcastingTX, err2)
}

reportInfof("Attempting to create app (approval size %d, hash %v; clear size %d, hash %v)", len(approvalProg), crypto.HashObj(logic.Program(approvalProg)), len(clearProg), crypto.HashObj(logic.Program(clearProg)))
reportInfof("Attempting to create app (approval size %d, hash %v; clear size %d, hash %v)", len(approvalProg), crypto.HashObj(logic.Program(approvalProg)), len(clearProg), logic.HashProgram(clearProg))
reportInfof("Issued transaction from account %s, txid %s (fee %d)", tx.Sender, txid, tx.Fee.Raw)

if !noWaitAfterSend {
Expand Down Expand Up @@ -563,7 +563,7 @@ var updateAppCmd = &cobra.Command{
reportErrorf(errorBroadcastingTX, err2)
}

reportInfof("Attempting to update app (approval size %d, hash %v; clear size %d, hash %v)", len(approvalProg), crypto.HashObj(logic.Program(approvalProg)), len(clearProg), crypto.HashObj(logic.Program(clearProg)))
reportInfof("Attempting to update app (approval size %d, hash %v; clear size %d, hash %v)", len(approvalProg), crypto.HashObj(logic.Program(approvalProg)), len(clearProg), logic.HashProgram(clearProg))
reportInfof("Issued transaction from account %s, txid %s (fee %d)", tx.Sender, txid, tx.Fee.Raw)

if !noWaitAfterSend {
Expand Down Expand Up @@ -1455,9 +1455,9 @@ var methodAppCmd = &cobra.Command{

// Report tx details to user
if methodCreatesApp {
reportInfof("Attempting to create app (approval size %d, hash %v; clear size %d, hash %v)", len(approvalProg), crypto.HashObj(logic.Program(approvalProg)), len(clearProg), crypto.HashObj(logic.Program(clearProg)))
reportInfof("Attempting to create app (approval size %d, hash %v; clear size %d, hash %v)", len(approvalProg), crypto.HashObj(logic.Program(approvalProg)), len(clearProg), logic.HashProgram(clearProg))
} else if onCompletionEnum == transactions.UpdateApplicationOC {
reportInfof("Attempting to update app (approval size %d, hash %v; clear size %d, hash %v)", len(approvalProg), crypto.HashObj(logic.Program(approvalProg)), len(clearProg), crypto.HashObj(logic.Program(clearProg)))
reportInfof("Attempting to update app (approval size %d, hash %v; clear size %d, hash %v)", len(approvalProg), crypto.HashObj(logic.Program(approvalProg)), len(clearProg), logic.HashProgram(clearProg))
}

reportInfof("Issued %d transaction(s):", len(signedTxnGroup))
Expand Down
4 changes: 2 additions & 2 deletions cmd/goal/interact.go
Original file line number Diff line number Diff line change
Expand Up @@ -625,9 +625,9 @@ var appExecuteCmd = &cobra.Command{
}

if appIdx == 0 {
reportInfof("Attempting to create app (global ints %d, global blobs %d, local ints %d, local blobs %d, approval size %d, hash %v; clear size %d, hash %v)", globalSchema.NumUint, globalSchema.NumByteSlice, localSchema.NumUint, localSchema.NumByteSlice, len(approvalProg), crypto.HashObj(logic.Program(approvalProg)), len(clearProg), crypto.HashObj(logic.Program(clearProg)))
reportInfof("Attempting to create app (global ints %d, global blobs %d, local ints %d, local blobs %d, approval size %d, hash %v; clear size %d, hash %v)", globalSchema.NumUint, globalSchema.NumByteSlice, localSchema.NumUint, localSchema.NumByteSlice, len(approvalProg), logic.HashProgram(approvalProg), len(clearProg), crypto.HashObj(logic.Program(clearProg)))
} else if onCompletion == transactions.UpdateApplicationOC {
reportInfof("Attempting to update app (approval size %d, hash %v; clear size %d, hash %v)", len(approvalProg), crypto.HashObj(logic.Program(approvalProg)), len(clearProg), crypto.HashObj(logic.Program(clearProg)))
reportInfof("Attempting to update app (approval size %d, hash %v; clear size %d, hash %v)", len(approvalProg), crypto.HashObj(logic.Program(approvalProg)), len(clearProg), logic.HashProgram(clearProg))
}
reportInfof("Issued transaction from account %s, txid %s (fee %d)", tx.Sender, txid, tx.Fee.Raw)

Expand Down
2 changes: 1 addition & 1 deletion cmd/goal/tealsign.go
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,7 @@ The base64 encoding of the signature will always be printed to stdout. Optionall
reportErrorf(tealsignEmptyLogic)
}

progHash = crypto.HashObj(logic.Program(stxn.Lsig.Logic))
progHash = logic.HashProgram(stxn.Lsig.Logic)
} else {
// Otherwise, the contract address is the logic hash
parsedAddr, err := basics.UnmarshalChecksumAddress(contractAddr)
Expand Down
1 change: 0 additions & 1 deletion crypto/hashes_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,6 @@ func TestHashSum(t *testing.T) {

dgst := HashObj(TestingHashable{})
a.Equal(GenericHashObj(h, TestingHashable{}), dgst[:])

}

func TestEmptyHash(t *testing.T) {
Expand Down
4 changes: 2 additions & 2 deletions crypto/util.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ type Hashable interface {
}

// HashRep appends the correct hashid before the message to be hashed.
func HashRep(h Hashable) []byte {
func HashRep[H Hashable](h H) []byte {
hashid, data := h.ToBeHashed()
return append([]byte(hashid), data...)
}
Expand Down Expand Up @@ -86,7 +86,7 @@ func Hash(data []byte) Digest {
}

// HashObj computes a hash of a Hashable object and its type
func HashObj(h Hashable) Digest {
func HashObj[H Hashable](h H) Digest {
return Hash(HashRep(h))
}

Expand Down
6 changes: 3 additions & 3 deletions daemon/algod/api/server/v2/test/handlers_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@ import (
"encoding/json"
"errors"
"fmt"
"golang.org/x/sync/semaphore"
"io"
"math"
"net"
Expand All @@ -33,6 +32,8 @@ import (
"testing"
"time"

"golang.org/x/sync/semaphore"

"github.com/algorand/go-algorand/daemon/algod/api/server"
"github.com/algorand/go-algorand/ledger/eval"
"github.com/algorand/go-algorand/ledger/ledgercore"
Expand Down Expand Up @@ -272,8 +273,7 @@ func addBlockHelper(t *testing.T) (v2.Handlers, echo.Context, *httptest.Response

// make an app call txn with eval delta
lsig := transactions.LogicSig{Logic: retOneProgram} // int 1
program := logic.Program(lsig.Logic)
lhash := crypto.HashObj(&program)
lhash := logic.HashProgram(lsig.Logic)
var sender basics.Address
copy(sender[:], lhash[:])
stx := transactions.SignedTxn{
Expand Down
3 changes: 1 addition & 2 deletions daemon/algod/api/server/v2/test/helpers.go
Original file line number Diff line number Diff line change
Expand Up @@ -342,8 +342,7 @@ func testingenvWithBalances(t testing.TB, minMoneyAtStart, maxMoneyAtStart, numA

genesis[poolAddr] = basics_testing.MakeAccountData(basics.NotParticipating, basics.MicroAlgos{Raw: 100000 * uint64(proto.RewardsRateRefreshInterval)})

program := logic.Program(retOneProgram)
lhash := crypto.HashObj(&program)
lhash := logic.HashProgram(retOneProgram)
var addr basics.Address
copy(addr[:], lhash[:])
ad := basics_testing.MakeAccountData(basics.NotParticipating, basics.MicroAlgos{Raw: 100000 * uint64(proto.RewardsRateRefreshInterval)})
Expand Down
4 changes: 2 additions & 2 deletions data/account/participation.go
Original file line number Diff line number Diff line change
Expand Up @@ -80,8 +80,8 @@ func (id *ParticipationKeyIdentity) ToBeHashed() (protocol.HashID, []byte) {
}

// ID creates a ParticipationID hash from the identity file.
func (id ParticipationKeyIdentity) ID() ParticipationID {
return ParticipationID(crypto.HashObj(&id))
func (id *ParticipationKeyIdentity) ID() ParticipationID {
return ParticipationID(crypto.HashObj(id))
}

// ID computes a ParticipationID.
Expand Down
10 changes: 10 additions & 0 deletions data/account/participation_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -606,3 +606,13 @@ func BenchmarkParticipationSign(b *testing.B) {
_ = part.Voting.Sign(ephID, msg)
}
}

func BenchmarkID(b *testing.B) {
pki := ParticipationKeyIdentity{}
b.Run("existing", func(b *testing.B) {
b.ReportAllocs() // demonstrate this is a single alloc
for i := 0; i < b.N; i++ {
pki.ID()
}
})
}
28 changes: 28 additions & 0 deletions data/bookkeeping/genesis_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import (
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"

"github.com/algorand/go-algorand/crypto"
"github.com/algorand/go-algorand/data/basics"
"github.com/algorand/go-algorand/test/partitiontest"
)
Expand Down Expand Up @@ -155,3 +156,30 @@ func TestGenesis_Balances(t *testing.T) {
})
}
}

func (genesis Genesis) hashOld() crypto.Digest {
return hashObjOld(genesis)
}

// hashObjOld computes a hash of a Hashable object and its type, doing so the
// "old way" to show it requires an extra allocation in benchmarks.
func hashObjOld(h crypto.Hashable) crypto.Digest {
return crypto.Hash(crypto.HashRep(h))
}

func BenchmarkGenesisHash(b *testing.B) {
b.ReportAllocs()
g := Genesis{}
b.Run("new", func(b *testing.B) {
b.ReportAllocs()
for i := 0; i < b.N; i++ {
g.Hash()
}
})
b.Run("old", func(b *testing.B) {
b.ReportAllocs()
for i := 0; i < b.N; i++ {
g.hashOld()
}
})
}
2 changes: 1 addition & 1 deletion data/transactions/logic/program.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,5 +33,5 @@ func (lsl Program) ToBeHashed() (protocol.HashID, []byte) {
// This Digest can be used as an Address for a logic controlled account.
func HashProgram(program []byte) crypto.Digest {
pb := Program(program)
return crypto.HashObj(&pb)
return crypto.HashObj(pb)
}