func (s *Service) RunRules(ctx context.Context,
	credentials *checker.Credentials,
	action string,
	rulesData []*ruler.RulesData,
) []rules.Result {
	span, ctx := opentracing.StartSpanFromContext(ctx, "ruler.golang.RunRules")
	defer span.Finish()
	if len(rulesData) == 0 {
		log.Debug().Msg("Received no rules data entries")
		return []rules.Result{rules.FAILED}
	}
	results := make([]rules.Result, len(rulesData))
	for i := range rulesData {
		results[i] = rules.UNKNOWN
	}
	for i := range rulesData {
		if rulesData[i] == nil {
			log.Debug().Msg("Received nil rules data")
			results[i] = rules.FAILED
			return results
		}
		if rulesData[i].Data == nil {
			log.Debug().Msg("Received nil data in rules data")
			results[i] = rules.FAILED
			return results
		}
	}
	if action == ruler.ActionSign ||
		action == ruler.ActionSignBeaconProposal ||
		action == ruler.ActionSignBeaconAttestation {
		pubKeyMap := make(map[[48]byte]bool)
		for i := range rulesData {
			var key [48]byte
			if len(rulesData[i].PubKey) == 0 {
				log.Debug().Msg("Received no pubkey in rules data")
				results[i] = rules.FAILED
				return results
			}
			copy(key[:], rulesData[i].PubKey)
			if _, exists := pubKeyMap[key]; exists {
				log.Debug().Str("pubkey", fmt.Sprintf("%#x", rulesData[i].PubKey)).Msg("Multiple requests for same key")
				results[i] = rules.FAILED
				return results
			}
			pubKeyMap[key] = true
		}
		s.locker.PreLock()
		for i := range rulesData {
			var lockKey [48]byte
			copy(lockKey[:], rulesData[i].PubKey)
			s.locker.Lock(lockKey)
			defer s.locker.Unlock(lockKey)
		}
		s.locker.PostLock()
	}
	return s.runRules(ctx, credentials, action, rulesData)
}
RunRules runs a number of rules and returns a result.
package golang
import (
	"context"
	"fmt"
	"sync"
	"github.com/attestantio/dirk/rules"
	"github.com/attestantio/dirk/services/checker"
	"github.com/attestantio/dirk/services/ruler"
	"github.com/attestantio/dirk/util"
	"github.com/opentracing/opentracing-go"
	"github.com/pkg/errors"
)